From c486130a9f11ea38c4a8239255bb284cd63cf24d Mon Sep 17 00:00:00 2001 From: Marcelo Rydel Date: Mon, 21 Mar 2022 09:51:29 -0300 Subject: [PATCH] fix(kube): Use KubeClusterAccessService for Helm operations [EE-2500] (#6559) --- api/cmd/portainer/main.go | 5 +- api/http/handler/helm/handler.go | 47 +++++++++-------- api/http/handler/helm/helm_delete_test.go | 4 +- api/http/handler/helm/helm_install_test.go | 4 +- api/http/handler/helm/helm_list_test.go | 4 +- api/http/handler/kubernetes/handler.go | 24 +++++---- .../handler/kubernetes/kubernetes_config.go | 14 +++--- api/http/server.go | 8 ++- ...ervice.go => kubeclusteraccess_service.go} | 50 +++++++++++-------- ...t.go => kubeclusteraccess_service_test.go} | 48 ++++++++---------- 10 files changed, 105 insertions(+), 103 deletions(-) rename api/kubernetes/{kubeconfig_service.go => kubeclusteraccess_service.go} (62%) rename api/kubernetes/{kubeconfig_service_test.go => kubeclusteraccess_service_test.go} (77%) diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index 588301c3a..61d89f8d6 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -599,7 +599,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server { kubernetesTokenCacheManager := kubeproxy.NewTokenCacheManager() - kubeConfigService := kubernetes.NewKubeConfigCAService(*flags.AddrHTTPS, sslSettings.CertPath) + kubeClusterAccessService := kubernetes.NewKubeClusterAccessService(*flags.BaseURL, *flags.AddrHTTPS, sslSettings.CertPath) proxyManager := proxy.NewManager(dataStore, digitalSignatureService, reverseTunnelService, dockerClientFactory, kubernetesClientFactory, kubernetesTokenCacheManager) @@ -706,7 +706,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server { OpenAMTService: openAMTService, ProxyManager: proxyManager, KubernetesTokenCacheManager: kubernetesTokenCacheManager, - KubeConfigService: kubeConfigService, + KubeClusterAccessService: kubeClusterAccessService, SignatureService: digitalSignatureService, SnapshotService: snapshotService, SSLService: sslService, @@ -716,7 +716,6 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server { ShutdownCtx: shutdownCtx, ShutdownTrigger: shutdownTrigger, StackDeployer: stackDeployer, - BaseURL: *flags.BaseURL, } } diff --git a/api/http/handler/helm/handler.go b/api/http/handler/helm/handler.go index e3c198305..cb32be80e 100644 --- a/api/http/handler/helm/handler.go +++ b/api/http/handler/helm/handler.go @@ -2,6 +2,7 @@ package helm import ( "net/http" + "strings" "github.com/gorilla/mux" "github.com/portainer/libhelm" @@ -14,10 +15,6 @@ import ( "github.com/portainer/portainer/api/kubernetes" ) -const ( - handlerActivityContext = "Kubernetes" -) - type requestBouncer interface { AuthenticatedAccess(h http.Handler) http.Handler } @@ -25,24 +22,24 @@ type requestBouncer interface { // Handler is the HTTP handler used to handle environment(endpoint) group operations. type Handler struct { *mux.Router - requestBouncer requestBouncer - dataStore dataservices.DataStore - jwtService dataservices.JWTService - kubeConfigService kubernetes.KubeConfigService - kubernetesDeployer portainer.KubernetesDeployer - helmPackageManager libhelm.HelmPackageManager + requestBouncer requestBouncer + dataStore dataservices.DataStore + jwtService dataservices.JWTService + kubeClusterAccessService kubernetes.KubeClusterAccessService + kubernetesDeployer portainer.KubernetesDeployer + helmPackageManager libhelm.HelmPackageManager } // NewHandler creates a handler to manage endpoint group operations. -func NewHandler(bouncer requestBouncer, dataStore dataservices.DataStore, jwtService dataservices.JWTService, kubernetesDeployer portainer.KubernetesDeployer, helmPackageManager libhelm.HelmPackageManager, kubeConfigService kubernetes.KubeConfigService) *Handler { +func NewHandler(bouncer requestBouncer, dataStore dataservices.DataStore, jwtService dataservices.JWTService, kubernetesDeployer portainer.KubernetesDeployer, helmPackageManager libhelm.HelmPackageManager, kubeClusterAccessService kubernetes.KubeClusterAccessService) *Handler { h := &Handler{ - Router: mux.NewRouter(), - requestBouncer: bouncer, - dataStore: dataStore, - jwtService: jwtService, - kubernetesDeployer: kubernetesDeployer, - helmPackageManager: helmPackageManager, - kubeConfigService: kubeConfigService, + Router: mux.NewRouter(), + requestBouncer: bouncer, + dataStore: dataStore, + jwtService: jwtService, + kubernetesDeployer: kubernetesDeployer, + helmPackageManager: helmPackageManager, + kubeClusterAccessService: kubeClusterAccessService, } h.Use(middlewares.WithEndpoint(dataStore.Endpoint(), "id")) @@ -104,10 +101,20 @@ func (handler *Handler) getHelmClusterAccess(r *http.Request) (*options.Kubernet return nil, &httperror.HandlerError{http.StatusUnauthorized, "Unauthorized", err} } - kubeConfigInternal := handler.kubeConfigService.GetKubeConfigInternal(endpoint.ID, bearerToken) + sslSettings, err := handler.dataStore.SSLSettings().Settings() + if err != nil { + return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + } + + hostURL := "localhost" + if !sslSettings.SelfSigned { + hostURL = strings.Split(r.Host, ":")[0] + } + + kubeConfigInternal := handler.kubeClusterAccessService.GetData(hostURL, endpoint.ID) return &options.KubernetesClusterAccess{ ClusterServerURL: kubeConfigInternal.ClusterServerURL, CertificateAuthorityFile: kubeConfigInternal.CertificateAuthorityFile, - AuthToken: kubeConfigInternal.AuthToken, + AuthToken: bearerToken, }, nil } diff --git a/api/http/handler/helm/helm_delete_test.go b/api/http/handler/helm/helm_delete_test.go index 1c74b5061..a1f141159 100644 --- a/api/http/handler/helm/helm_delete_test.go +++ b/api/http/handler/helm/helm_delete_test.go @@ -36,8 +36,8 @@ func Test_helmDelete(t *testing.T) { kubernetesDeployer := exectest.NewKubernetesDeployer() helmPackageManager := test.NewMockHelmBinaryPackageManager("") - kubeConfigService := kubernetes.NewKubeConfigCAService("", "") - h := NewHandler(helper.NewTestRequestBouncer(), store, jwtService, kubernetesDeployer, helmPackageManager, kubeConfigService) + kubeClusterAccessService := kubernetes.NewKubeClusterAccessService("", "", "") + h := NewHandler(helper.NewTestRequestBouncer(), store, jwtService, kubernetesDeployer, helmPackageManager, kubeClusterAccessService) is.NotNil(h, "Handler should not fail") diff --git a/api/http/handler/helm/helm_install_test.go b/api/http/handler/helm/helm_install_test.go index c28b268ec..cb011fc70 100644 --- a/api/http/handler/helm/helm_install_test.go +++ b/api/http/handler/helm/helm_install_test.go @@ -39,8 +39,8 @@ func Test_helmInstall(t *testing.T) { kubernetesDeployer := exectest.NewKubernetesDeployer() helmPackageManager := test.NewMockHelmBinaryPackageManager("") - kubeConfigService := kubernetes.NewKubeConfigCAService("", "") - h := NewHandler(helper.NewTestRequestBouncer(), store, jwtService, kubernetesDeployer, helmPackageManager, kubeConfigService) + kubeClusterAccessService := kubernetes.NewKubeClusterAccessService("", "", "") + h := NewHandler(helper.NewTestRequestBouncer(), store, jwtService, kubernetesDeployer, helmPackageManager, kubeClusterAccessService) is.NotNil(h, "Handler should not fail") diff --git a/api/http/handler/helm/helm_list_test.go b/api/http/handler/helm/helm_list_test.go index 8a48ad4d8..710771b4e 100644 --- a/api/http/handler/helm/helm_list_test.go +++ b/api/http/handler/helm/helm_list_test.go @@ -38,8 +38,8 @@ func Test_helmList(t *testing.T) { kubernetesDeployer := exectest.NewKubernetesDeployer() helmPackageManager := test.NewMockHelmBinaryPackageManager("") - kubeConfigService := kubernetes.NewKubeConfigCAService("", "") - h := NewHandler(helper.NewTestRequestBouncer(), store, jwtService, kubernetesDeployer, helmPackageManager, kubeConfigService) + kubeClusterAccessService := kubernetes.NewKubeClusterAccessService("", "", "") + h := NewHandler(helper.NewTestRequestBouncer(), store, jwtService, kubernetesDeployer, helmPackageManager, kubeClusterAccessService) // Install a single chart. We expect to get these values back options := options.InstallOptions{Name: "nginx-1", Chart: "nginx", Namespace: "default"} diff --git a/api/http/handler/kubernetes/handler.go b/api/http/handler/kubernetes/handler.go index aedc9291c..2e44f7357 100644 --- a/api/http/handler/kubernetes/handler.go +++ b/api/http/handler/kubernetes/handler.go @@ -2,6 +2,7 @@ package kubernetes import ( "errors" + "github.com/portainer/portainer/api/kubernetes" "net/http" "github.com/gorilla/mux" @@ -17,21 +18,22 @@ import ( // Handler is the HTTP handler which will natively deal with to external environments(endpoints). type Handler struct { *mux.Router - dataStore dataservices.DataStore - kubernetesClientFactory *cli.ClientFactory - authorizationService *authorization.Service - JwtService dataservices.JWTService - BaseURL string + authorizationService *authorization.Service + dataStore dataservices.DataStore + jwtService dataservices.JWTService + kubernetesClientFactory *cli.ClientFactory + kubeClusterAccessService kubernetes.KubeClusterAccessService } // NewHandler creates a handler to process pre-proxied requests to external APIs. -func NewHandler(bouncer *security.RequestBouncer, authorizationService *authorization.Service, dataStore dataservices.DataStore, kubernetesClientFactory *cli.ClientFactory, baseURL string) *Handler { +func NewHandler(bouncer *security.RequestBouncer, authorizationService *authorization.Service, dataStore dataservices.DataStore, jwtService dataservices.JWTService, kubeClusterAccessService kubernetes.KubeClusterAccessService, kubernetesClientFactory *cli.ClientFactory) *Handler { h := &Handler{ - Router: mux.NewRouter(), - dataStore: dataStore, - kubernetesClientFactory: kubernetesClientFactory, - authorizationService: authorizationService, - BaseURL: baseURL, + Router: mux.NewRouter(), + authorizationService: authorizationService, + dataStore: dataStore, + jwtService: jwtService, + kubeClusterAccessService: kubeClusterAccessService, + kubernetesClientFactory: kubernetesClientFactory, } kubeRouter := h.PathPrefix("/kubernetes").Subrouter() diff --git a/api/http/handler/kubernetes/kubernetes_config.go b/api/http/handler/kubernetes/kubernetes_config.go index e9211cc63..fcb8ce0d8 100644 --- a/api/http/handler/kubernetes/kubernetes_config.go +++ b/api/http/handler/kubernetes/kubernetes_config.go @@ -39,7 +39,7 @@ func (handler *Handler) getKubernetesConfig(w http.ResponseWriter, r *http.Reque if err != nil { return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} } - bearerToken, err := handler.JwtService.GenerateTokenForKubeconfig(tokenData) + bearerToken, err := handler.jwtService.GenerateTokenForKubeconfig(tokenData) if err != nil { return &httperror.HandlerError{http.StatusInternalServerError, "Unable to generate JWT token", err} } @@ -126,7 +126,7 @@ func (handler *Handler) buildConfig(r *http.Request, tokenData *portainer.TokenD instanceID := handler.kubernetesClientFactory.GetInstanceID() serviceAccountName := kcli.UserServiceAccountName(int(tokenData.ID), instanceID) - configClusters[idx] = buildCluster(r, handler.BaseURL, endpoint) + configClusters[idx] = handler.buildCluster(r, endpoint) configContexts[idx] = buildContext(serviceAccountName, endpoint) if !authInfosSet[serviceAccountName] { configAuthInfos = append(configAuthInfos, buildAuthInfo(serviceAccountName, bearerToken)) @@ -144,15 +144,13 @@ func (handler *Handler) buildConfig(r *http.Request, tokenData *portainer.TokenD }, nil } -func buildCluster(r *http.Request, baseURL string, endpoint portainer.Endpoint) clientV1.NamedCluster { - if baseURL != "/" { - baseURL = fmt.Sprintf("/%s/", strings.Trim(baseURL, "/")) - } - proxyURL := fmt.Sprintf("https://%s%sapi/endpoints/%d/kubernetes", r.Host, baseURL, endpoint.ID) +func (handler *Handler) buildCluster(r *http.Request, endpoint portainer.Endpoint) clientV1.NamedCluster { + hostURL := strings.Split(r.Host, ":")[0] + kubeConfigInternal := handler.kubeClusterAccessService.GetData(hostURL, endpoint.ID) return clientV1.NamedCluster{ Name: buildClusterName(endpoint.Name), Cluster: clientV1.Cluster{ - Server: proxyURL, + Server: kubeConfigInternal.ClusterServerURL, InsecureSkipTLSVerify: true, }, } diff --git a/api/http/server.go b/api/http/server.go index b8f45fe68..4832a3db1 100644 --- a/api/http/server.go +++ b/api/http/server.go @@ -87,7 +87,7 @@ type Server struct { SwarmStackManager portainer.SwarmStackManager ProxyManager *proxy.Manager KubernetesTokenCacheManager *kubernetes.TokenCacheManager - KubeConfigService k8s.KubeConfigService + KubeClusterAccessService k8s.KubeClusterAccessService Handler *handler.Handler SSLService *ssl.Service DockerClientFactory *docker.ClientFactory @@ -98,7 +98,6 @@ type Server struct { ShutdownCtx context.Context ShutdownTrigger context.CancelFunc StackDeployer stackdeployer.StackDeployer - BaseURL string } // Start starts the HTTP server @@ -175,12 +174,11 @@ func (server *Server) Start() error { endpointProxyHandler.ProxyManager = server.ProxyManager endpointProxyHandler.ReverseTunnelService = server.ReverseTunnelService - var kubernetesHandler = kubehandler.NewHandler(requestBouncer, server.AuthorizationService, server.DataStore, server.KubernetesClientFactory, server.BaseURL) - kubernetesHandler.JwtService = server.JWTService + var kubernetesHandler = kubehandler.NewHandler(requestBouncer, server.AuthorizationService, server.DataStore, server.JWTService, server.KubeClusterAccessService, server.KubernetesClientFactory) var fileHandler = file.NewHandler(filepath.Join(server.AssetsPath, "public")) - var endpointHelmHandler = helm.NewHandler(requestBouncer, server.DataStore, server.JWTService, server.KubernetesDeployer, server.HelmPackageManager, server.KubeConfigService) + var endpointHelmHandler = helm.NewHandler(requestBouncer, server.DataStore, server.JWTService, server.KubernetesDeployer, server.HelmPackageManager, server.KubeClusterAccessService) var helmTemplatesHandler = helm.NewTemplateHandler(requestBouncer, server.HelmPackageManager) diff --git a/api/kubernetes/kubeconfig_service.go b/api/kubernetes/kubeclusteraccess_service.go similarity index 62% rename from api/kubernetes/kubeconfig_service.go rename to api/kubernetes/kubeclusteraccess_service.go index 84ac6834a..dcbe204f7 100644 --- a/api/kubernetes/kubeconfig_service.go +++ b/api/kubernetes/kubeclusteraccess_service.go @@ -7,26 +7,27 @@ import ( "fmt" "io/ioutil" "log" + "strings" "github.com/pkg/errors" portainer "github.com/portainer/portainer/api" ) -// KubeConfigService represents a service that is responsible for handling kubeconfig operations -type KubeConfigService interface { +// KubeClusterAccessService represents a service that is responsible for centralizing kube cluster access data +type KubeClusterAccessService interface { IsSecure() bool - GetKubeConfigInternal(endpointId portainer.EndpointID, authToken string) kubernetesClusterAccess + GetData(hostURL string, endpointId portainer.EndpointID) kubernetesClusterAccessData } // KubernetesClusterAccess represents core details which can be used to generate KubeConfig file/data -type kubernetesClusterAccess struct { +type kubernetesClusterAccessData struct { ClusterServerURL string `example:"https://mycompany.k8s.com"` CertificateAuthorityFile string `example:"/data/tls/localhost.crt"` CertificateAuthorityData string `example:"MIIC5TCCAc2gAwIBAgIJAJ+...+xuhOaFXwQ=="` - AuthToken string `example:"ey..."` } -type kubeConfigCAService struct { +type kubeClusterAccessService struct { + baseURL string httpsBindAddr string certificateAuthorityFile string certificateAuthorityData string @@ -39,14 +40,15 @@ var ( errTLSCertValidation = errors.New("failed to parse tls certificate") ) -// NewKubeConfigCAService encapsulates generation of core KubeConfig data -func NewKubeConfigCAService(httpsBindAddr string, tlsCertPath string) KubeConfigService { +// NewKubeClusterAccessService creates a new instance of a KubeClusterAccessService +func NewKubeClusterAccessService(baseURL, httpsBindAddr, tlsCertPath string) KubeClusterAccessService { certificateAuthorityData, err := getCertificateAuthorityData(tlsCertPath) if err != nil { log.Printf("[DEBUG] [internal,kubeconfig] [message: %s, generated KubeConfig will be insecure]", err.Error()) } - return &kubeConfigCAService{ + return &kubeClusterAccessService{ + baseURL: baseURL, httpsBindAddr: httpsBindAddr, certificateAuthorityFile: tlsCertPath, certificateAuthorityData: certificateAuthorityData, @@ -82,23 +84,27 @@ func getCertificateAuthorityData(tlsCertPath string) (string, error) { // this is based on the fact that we can successfully extract `certificateAuthorityData` from // certificate file at `tlsCertPath`. If we can successfully extract `certificateAuthorityData`, // then this will be used as `certificate-authority-data` attribute in a generated KubeConfig. -func (kccas *kubeConfigCAService) IsSecure() bool { - return kccas.certificateAuthorityData != "" +func (service *kubeClusterAccessService) IsSecure() bool { + return service.certificateAuthorityData != "" } -// GetKubeConfigInternal returns K8s cluster access details for the specified environment(endpoint). -// On startup, portainer generates a certificate against localhost at specified `httpsBindAddr` port, hence -// the kubeconfig generated should only be utilised by internal portainer binaries as the `ClusterServerURL` -// points to the internally accessible `https` based `localhost` address. +// GetData returns K8s cluster access details for the specified environment(endpoint). // The struct can be used to: // - generate a kubeconfig file // - pass down params to binaries -func (kccas *kubeConfigCAService) GetKubeConfigInternal(endpointId portainer.EndpointID, authToken string) kubernetesClusterAccess { - clusterServerUrl := fmt.Sprintf("https://localhost%s/api/endpoints/%s/kubernetes", kccas.httpsBindAddr, fmt.Sprint(endpointId)) - return kubernetesClusterAccess{ - ClusterServerURL: clusterServerUrl, - CertificateAuthorityFile: kccas.certificateAuthorityFile, - CertificateAuthorityData: kccas.certificateAuthorityData, - AuthToken: authToken, +func (service *kubeClusterAccessService) GetData(hostURL string, endpointID portainer.EndpointID) kubernetesClusterAccessData { + baseURL := service.baseURL + if baseURL != "/" { + baseURL = fmt.Sprintf("/%s/", strings.Trim(baseURL, "/")) + } + + clusterURL := hostURL + service.httpsBindAddr + baseURL + + clusterServerURL := fmt.Sprintf("https://%sapi/endpoints/%d/kubernetes", clusterURL, endpointID) + + return kubernetesClusterAccessData{ + ClusterServerURL: clusterServerURL, + CertificateAuthorityFile: service.certificateAuthorityFile, + CertificateAuthorityData: service.certificateAuthorityData, } } diff --git a/api/kubernetes/kubeconfig_service_test.go b/api/kubernetes/kubeclusteraccess_service_test.go similarity index 77% rename from api/kubernetes/kubeconfig_service_test.go rename to api/kubernetes/kubeclusteraccess_service_test.go index 402b4f082..d415d86e5 100644 --- a/api/kubernetes/kubeconfig_service_test.go +++ b/api/kubernetes/kubeclusteraccess_service_test.go @@ -78,11 +78,11 @@ func Test_getCertificateAuthorityData(t *testing.T) { }) } -func TestKubeConfigService_IsSecure(t *testing.T) { +func TestKubeClusterAccessService_IsSecure(t *testing.T) { is := assert.New(t) t.Run("IsSecure should be false", func(t *testing.T) { - kcs := NewKubeConfigCAService("", "") + kcs := NewKubeClusterAccessService("", "", "") is.False(kcs.IsSecure(), "should be false if TLS cert not provided") }) @@ -90,39 +90,32 @@ func TestKubeConfigService_IsSecure(t *testing.T) { filePath, teardown := createTempFile("valid-cert.crt", certData) defer teardown() - kcs := NewKubeConfigCAService("", filePath) + kcs := NewKubeClusterAccessService("", "", filePath) is.True(kcs.IsSecure(), "should be true if valid TLS cert (path and content) provided") }) } -func TestKubeConfigService_GetKubeConfigInternal(t *testing.T) { +func TestKubeClusterAccessService_GetKubeConfigInternal(t *testing.T) { is := assert.New(t) - t.Run("GetKubeConfigInternal returns localhost address", func(t *testing.T) { - kcs := NewKubeConfigCAService("", "") - clusterAccessDetails := kcs.GetKubeConfigInternal(1, "some-token") - is.True(strings.Contains(clusterAccessDetails.ClusterServerURL, "https://localhost"), "should contain localhost address") + t.Run("GetData contains host address", func(t *testing.T) { + kcs := NewKubeClusterAccessService("/", "", "") + clusterAccessDetails := kcs.GetData("mysite.com", 1) + is.True(strings.Contains(clusterAccessDetails.ClusterServerURL, "https://mysite.com"), "should contain host address") }) - t.Run("GetKubeConfigInternal contains https bind address port", func(t *testing.T) { - kcs := NewKubeConfigCAService(":1010", "") - clusterAccessDetails := kcs.GetKubeConfigInternal(1, "some-token") - is.True(strings.Contains(clusterAccessDetails.ClusterServerURL, ":1010"), "should contain bind address port") - }) - - t.Run("GetKubeConfigInternal contains environment proxy url", func(t *testing.T) { - kcs := NewKubeConfigCAService("", "") - clusterAccessDetails := kcs.GetKubeConfigInternal(100, "some-token") + t.Run("GetData contains environment proxy url", func(t *testing.T) { + kcs := NewKubeClusterAccessService("/", "", "") + clusterAccessDetails := kcs.GetData("mysite.com", 100) is.True(strings.Contains(clusterAccessDetails.ClusterServerURL, "api/endpoints/100/kubernetes"), "should contain environment proxy url") }) - t.Run("GetKubeConfigInternal returns insecure cluster access config", func(t *testing.T) { - kcs := NewKubeConfigCAService("", "") - clusterAccessDetails := kcs.GetKubeConfigInternal(1, "some-token") + t.Run("GetData returns insecure cluster access config", func(t *testing.T) { + kcs := NewKubeClusterAccessService("/", ":9443", "") + clusterAccessDetails := kcs.GetData("mysite.com", 1) - wantClusterAccessDetails := kubernetesClusterAccess{ - ClusterServerURL: "https://localhost/api/endpoints/1/kubernetes", - AuthToken: "some-token", + wantClusterAccessDetails := kubernetesClusterAccessData{ + ClusterServerURL: "https://mysite.com:9443/api/endpoints/1/kubernetes", CertificateAuthorityFile: "", CertificateAuthorityData: "", } @@ -130,16 +123,15 @@ func TestKubeConfigService_GetKubeConfigInternal(t *testing.T) { is.Equal(clusterAccessDetails, wantClusterAccessDetails) }) - t.Run("GetKubeConfigInternal returns secure cluster access config", func(t *testing.T) { + t.Run("GetData returns secure cluster access config", func(t *testing.T) { filePath, teardown := createTempFile("valid-cert.crt", certData) defer teardown() - kcs := NewKubeConfigCAService("", filePath) - clusterAccessDetails := kcs.GetKubeConfigInternal(1, "some-token") + kcs := NewKubeClusterAccessService("/", "", filePath) + clusterAccessDetails := kcs.GetData("localhost", 1) - wantClusterAccessDetails := kubernetesClusterAccess{ + wantClusterAccessDetails := kubernetesClusterAccessData{ ClusterServerURL: "https://localhost/api/endpoints/1/kubernetes", - AuthToken: "some-token", CertificateAuthorityFile: filePath, CertificateAuthorityData: certDataString, }