diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index f955c7e57..a2cb8ae7d 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -464,7 +464,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server { kubeClusterAccessService := kubernetes.NewKubeClusterAccessService(*flags.BaseURL, *flags.AddrHTTPS, sslSettings.CertPath) - proxyManager := proxy.NewManager(dataStore, digitalSignatureService, reverseTunnelService, dockerClientFactory, kubernetesClientFactory, kubernetesTokenCacheManager, gitService) + proxyManager := proxy.NewManager(kubernetesClientFactory) reverseTunnelService.ProxyManager = proxyManager @@ -495,6 +495,8 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server { } snapshotService.Start() + proxyManager.NewProxyFactory(dataStore, digitalSignatureService, reverseTunnelService, dockerClientFactory, kubernetesClientFactory, kubernetesTokenCacheManager, gitService, snapshotService) + helmPackageManager, err := initHelmPackageManager(*flags.Assets) if err != nil { log.Fatal().Err(err).Msg("failed initializing helm package manager") diff --git a/api/http/handler/endpoints/endpoint_delete_test.go b/api/http/handler/endpoints/endpoint_delete_test.go index 8eb3e982c..cc83633a2 100644 --- a/api/http/handler/endpoints/endpoint_delete_test.go +++ b/api/http/handler/endpoints/endpoint_delete_test.go @@ -21,7 +21,8 @@ func TestEndpointDeleteEdgeGroupsConcurrently(t *testing.T) { handler := NewHandler(testhelpers.NewTestRequestBouncer(), demo.NewService()) handler.DataStore = store - handler.ProxyManager = proxy.NewManager(nil, nil, nil, nil, nil, nil, nil) + handler.ProxyManager = proxy.NewManager(nil) + handler.ProxyManager.NewProxyFactory(nil, nil, nil, nil, nil, nil, nil, nil) // Create all the environments and add them to the same edge group diff --git a/api/http/proxy/factory/docker.go b/api/http/proxy/factory/docker.go index 2e4d28e21..ca9dce35e 100644 --- a/api/http/proxy/factory/docker.go +++ b/api/http/proxy/factory/docker.go @@ -65,7 +65,7 @@ func (factory *ProxyFactory) newDockerHTTPProxy(endpoint *portainer.Endpoint) (h DockerClientFactory: factory.dockerClientFactory, } - dockerTransport, err := docker.NewTransport(transportParameters, httpTransport, factory.gitService) + dockerTransport, err := docker.NewTransport(transportParameters, httpTransport, factory.gitService, factory.snapshotService) if err != nil { return nil, err } diff --git a/api/http/proxy/factory/docker/transport.go b/api/http/proxy/factory/docker/transport.go index 61ab1c711..2548abe00 100644 --- a/api/http/proxy/factory/docker/transport.go +++ b/api/http/proxy/factory/docker/transport.go @@ -36,6 +36,7 @@ type ( reverseTunnelService portainer.ReverseTunnelService dockerClientFactory *dockerclient.ClientFactory gitService portainer.GitService + snapshotService portainer.SnapshotService } // TransportParameters is used to create a new Transport @@ -63,7 +64,7 @@ type ( ) // NewTransport returns a pointer to a new Transport instance. -func NewTransport(parameters *TransportParameters, httpTransport *http.Transport, gitService portainer.GitService) (*Transport, error) { +func NewTransport(parameters *TransportParameters, httpTransport *http.Transport, gitService portainer.GitService, snapshotService portainer.SnapshotService) (*Transport, error) { transport := &Transport{ endpoint: parameters.Endpoint, dataStore: parameters.DataStore, @@ -72,6 +73,7 @@ func NewTransport(parameters *TransportParameters, httpTransport *http.Transport dockerClientFactory: parameters.DockerClientFactory, HTTPTransport: httpTransport, gitService: gitService, + snapshotService: snapshotService, } return transport, nil diff --git a/api/http/proxy/factory/docker/volumes.go b/api/http/proxy/factory/docker/volumes.go index c4b44c985..1d8101321 100644 --- a/api/http/proxy/factory/docker/volumes.go +++ b/api/http/proxy/factory/docker/volumes.go @@ -8,6 +8,7 @@ import ( "path" "github.com/docker/docker/client" + "github.com/rs/zerolog/log" portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/http/proxy/factory/utils" @@ -48,6 +49,14 @@ func (transport *Transport) volumeListOperation(response *http.Response, executo if responseObject["Volumes"] != nil { volumeData := responseObject["Volumes"].([]interface{}) + if transport.snapshotService != nil { + // Filling snapshot data can improve the performance of getVolumeResourceID + if err = transport.snapshotService.FillSnapshotData(transport.endpoint); err != nil { + log.Info().Err(err). + Int("endpoint id", int(transport.endpoint.ID)). + Msg("snapshot is not filled into the endpoint.") + } + } for _, volumeObject := range volumeData { volume := volumeObject.(map[string]interface{}) diff --git a/api/http/proxy/factory/docker_unix.go b/api/http/proxy/factory/docker_unix.go index 5a4cdc445..5e4cfc5db 100644 --- a/api/http/proxy/factory/docker_unix.go +++ b/api/http/proxy/factory/docker_unix.go @@ -22,7 +22,7 @@ func (factory ProxyFactory) newOSBasedLocalProxy(path string, endpoint *portaine proxy := &dockerLocalProxy{} - dockerTransport, err := docker.NewTransport(transportParameters, newSocketTransport(path), factory.gitService) + dockerTransport, err := docker.NewTransport(transportParameters, newSocketTransport(path), factory.gitService, factory.snapshotService) if err != nil { return nil, err } diff --git a/api/http/proxy/factory/docker_windows.go b/api/http/proxy/factory/docker_windows.go index 161f08bfb..bf2ce58d3 100644 --- a/api/http/proxy/factory/docker_windows.go +++ b/api/http/proxy/factory/docker_windows.go @@ -23,7 +23,7 @@ func (factory ProxyFactory) newOSBasedLocalProxy(path string, endpoint *portaine proxy := &dockerLocalProxy{} - dockerTransport, err := docker.NewTransport(transportParameters, newNamedPipeTransport(path), factory.gitService) + dockerTransport, err := docker.NewTransport(transportParameters, newNamedPipeTransport(path), factory.gitService, factory.snapshotService) if err != nil { return nil, err } diff --git a/api/http/proxy/factory/factory.go b/api/http/proxy/factory/factory.go index 9f7e3f995..28d05dec5 100644 --- a/api/http/proxy/factory/factory.go +++ b/api/http/proxy/factory/factory.go @@ -23,11 +23,12 @@ type ( kubernetesClientFactory *cli.ClientFactory kubernetesTokenCacheManager *kubernetes.TokenCacheManager gitService portainer.GitService + snapshotService portainer.SnapshotService } ) // NewProxyFactory returns a pointer to a new instance of a ProxyFactory -func NewProxyFactory(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *dockerclient.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService) *ProxyFactory { +func NewProxyFactory(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *dockerclient.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService, snapshotService portainer.SnapshotService) *ProxyFactory { return &ProxyFactory{ dataStore: dataStore, signatureService: signatureService, @@ -36,6 +37,7 @@ func NewProxyFactory(dataStore dataservices.DataStore, signatureService portaine kubernetesClientFactory: kubernetesClientFactory, kubernetesTokenCacheManager: kubernetesTokenCacheManager, gitService: gitService, + snapshotService: snapshotService, } } diff --git a/api/http/proxy/manager.go b/api/http/proxy/manager.go index 65ea0c31b..ad7369064 100644 --- a/api/http/proxy/manager.go +++ b/api/http/proxy/manager.go @@ -25,17 +25,24 @@ type ( ) // NewManager initializes a new proxy Service -func NewManager(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *dockerclient.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService) *Manager { +func NewManager(kubernetesClientFactory *cli.ClientFactory) *Manager { return &Manager{ endpointProxies: cmap.New(), k8sClientFactory: kubernetesClientFactory, - proxyFactory: factory.NewProxyFactory(dataStore, signatureService, tunnelService, clientFactory, kubernetesClientFactory, kubernetesTokenCacheManager, gitService), } } +func (manager *Manager) NewProxyFactory(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *dockerclient.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService, snapshotService portainer.SnapshotService) { + manager.proxyFactory = factory.NewProxyFactory(dataStore, signatureService, tunnelService, clientFactory, kubernetesClientFactory, kubernetesTokenCacheManager, gitService, snapshotService) +} + // CreateAndRegisterEndpointProxy creates a new HTTP reverse proxy based on environment(endpoint) properties and and adds it to the registered proxies. // It can also be used to create a new HTTP reverse proxy and replace an already registered proxy. func (manager *Manager) CreateAndRegisterEndpointProxy(endpoint *portainer.Endpoint) (http.Handler, error) { + if manager.proxyFactory == nil { + return nil, fmt.Errorf("proxy factory not init") + } + proxy, err := manager.proxyFactory.NewEndpointProxy(endpoint) if err != nil { return nil, err @@ -48,6 +55,9 @@ func (manager *Manager) CreateAndRegisterEndpointProxy(endpoint *portainer.Endpo // CreateAgentProxyServer creates a new HTTP reverse proxy based on environment(endpoint) properties and and adds it to the registered proxies. // It can also be used to create a new HTTP reverse proxy and replace an already registered proxy. func (manager *Manager) CreateAgentProxyServer(endpoint *portainer.Endpoint) (*factory.ProxyServer, error) { + if manager.proxyFactory == nil { + return nil, fmt.Errorf("proxy factory not init") + } return manager.proxyFactory.NewAgentProxy(endpoint) } @@ -74,5 +84,8 @@ func (manager *Manager) DeleteEndpointProxy(endpointID portainer.EndpointID) { // CreateGitlabProxy creates a new HTTP reverse proxy that can be used to send requests to the Gitlab API func (manager *Manager) CreateGitlabProxy(url string) (http.Handler, error) { + if manager.proxyFactory == nil { + return nil, fmt.Errorf("proxy factory not init") + } return manager.proxyFactory.NewGitlabProxy(url) }