|
|
@@ -0,0 +1,304 @@
|
|
|
+package api_test
|
|
|
+
|
|
|
+import (
|
|
|
+ "context"
|
|
|
+ "testing"
|
|
|
+
|
|
|
+ "github.com/porter-dev/porter/internal/models"
|
|
|
+
|
|
|
+ "github.com/porter-dev/porter/cli/cmd/api"
|
|
|
+)
|
|
|
+
|
|
|
+func initProject(name string, client *api.Client, t *testing.T) *api.CreateProjectResponse {
|
|
|
+ t.Helper()
|
|
|
+
|
|
|
+ resp, err := client.CreateProject(context.Background(), &api.CreateProjectRequest{
|
|
|
+ Name: name,
|
|
|
+ })
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("%v\n", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return resp
|
|
|
+}
|
|
|
+
|
|
|
+func initProjectCandidate(
|
|
|
+ projectID uint,
|
|
|
+ kubeconfig string,
|
|
|
+ client *api.Client,
|
|
|
+ t *testing.T,
|
|
|
+) *models.ServiceAccountCandidateExternal {
|
|
|
+ t.Helper()
|
|
|
+
|
|
|
+ resp, err := client.CreateProjectCandidates(
|
|
|
+ context.Background(),
|
|
|
+ projectID,
|
|
|
+ &api.CreateProjectCandidatesRequest{
|
|
|
+ Kubeconfig: kubeconfig,
|
|
|
+ },
|
|
|
+ )
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("%v\n", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return resp[0]
|
|
|
+}
|
|
|
+
|
|
|
+func TestCreateProject(t *testing.T) {
|
|
|
+ email := "create_project_test@example.com"
|
|
|
+ client := api.NewClient(baseURL, "cookie_create_project_test.json")
|
|
|
+ user := initUser(email, client, t)
|
|
|
+ client.Login(context.Background(), &api.LoginRequest{
|
|
|
+ Email: user.Email,
|
|
|
+ Password: "hello1234",
|
|
|
+ })
|
|
|
+
|
|
|
+ resp, err := client.CreateProject(context.Background(), &api.CreateProjectRequest{
|
|
|
+ Name: "project-test",
|
|
|
+ })
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("%v\n", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure user is admin and project name is correct
|
|
|
+ if resp.Name != "project-test" {
|
|
|
+ t.Errorf("project name incorrect: expected %s, got %s\n", "project-test", resp.Name)
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(resp.Roles) != 1 {
|
|
|
+ t.Fatalf("project role length is not 1")
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.Roles[0].Kind != models.RoleAdmin {
|
|
|
+ t.Errorf("project role kind is incorrect: expected %s, got %s\n", models.RoleAdmin, resp.Roles[0].Kind)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.Roles[0].UserID != user.ID {
|
|
|
+ t.Errorf("project role user_id is incorrect: expected %d, got %d\n", user.ID, resp.Roles[0].UserID)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestGetProject(t *testing.T) {
|
|
|
+ email := "get_project_test@example.com"
|
|
|
+ client := api.NewClient(baseURL, "cookie_get_project_test.json")
|
|
|
+ user := initUser(email, client, t)
|
|
|
+ client.Login(context.Background(), &api.LoginRequest{
|
|
|
+ Email: user.Email,
|
|
|
+ Password: "hello1234",
|
|
|
+ })
|
|
|
+ project := initProject("project-test", client, t)
|
|
|
+
|
|
|
+ resp, err := client.GetProject(context.Background(), project.ID)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("%v\n", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure user is admin and project name is correct
|
|
|
+ if resp.Name != "project-test" {
|
|
|
+ t.Errorf("project name incorrect: expected %s, got %s\n", "project-test", resp.Name)
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(resp.Roles) != 1 {
|
|
|
+ t.Fatalf("project role length is not 1")
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.Roles[0].Kind != models.RoleAdmin {
|
|
|
+ t.Errorf("project role kind is incorrect: expected %s, got %s\n", models.RoleAdmin, resp.Roles[0].Kind)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.Roles[0].UserID != user.ID {
|
|
|
+ t.Errorf("project role user_id is incorrect: expected %d, got %d\n", user.ID, resp.Roles[0].UserID)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestCreateProjectCandidates(t *testing.T) {
|
|
|
+ email := "create_project_candidates_test@example.com"
|
|
|
+ client := api.NewClient(baseURL, "cookie_create_project_candidates_test.json")
|
|
|
+ user := initUser(email, client, t)
|
|
|
+ client.Login(context.Background(), &api.LoginRequest{
|
|
|
+ Email: user.Email,
|
|
|
+ Password: "hello1234",
|
|
|
+ })
|
|
|
+ project := initProject("project-test", client, t)
|
|
|
+
|
|
|
+ resp, err := client.CreateProjectCandidates(
|
|
|
+ context.Background(),
|
|
|
+ project.ID,
|
|
|
+ &api.CreateProjectCandidatesRequest{
|
|
|
+ Kubeconfig: OIDCAuthWithoutData,
|
|
|
+ },
|
|
|
+ )
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("%v\n", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure length is 1
|
|
|
+ if len(resp) != 1 {
|
|
|
+ t.Fatalf("candidates length is not 1\n")
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure auth mechanism is OIDC, project id is correct, and cluster info is correct
|
|
|
+ if resp[0].AuthMechanism != models.OIDC {
|
|
|
+ t.Errorf("oidc auth mechanism incorrect: expected %s, got %s\n", models.OIDC, resp[0].AuthMechanism)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp[0].ProjectID != project.ID {
|
|
|
+ t.Errorf("project id incorrect: expected %d, got %d\n", project.ID, resp[0].ProjectID)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp[0].ClusterName != "cluster-test" {
|
|
|
+ t.Errorf("cluster name incorrect: expected %s, got %s\n", "cluster-test", resp[0].ClusterName)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp[0].ClusterEndpoint != "https://localhost" {
|
|
|
+ t.Errorf("cluster endpoint incorrect: expected %s, got %s\n", "https://localhost", resp[0].ClusterEndpoint)
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure correct actions need to be performed
|
|
|
+ if len(resp[0].Actions) != 1 {
|
|
|
+ t.Fatalf("actions length is not 1\n")
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp[0].Actions[0].Name != models.OIDCIssuerDataAction {
|
|
|
+ t.Errorf("action name incorrect: expected %s, got %s\n", models.OIDCIssuerDataAction, resp[0].Actions[0].Name)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestGetProjectCandidates(t *testing.T) {
|
|
|
+ email := "get_project_candidates_test@example.com"
|
|
|
+ client := api.NewClient(baseURL, "cookie_get_project_candidates_test.json")
|
|
|
+ user := initUser(email, client, t)
|
|
|
+ client.Login(context.Background(), &api.LoginRequest{
|
|
|
+ Email: user.Email,
|
|
|
+ Password: "hello1234",
|
|
|
+ })
|
|
|
+ project := initProject("project-test", client, t)
|
|
|
+ initProjectCandidate(project.ID, OIDCAuthWithoutData, client, t)
|
|
|
+
|
|
|
+ resp, err := client.GetProjectCandidates(context.Background(), project.ID)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("%v\n", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure length is 1
|
|
|
+ if len(resp) != 1 {
|
|
|
+ t.Fatalf("candidates length is not 1\n")
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure auth mechanism is OIDC, project id is correct, and cluster info is correct
|
|
|
+ if resp[0].AuthMechanism != models.OIDC {
|
|
|
+ t.Errorf("oidc auth mechanism incorrect: expected %s, got %s\n", models.OIDC, resp[0].AuthMechanism)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp[0].ProjectID != project.ID {
|
|
|
+ t.Errorf("project id incorrect: expected %d, got %d\n", project.ID, resp[0].ProjectID)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp[0].ClusterName != "cluster-test" {
|
|
|
+ t.Errorf("cluster name incorrect: expected %s, got %s\n", "cluster-test", resp[0].ClusterName)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp[0].ClusterEndpoint != "https://localhost" {
|
|
|
+ t.Errorf("cluster endpoint incorrect: expected %s, got %s\n", "https://localhost", resp[0].ClusterEndpoint)
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure correct actions need to be performed
|
|
|
+ if len(resp[0].Actions) != 1 {
|
|
|
+ t.Fatalf("actions length is not 1\n")
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp[0].Actions[0].Name != models.OIDCIssuerDataAction {
|
|
|
+ t.Errorf("action name incorrect: expected %s, got %s\n", models.OIDCIssuerDataAction, resp[0].Actions[0].Name)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestCreateProjectServiceAccount(t *testing.T) {
|
|
|
+ email := "create_project_sa_test@example.com"
|
|
|
+ client := api.NewClient(baseURL, "cookie_create_project_sa_test.json")
|
|
|
+ user := initUser(email, client, t)
|
|
|
+ client.Login(context.Background(), &api.LoginRequest{
|
|
|
+ Email: user.Email,
|
|
|
+ Password: "hello1234",
|
|
|
+ })
|
|
|
+ project := initProject("project-test", client, t)
|
|
|
+ saCandidate := initProjectCandidate(project.ID, OIDCAuthWithoutData, client, t)
|
|
|
+
|
|
|
+ resp, err := client.CreateProjectServiceAccount(
|
|
|
+ context.Background(),
|
|
|
+ project.ID,
|
|
|
+ saCandidate.ID,
|
|
|
+ api.CreateProjectServiceAccountRequest{
|
|
|
+ &models.ServiceAccountAllActions{
|
|
|
+ Name: models.OIDCIssuerDataAction,
|
|
|
+ OIDCIssuerCAData: "LS0tLS1CRUdJTiBDRVJ=",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ )
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("%v\n", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // ensure project id and metadata is correct
|
|
|
+ if resp.ProjectID != project.ID {
|
|
|
+ t.Errorf("project id incorrect: expected %d, got %d\n", project.ID, resp.ProjectID)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.Kind != "connector" {
|
|
|
+ t.Errorf("service account kind incorrect: expected %s, got %s\n", "connector", resp.Kind)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.AuthMechanism != models.OIDC {
|
|
|
+ t.Errorf("service account auth mechanism incorrect: expected %s, got %s\n", models.OIDC, resp.AuthMechanism)
|
|
|
+ }
|
|
|
+
|
|
|
+ // verify clusters
|
|
|
+ if len(resp.Clusters) != 1 {
|
|
|
+ t.Fatalf("length of clusters is not 1")
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.Clusters[0].ServiceAccountID != resp.ID {
|
|
|
+ t.Errorf("cluster's sa id is incorrect: expected %d, got %d\n", resp.ID, resp.Clusters[0].ServiceAccountID)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.Clusters[0].Name != "cluster-test" {
|
|
|
+ t.Errorf("cluster's name is incorrect: expected %s, got %s\n", "cluster-test", resp.Clusters[0].Name)
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.Clusters[0].Server != "https://localhost" {
|
|
|
+ t.Errorf("cluster's name is incorrect: expected %s, got %s\n", "https://localhost", resp.Clusters[0].Server)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const OIDCAuthWithoutData string = `
|
|
|
+apiVersion: v1
|
|
|
+clusters:
|
|
|
+- cluster:
|
|
|
+ server: https://localhost
|
|
|
+ certificate-authority-data: LS0tLS1CRUdJTiBDRVJ=
|
|
|
+ name: cluster-test
|
|
|
+contexts:
|
|
|
+- context:
|
|
|
+ cluster: cluster-test
|
|
|
+ user: test-admin
|
|
|
+ name: context-test
|
|
|
+current-context: context-test
|
|
|
+kind: Config
|
|
|
+preferences: {}
|
|
|
+users:
|
|
|
+- name: test-admin
|
|
|
+ user:
|
|
|
+ auth-provider:
|
|
|
+ config:
|
|
|
+ client-id: porter-api
|
|
|
+ id-token: token
|
|
|
+ idp-issuer-url: https://localhost
|
|
|
+ idp-certificate-authority: /fake/path/to/ca.pem
|
|
|
+ name: oidc
|
|
|
+`
|