diff --git a/tests/e2e/idps_test.go b/tests/e2e/idps_test.go new file mode 100644 index 00000000..ebdf4329 --- /dev/null +++ b/tests/e2e/idps_test.go @@ -0,0 +1,86 @@ +package e2e + +import ( + "net/http" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + conn "github.com/terraform-redhat/terraform-provider-rhcs/tests/ci" + "github.com/terraform-redhat/terraform-provider-rhcs/tests/utils/cms" + con "github.com/terraform-redhat/terraform-provider-rhcs/tests/utils/constants" + exe "github.com/terraform-redhat/terraform-provider-rhcs/tests/utils/exec" +) + +var _ = Describe("TF Test", func() { + Describe("Identity Providers test cases", func() { + + // all identity providers - declared for future cases + type IDPServices struct { + htpasswd, + github, + gitlab, + google, + ldap, + openid exe.IDPService + } + + var idpService IDPServices + + Describe("Htpasswd IDP test cases", func() { + var htpasswdMap = []interface{}{map[string]string{}} + var htpasswdUsername, htpasswdPassword string + + BeforeEach(func() { + + htpasswdUsername = "jacko" + htpasswdPassword = "1q2wFe4rpoe2318" + htpasswdMap = []interface{}{map[string]string{"username": htpasswdUsername, "password": htpasswdPassword}} + idpService.htpasswd = *exe.NewIDPService(con.HtpasswdDir) // init new htpasswd service + }) + + AfterEach(func() { + err := idpService.htpasswd.Destroy() + Expect(err).ToNot(HaveOccurred()) + }) + + Context("Author:smiron-High-OCP-63151 @OCP-63151 @smiron", func() { + It("OCP-63151 - Provision HTPASSWD IDP against cluster using TF", func() { + By("Create htpasswd idp for an existing cluster") + + idpParam := &exe.IDPArgs{ + Token: token, + ClusterID: clusterID, + Name: "htpasswd-idp-test", + HtpasswdUsers: htpasswdMap, + } + err := idpService.htpasswd.Create(idpParam, "-auto-approve", "-no-color") + Expect(err).ToNot(HaveOccurred()) + idpID, _ := idpService.htpasswd.Output() + + By("List existing HtpasswdUsers and compare to the created one") + htpasswdUsersList, _ := cms.ListHtpasswdUsers(conn.RHCSConnection, clusterID, idpID.ID) + Expect(htpasswdUsersList.Status()).To(Equal(http.StatusOK)) + respUserName, _ := htpasswdUsersList.Items().Slice()[0].GetUsername() + Expect(respUserName).To(Equal(htpasswdUsername)) + + By("Login with created htpasswd idp") + getResp, err := cms.RetrieveClusterDetail(conn.RHCSConnection, clusterID) + Expect(err).ToNot(HaveOccurred()) + server := getResp.Body().API().URL() + + ocAtter := &exe.OcAttributes{ + Server: server, + Username: htpasswdUsername, + Password: htpasswdPassword, + ClusterID: clusterID, + AdditioanlFlags: nil, + Timeout: 5, + } + err = exe.OcLogin(*ocAtter) + Expect(err).ToNot(HaveOccurred()) + + }) + }) + }) + }) +}) diff --git a/tests/e2e/init_test.go b/tests/e2e/init_test.go index 3eb997a5..a11cfbb8 100644 --- a/tests/e2e/init_test.go +++ b/tests/e2e/init_test.go @@ -12,9 +12,11 @@ import ( var ctx context.Context var token string +var clusterID string func TestRHCSProvider(t *testing.T) { token = CI.GetEnvWithDefault(CON.TokenENVName, "") + clusterID = CI.GetEnvWithDefault(CON.ClusterIDEnv, "") ctx = context.Background() RegisterFailHandler(Fail) RunSpecs(t, "RHCS Provider Test") diff --git a/tests/tf-manifests/rhcs/idps/htpasswd/main.tf b/tests/tf-manifests/rhcs/idps/htpasswd/main.tf index 7dde8f51..cdeab15f 100644 --- a/tests/tf-manifests/rhcs/idps/htpasswd/main.tf +++ b/tests/tf-manifests/rhcs/idps/htpasswd/main.tf @@ -22,17 +22,17 @@ terraform { } } + provider "rhcs" { token = var.token url = var.gateway } -resource "rhcs_identity_provider" "htpassed_idp" { - cluster = var.cluster_id - name = var.name +resource "rhcs_identity_provider" "htpasswd_idp" { + cluster = var.cluster_id + name = var.name mapping_method = var.mapping_method htpasswd = { - username = var.username - password = var.password + users = var.htpasswd_users } } \ No newline at end of file diff --git a/tests/tf-manifests/rhcs/idps/htpasswd/output.tf b/tests/tf-manifests/rhcs/idps/htpasswd/output.tf index e69de29b..596fc2b3 100644 --- a/tests/tf-manifests/rhcs/idps/htpasswd/output.tf +++ b/tests/tf-manifests/rhcs/idps/htpasswd/output.tf @@ -0,0 +1,3 @@ +output "idp_id" { + value = rhcs_identity_provider.htpasswd_idp.id +} \ No newline at end of file diff --git a/tests/tf-manifests/rhcs/idps/htpasswd/variables.tf b/tests/tf-manifests/rhcs/idps/htpasswd/variables.tf index 6f7989a1..d539be76 100644 --- a/tests/tf-manifests/rhcs/idps/htpasswd/variables.tf +++ b/tests/tf-manifests/rhcs/idps/htpasswd/variables.tf @@ -17,11 +17,10 @@ variable "mapping_method" { type = string default = "claim" } -variable "username" { - type = string - default = null -} -variable "password" { - type = string - default = null +variable "htpasswd_users" { + type = list(object({ + username = string + password = string + })) + description = "htpasswd user list" } \ No newline at end of file diff --git a/tests/utils/constants/constants.go b/tests/utils/constants/constants.go index fa68d239..1bbf49b1 100644 --- a/tests/utils/constants/constants.go +++ b/tests/utils/constants/constants.go @@ -19,6 +19,7 @@ const ( var ( TokenENVName = "RHCS_TOKEN" + ClusterIDEnv = "CLUSTER_ID" OCMEnv = "OCM_ENV" RhcsClusterProfileENV = "RHCS_PROFILE_ENV" ClusterTypeManifestDirEnv = "CLUSTER_ROSA_TYPE" @@ -79,6 +80,16 @@ var ( OSDCCS = path.Join(ClusterDir, "osd-ccs") ) +// Dirs of identity providers +var ( + HtpasswdDir = path.Join(IDPsDir, "htpasswd") + GitlabDir = path.Join(IDPsDir, "gitlab") + GithubDir = path.Join(IDPsDir, "github") + LdapDir = path.Join(IDPsDir, "ldap") + OpenidDir = path.Join(IDPsDir, "openid") + GoogleDir = path.Join(IDPsDir, "google") +) + // Supports abs and relatives func GrantClusterManifestDir(manifestDir string) string { var targetDir string diff --git a/tests/utils/exec/idps.go b/tests/utils/exec/idps.go new file mode 100644 index 00000000..c6025418 --- /dev/null +++ b/tests/utils/exec/idps.go @@ -0,0 +1,97 @@ +package exec + +import ( + "context" + "fmt" + + CON "github.com/terraform-redhat/terraform-provider-rhcs/tests/utils/constants" + h "github.com/terraform-redhat/terraform-provider-rhcs/tests/utils/helper" +) + +type IDPArgs struct { + ClusterID string `json:"cluster_id,omitempty"` + Name string `json:"name,omitempty"` + ID string `json:"id,omitempty"` + Token string `json:"token,omitempty"` + OCMENV string `json:"ocm_environment,omitempty"` + URL string `json:"url,omitempty"` + MappingMethod string `json:"mapping_method,omitempty"` + HtpasswdUsers []interface{} `json:"htpasswd_users,omitempty"` +} + +type IDPService struct { + CreationArgs *IDPArgs + ManifestDir string + Context context.Context +} + +// for now holds only ID, additional vars might be needed in the future +type IDPOutput struct { + ID string `json:"idp_id,omitempty"` +} + +func (idp *IDPService) Init(manifestDirs ...string) error { + idp.ManifestDir = CON.IDPsDir + if len(manifestDirs) != 0 { + idp.ManifestDir = manifestDirs[0] + } + ctx := context.TODO() + idp.Context = ctx + err := runTerraformInit(ctx, idp.ManifestDir) + if err != nil { + return err + } + return nil +} + +func (idp *IDPService) Create(createArgs *IDPArgs, extraArgs ...string) error { + idp.CreationArgs = createArgs + args := combineStructArgs(createArgs, extraArgs...) + _, err := runTerraformApplyWithArgs(idp.Context, idp.ManifestDir, args) + if err != nil { + return err + } + return nil +} + +func (idp *IDPService) Output() (IDPOutput, error) { + idpDir := CON.IDPsDir + if idp.ManifestDir != "" { + idpDir = idp.ManifestDir + } + var output IDPOutput + out, err := runTerraformOutput(context.TODO(), idpDir) + if err != nil { + return output, err + } + if err != nil { + return output, err + } + id := h.DigString(out["idp_id"], "value") + + // right now only "holds" id, more vars might be needed in the future + output = IDPOutput{ + ID: id, + } + return output, nil +} + +func (idp *IDPService) Destroy(createArgs ...*IDPArgs) error { + if idp.CreationArgs == nil && len(createArgs) == 0 { + return fmt.Errorf("got unset destroy args, set it in object or pass as a parameter") + } + destroyArgs := idp.CreationArgs + if len(createArgs) != 0 { + destroyArgs = createArgs[0] + } + args := combineStructArgs(destroyArgs) + err := runTerraformDestroyWithArgs(idp.Context, idp.ManifestDir, args) + + return err +} + +func NewIDPService(manifestDir ...string) *IDPService { + idp := &IDPService{} + idp.Init(manifestDir...) + return idp +} diff --git a/tests/utils/exec/openshift.go b/tests/utils/exec/openshift.go new file mode 100644 index 00000000..e8d36e91 --- /dev/null +++ b/tests/utils/exec/openshift.go @@ -0,0 +1,57 @@ +package exec + +import ( + "fmt" + "strings" + "time" + + h "github.com/terraform-redhat/terraform-provider-rhcs/tests/utils/helper" +) + +type OcAttributes struct { + Server string + Username string + Password string + ClusterID string + AdditioanlFlags []string + Timeout time.Duration +} + +func GenerateOCLoginCMD(server string, username string, password string, clusterid string, additioanlFlags ...string) string { + cmd := fmt.Sprintf("oc login %s --username %s --password %s", + server, username, password) + if len(additioanlFlags) != 0 { + cmd = cmd + " " + strings.Join(additioanlFlags, " ") + } + return cmd +} + +func RetryCMDRun(cmd string, timeout time.Duration) (string, error) { + now := time.Now() + var stdout string + var stderr string + var err error + for time.Now().Before(now.Add(timeout * time.Minute)) { + stdout, stderr, err = h.RunCMD(cmd) + if err == nil { + return stdout, nil + } + err = fmt.Errorf(stdout + stderr) + time.Sleep(time.Minute) + } + return "", fmt.Errorf("timeout %d mins for command run %s with error: %s", timeout, cmd, err.Error()) +} + +func OcLogin(ocLoginAtter OcAttributes) error { + cmd := GenerateOCLoginCMD(ocLoginAtter.Server, + ocLoginAtter.Username, + ocLoginAtter.Password, + ocLoginAtter.ClusterID, + ocLoginAtter.AdditioanlFlags...) + + errMsg, errStatus := RetryCMDRun(cmd, ocLoginAtter.Timeout) + if errMsg != "" { + fmt.Errorf("timeout %d mins for command run %s with error: %s", ocLoginAtter.Timeout, cmd, errStatus.Error()) + } + return errStatus +}