From ff9dd45bc002004c296a186d72abfbc873e9119f Mon Sep 17 00:00:00 2001 From: andres-portainer <91705312+andres-portainer@users.noreply.github.com> Date: Tue, 4 Aug 2026 23:10:37 -0300 Subject: [PATCH] fix(deps): replace orcaman/concurrent-map with stdlib sync.Map BE-13306 (#3372) --- .golangci.yaml | 2 + api/http/proxy/manager.go | 14 +++--- api/http/proxy/manager_test.go | 90 ++++++++++++++++++++++++++++++++++ go.mod | 1 - go.sum | 2 - 5 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 api/http/proxy/manager_test.go diff --git a/.golangci.yaml b/.golangci.yaml index 288653e7ab..cbd02d9bde 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -77,6 +77,8 @@ linters: desc: use github.com/Masterminds/semver/v3 - pkg: github.com/hashicorp/go-version desc: use github.com/Masterminds/semver/v3 + - pkg: github.com/orcaman/concurrent-map + desc: use sync.Map instead gocritic: disable-all: true enabled-checks: diff --git a/api/http/proxy/manager.go b/api/http/proxy/manager.go index 477bc547ba..893e88e1b4 100644 --- a/api/http/proxy/manager.go +++ b/api/http/proxy/manager.go @@ -2,8 +2,9 @@ package proxy import ( "errors" - "fmt" "net/http" + "strconv" + "sync" portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/dataservices" @@ -11,8 +12,6 @@ import ( "github.com/portainer/portainer/api/http/proxy/factory" "github.com/portainer/portainer/api/http/proxy/factory/kubernetes" "github.com/portainer/portainer/api/kubernetes/cli" - - cmap "github.com/orcaman/concurrent-map" ) var ErrProxyFactoryNotInitialized = errors.New("proxy factory not initialized") @@ -20,14 +19,13 @@ var ErrProxyFactoryNotInitialized = errors.New("proxy factory not initialized") // Manager represents a service used to manage proxies to environments (endpoints) and extensions. type Manager struct { proxyFactory *factory.ProxyFactory - endpointProxies cmap.ConcurrentMap + endpointProxies sync.Map k8sClientFactory *cli.ClientFactory } // NewManager initializes a new proxy Service func NewManager(kubernetesClientFactory *cli.ClientFactory) *Manager { return &Manager{ - endpointProxies: cmap.New(), k8sClientFactory: kubernetesClientFactory, } } @@ -48,7 +46,7 @@ func (manager *Manager) CreateAndRegisterEndpointProxy(endpoint *portainer.Endpo return nil, err } - manager.endpointProxies.Set(fmt.Sprint(endpoint.ID), proxy) + manager.endpointProxies.Store(strconv.Itoa(int(endpoint.ID)), proxy) return proxy, nil } @@ -65,7 +63,7 @@ func (manager *Manager) CreateAgentProxyServer(endpoint *portainer.Endpoint) (*f // GetEndpointProxy returns the proxy associated to a key func (manager *Manager) GetEndpointProxy(endpoint *portainer.Endpoint) http.Handler { - proxy, ok := manager.endpointProxies.Get(fmt.Sprint(endpoint.ID)) + proxy, ok := manager.endpointProxies.Load(strconv.Itoa(int(endpoint.ID))) if !ok { return nil } @@ -77,7 +75,7 @@ func (manager *Manager) GetEndpointProxy(endpoint *portainer.Endpoint) http.Hand // and cleans the k8s environment(endpoint) client cache. DeleteEndpointProxy // is currently only called for edge connection clean up and when endpoint is updated func (manager *Manager) DeleteEndpointProxy(endpointID portainer.EndpointID) { - manager.endpointProxies.Remove(fmt.Sprint(endpointID)) + manager.endpointProxies.Delete(strconv.Itoa(int(endpointID))) if manager.k8sClientFactory != nil { manager.k8sClientFactory.RemoveKubeClient(endpointID) diff --git a/api/http/proxy/manager_test.go b/api/http/proxy/manager_test.go new file mode 100644 index 0000000000..ab0c6c047c --- /dev/null +++ b/api/http/proxy/manager_test.go @@ -0,0 +1,90 @@ +package proxy + +import ( + "net/http" + "strconv" + "testing" + + portainer "github.com/portainer/portainer/api" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type stubHandler struct{} + +func (*stubHandler) ServeHTTP(http.ResponseWriter, *http.Request) {} + +func TestCreateAndRegisterEndpointProxy_ProxyFactoryNotInitialized(t *testing.T) { + t.Parallel() + + manager := NewManager(nil) + endpoint := &portainer.Endpoint{ID: 1} + + proxy, err := manager.CreateAndRegisterEndpointProxy(endpoint) + + require.Error(t, err) + require.ErrorIs(t, err, ErrProxyFactoryNotInitialized) + assert.Nil(t, proxy) +} + +func TestCreateAgentProxyServer_ProxyFactoryNotInitialized(t *testing.T) { + t.Parallel() + + manager := NewManager(nil) + endpoint := &portainer.Endpoint{ID: 1} + + proxyServer, err := manager.CreateAgentProxyServer(endpoint) + + require.Error(t, err) + require.ErrorIs(t, err, ErrProxyFactoryNotInitialized) + assert.Nil(t, proxyServer) +} + +func TestCreateGitlabProxy_ProxyFactoryNotInitialized(t *testing.T) { + t.Parallel() + + manager := NewManager(nil) + + proxy, err := manager.CreateGitlabProxy("http://gitlab.example.com") + + require.Error(t, err) + require.ErrorIs(t, err, ErrProxyFactoryNotInitialized) + assert.Nil(t, proxy) +} + +func TestGetEndpointProxy_NotFound(t *testing.T) { + t.Parallel() + + manager := NewManager(nil) + endpoint := &portainer.Endpoint{ID: 1} + + proxy := manager.GetEndpointProxy(endpoint) + + assert.Nil(t, proxy) +} + +func TestGetEndpointProxy_Found(t *testing.T) { + t.Parallel() + + manager := NewManager(nil) + endpoint := &portainer.Endpoint{ID: 42} + handler := &stubHandler{} + manager.endpointProxies.Store(strconv.Itoa(int(endpoint.ID)), handler) + + proxy := manager.GetEndpointProxy(endpoint) + + assert.Same(t, handler, proxy) +} + +func TestDeleteEndpointProxy(t *testing.T) { + t.Parallel() + + manager := NewManager(nil) + endpoint := &portainer.Endpoint{ID: 7} + manager.endpointProxies.Store(strconv.Itoa(int(endpoint.ID)), &stubHandler{}) + + manager.DeleteEndpointProxy(endpoint.ID) + + proxy := manager.GetEndpointProxy(endpoint) + assert.Nil(t, proxy) +} diff --git a/go.mod b/go.mod index 89d4f5d4af..76a6526d56 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,6 @@ require ( github.com/kubernetes/kompose v1.37.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.1 - github.com/orcaman/concurrent-map v1.0.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.23.2 diff --git a/go.sum b/go.sum index e63b61dece..8826c0608c 100644 --- a/go.sum +++ b/go.sum @@ -779,8 +779,6 @@ github.com/openshift/api v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDD github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY= -github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= github.com/ovh/go-ovh v1.9.0 h1:6K8VoL3BYjVV3In9tPJUdT7qMx9h0GExN9EXx1r2kKE= github.com/ovh/go-ovh v1.9.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=