package kubernetes_test import ( "testing" "github.com/go-test/deep" "github.com/porter-dev/porter/api/types" "github.com/porter-dev/porter/internal/kubernetes" "github.com/porter-dev/porter/internal/kubernetes/fixtures" "github.com/porter-dev/porter/internal/models" "k8s.io/client-go/tools/clientcmd" ) type ccsTest struct { name string raw []byte expected []*models.ClusterCandidate } var ClusterCandidatesTests = []ccsTest{ { name: "test without cluster ca data", raw: []byte(fixtures.ClusterCAWithoutData), expected: []*models.ClusterCandidate{ { AuthMechanism: models.X509, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: types.ClusterCAData, Resolved: false, Data: []byte(`{"filename":"/fake/path/to/ca.pem"}`), }, }, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.ClusterCAWithoutData), AWSClusterIDGuess: []byte{}, }, }, }, { name: "test cluster localhost", raw: []byte(fixtures.ClusterLocalhost), expected: []*models.ClusterCandidate{ { AuthMechanism: models.X509, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: types.ClusterLocalhost, Resolved: false, }, }, Name: "cluster-test", Server: "https://localhost:30000", ContextName: "context-test", Kubeconfig: []byte(fixtures.ClusterLocalhost), AWSClusterIDGuess: []byte{}, }, }, }, { name: "x509 test with cert and key data", raw: []byte(fixtures.X509WithData), expected: []*models.ClusterCandidate{ { AuthMechanism: models.X509, ProjectID: 1, Resolvers: []models.ClusterResolver{}, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.X509WithData), AWSClusterIDGuess: []byte{}, }, }, }, { name: "x509 test without cert data", raw: []byte(fixtures.X509WithoutCertData), expected: []*models.ClusterCandidate{ { AuthMechanism: models.X509, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: "upload-client-cert-data", Resolved: false, Data: []byte(`{"filename":"/fake/path/to/cert.pem"}`), }, }, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.X509WithoutCertData), AWSClusterIDGuess: []byte{}, }, }, }, { name: "x509 test without key data", raw: []byte(fixtures.X509WithoutKeyData), expected: []*models.ClusterCandidate{ { AuthMechanism: models.X509, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: "upload-client-key-data", Resolved: false, Data: []byte(`{"filename":"/fake/path/to/key.pem"}`), }, }, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.X509WithoutKeyData), AWSClusterIDGuess: []byte{}, }, }, }, { name: "x509 test without cert and key data", raw: []byte(fixtures.X509WithoutCertAndKeyData), expected: []*models.ClusterCandidate{ { AuthMechanism: models.X509, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: "upload-client-cert-data", Resolved: false, Data: []byte(`{"filename":"/fake/path/to/cert.pem"}`), }, { Name: "upload-client-key-data", Resolved: false, Data: []byte(`{"filename":"/fake/path/to/key.pem"}`), }, }, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.X509WithoutCertAndKeyData), AWSClusterIDGuess: []byte{}, }, }, }, { name: "bearer token test with data", raw: []byte(fixtures.BearerTokenWithData), expected: []*models.ClusterCandidate{ { AuthMechanism: models.Bearer, ProjectID: 1, Resolvers: []models.ClusterResolver{}, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.BearerTokenWithData), AWSClusterIDGuess: []byte{}, }, }, }, { name: "bearer token test without data", raw: []byte(fixtures.BearerTokenWithoutData), expected: []*models.ClusterCandidate{ { AuthMechanism: models.Bearer, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: "upload-token-data", Resolved: false, Data: []byte(`{"filename":"/path/to/token/file.txt"}`), }, }, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.BearerTokenWithoutData), AWSClusterIDGuess: []byte{}, }, }, }, { name: "gcp test", raw: []byte(fixtures.GCPPlugin), expected: []*models.ClusterCandidate{ { AuthMechanism: models.GCP, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: "upload-gcp-key-data", Resolved: false, }, }, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.GCPPlugin), AWSClusterIDGuess: []byte{}, }, }, }, { name: "aws iam authenticator test", raw: []byte(fixtures.AWSIamAuthenticatorExec), expected: []*models.ClusterCandidate{ { AuthMechanism: models.AWS, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: "upload-aws-data", Resolved: false, }, }, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.AWSIamAuthenticatorExec), AWSClusterIDGuess: []byte("cluster-test-aws-id-guess"), }, }, }, { name: "aws eks get-token test", raw: []byte(fixtures.AWSEKSGetTokenExec), expected: []*models.ClusterCandidate{ { AuthMechanism: models.AWS, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: "upload-aws-data", Resolved: false, }, }, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.AWSEKSGetTokenExec), AWSClusterIDGuess: []byte("cluster-test-aws-id-guess"), }, }, }, { name: "oidc without ca data", raw: []byte(fixtures.OIDCAuthWithoutData), expected: []*models.ClusterCandidate{ { AuthMechanism: models.OIDC, ProjectID: 1, Resolvers: []models.ClusterResolver{ { Name: "upload-oidc-idp-issuer-ca-data", Resolved: false, Data: []byte(`{"filename":"/fake/path/to/ca.pem"}`), }, }, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.OIDCAuthWithoutData), AWSClusterIDGuess: []byte{}, }, }, }, { name: "oidc with ca data", raw: []byte(fixtures.OIDCAuthWithData), expected: []*models.ClusterCandidate{ { AuthMechanism: models.OIDC, ProjectID: 1, Resolvers: []models.ClusterResolver{}, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.OIDCAuthWithData), AWSClusterIDGuess: []byte{}, }, }, }, { name: "basic auth test", raw: []byte(fixtures.BasicAuth), expected: []*models.ClusterCandidate{ { AuthMechanism: models.Basic, ProjectID: 1, Resolvers: []models.ClusterResolver{}, Name: "cluster-test", Server: "https://10.10.10.10", ContextName: "context-test", Kubeconfig: []byte(fixtures.BasicAuth), AWSClusterIDGuess: []byte{}, }, }, }, } func TestGetClusterCandidatesNonLocal(t *testing.T) { for _, c := range ClusterCandidatesTests { result, err := kubernetes.GetClusterCandidatesFromKubeconfig(c.raw, 1, false) if err != nil { t.Fatalf("error occurred %v\n", err) } // make result into a map so it's easier to compare resMap := make(map[string]*models.ClusterCandidate) for _, res := range result { resMap[res.Server+"-"+string(res.AuthMechanism)] = res } for _, exp := range c.expected { res, ok := resMap[exp.Server+"-"+string(exp.AuthMechanism)] if !ok { t.Fatalf("%s failed: no matching result for %s\n", c.name, exp.Server+"-"+string(exp.AuthMechanism)) } // compare kubeconfig by transforming into a client config resConfig, _ := clientcmd.NewClientConfigFromBytes(res.Kubeconfig) expConfig, err := clientcmd.NewClientConfigFromBytes(exp.Kubeconfig) if err != nil { t.Fatalf("config from bytes, error occurred %v\n", err) } resRawConf, _ := resConfig.RawConfig() expRawConf, err := expConfig.RawConfig() if err != nil { t.Fatalf("raw config conversion, error occurred %v\n", err) } if diff := deep.Equal(expRawConf, resRawConf); diff != nil { t.Errorf("incorrect kubeconfigs") t.Error(diff) } // reset kubeconfigs since they won't be exactly "deep equal" exp.Kubeconfig = []byte{} res.Kubeconfig = []byte{} if diff := deep.Equal(exp, res); diff != nil { t.Errorf("incorrect cluster candidate") t.Error(diff) } } } }