2017-05-23 18:56:10 +00:00
package proxy
import (
2021-01-25 19:16:53 +00:00
"fmt"
2017-05-23 18:56:10 +00:00
"net/http"
2020-07-05 23:21:03 +00:00
"github.com/portainer/portainer/api/http/proxy/factory/kubernetes"
cmap "github.com/orcaman/concurrent-map"
"github.com/portainer/portainer/api/kubernetes/cli"
portainer "github.com/portainer/portainer/api"
2019-11-12 23:41:42 +00:00
"github.com/portainer/portainer/api/docker"
"github.com/portainer/portainer/api/http/proxy/factory"
2017-05-23 18:56:10 +00:00
)
2018-12-09 03:49:27 +00:00
// TODO: contain code related to legacy extension management
2018-05-06 07:15:57 +00:00
type (
2021-09-20 00:14:22 +00:00
// Manager represents a service used to manage proxies to environments(endpoints) and extensions.
2018-05-06 07:15:57 +00:00
Manager struct {
2019-11-12 23:41:42 +00:00
proxyFactory * factory . ProxyFactory
endpointProxies cmap . ConcurrentMap
2018-12-09 03:49:27 +00:00
legacyExtensionProxies cmap . ConcurrentMap
2021-01-07 22:55:42 +00:00
k8sClientFactory * cli . ClientFactory
2018-05-06 07:15:57 +00:00
}
)
2017-05-23 18:56:10 +00:00
// NewManager initializes a new proxy Service
2020-07-05 23:21:03 +00:00
func NewManager ( dataStore portainer . DataStore , signatureService portainer . DigitalSignatureService , tunnelService portainer . ReverseTunnelService , clientFactory * docker . ClientFactory , kubernetesClientFactory * cli . ClientFactory , kubernetesTokenCacheManager * kubernetes . TokenCacheManager ) * Manager {
2017-05-23 18:56:10 +00:00
return & Manager {
2019-11-12 23:41:42 +00:00
endpointProxies : cmap . New ( ) ,
2018-12-09 03:49:27 +00:00
legacyExtensionProxies : cmap . New ( ) ,
2021-01-07 22:55:42 +00:00
k8sClientFactory : kubernetesClientFactory ,
2020-07-05 23:21:03 +00:00
proxyFactory : factory . NewProxyFactory ( dataStore , signatureService , tunnelService , clientFactory , kubernetesClientFactory , kubernetesTokenCacheManager ) ,
2017-05-23 18:56:10 +00:00
}
}
2021-09-20 00:14:22 +00:00
// CreateAndRegisterEndpointProxy creates a new HTTP reverse proxy based on environment(endpoint) properties and and adds it to the registered proxies.
2018-05-28 14:40:33 +00:00
// It can also be used to create a new HTTP reverse proxy and replace an already registered proxy.
2019-11-12 23:41:42 +00:00
func ( manager * Manager ) CreateAndRegisterEndpointProxy ( endpoint * portainer . Endpoint ) ( http . Handler , error ) {
proxy , err := manager . proxyFactory . NewEndpointProxy ( endpoint )
2018-05-28 14:40:33 +00:00
if err != nil {
return nil , err
2017-05-23 18:56:10 +00:00
}
2021-01-25 19:16:53 +00:00
manager . endpointProxies . Set ( fmt . Sprint ( endpoint . ID ) , proxy )
2017-05-23 18:56:10 +00:00
return proxy , nil
}
2021-09-24 04:56:22 +00:00
// CreateAgentProxyServer creates a new HTTP reverse proxy based on environment(endpoint) properties and and adds it to the registered proxies.
2021-01-25 19:16:53 +00:00
// It can also be used to create a new HTTP reverse proxy and replace an already registered proxy.
2021-09-24 04:56:22 +00:00
func ( manager * Manager ) CreateAgentProxyServer ( endpoint * portainer . Endpoint ) ( * factory . ProxyServer , error ) {
return manager . proxyFactory . NewAgentProxy ( endpoint )
2021-01-25 19:16:53 +00:00
}
2019-11-12 23:41:42 +00:00
// GetEndpointProxy returns the proxy associated to a key
func ( manager * Manager ) GetEndpointProxy ( endpoint * portainer . Endpoint ) http . Handler {
2021-01-25 19:16:53 +00:00
proxy , ok := manager . endpointProxies . Get ( fmt . Sprint ( endpoint . ID ) )
2017-05-23 18:56:10 +00:00
if ! ok {
return nil
}
2019-11-12 23:41:42 +00:00
2017-05-23 18:56:10 +00:00
return proxy . ( http . Handler )
}
2019-11-12 23:41:42 +00:00
// DeleteEndpointProxy deletes the proxy associated to a key
2021-09-20 00:14:22 +00:00
// and cleans the k8s environment(endpoint) client cache. DeleteEndpointProxy
2021-01-07 22:55:42 +00:00
// is currently only called for edge connection clean up.
2021-10-15 05:13:20 +00:00
func ( manager * Manager ) DeleteEndpointProxy ( endpointID portainer . EndpointID ) {
manager . endpointProxies . Remove ( fmt . Sprint ( endpointID ) )
manager . k8sClientFactory . RemoveKubeClient ( endpointID )
2019-11-12 23:41:42 +00:00
}
2019-11-13 00:12:55 +00:00
// CreateLegacyExtensionProxy creates a new HTTP reverse proxy for a legacy extension and adds it to the registered proxies
2018-12-09 03:49:27 +00:00
func ( manager * Manager ) CreateLegacyExtensionProxy ( key , extensionAPIURL string ) ( http . Handler , error ) {
2019-11-12 23:41:42 +00:00
proxy , err := manager . proxyFactory . NewLegacyExtensionProxy ( extensionAPIURL )
2018-12-09 03:49:27 +00:00
if err != nil {
return nil , err
}
2019-05-24 21:53:10 +00:00
manager . legacyExtensionProxies . Set ( key , proxy )
2018-12-09 03:49:27 +00:00
return proxy , nil
}
2019-11-12 23:41:42 +00:00
// GetLegacyExtensionProxy returns a legacy extension proxy associated to a key
func ( manager * Manager ) GetLegacyExtensionProxy ( key string ) http . Handler {
proxy , ok := manager . legacyExtensionProxies . Get ( key )
if ! ok {
return nil
2018-02-23 02:10:26 +00:00
}
2019-11-12 23:41:42 +00:00
return proxy . ( http . Handler )
2018-02-23 02:10:26 +00:00
}
2019-11-12 03:28:31 +00:00
2019-11-13 00:12:55 +00:00
// CreateGitlabProxy creates a new HTTP reverse proxy that can be used to send requests to the Gitlab API
2019-11-12 03:28:31 +00:00
func ( manager * Manager ) CreateGitlabProxy ( url string ) ( http . Handler , error ) {
2019-11-13 00:12:55 +00:00
return manager . proxyFactory . NewGitlabProxy ( url )
2019-11-12 03:28:31 +00:00
}