From 205d0ec0a88ba105a99df24ac08ab2948d6681d6 Mon Sep 17 00:00:00 2001 From: ilia-medvedev-codefresh Date: Mon, 3 Jun 2024 14:01:22 +0300 Subject: [PATCH] Feat: Add gitops account settings resource and data source for configuring account level gitops settings (Git provider and ISC repo) (#147) --- codefresh/cfclient/current_account.go | 2 +- codefresh/cfclient/gitops_account_settings.go | 83 +++++++++++ codefresh/cfclient/pipeline.go | 16 +-- codefresh/cfclient/user.go | 6 +- codefresh/data_account_gitops_settings.go | 78 ++++++++++ codefresh/internal/gitops/account_settings.go | 36 +++++ codefresh/internal/gitops/doc.go | 2 + codefresh/provider.go | 26 ++-- codefresh/resource_account_gitops_settings.go | 133 ++++++++++++++++++ .../resource_account_gitops_settings_test.go | 100 +++++++++++++ codefresh/resource_pipeline.go | 56 ++++---- codefresh/resource_pipeline_test.go | 16 +-- codefresh/resource_user.go | 16 +-- docs/data-sources/account_gitops_settings.md | 27 ++++ docs/resources/account_gitops_settings.md | 51 +++++++ .../resources/account_gitops_settings.md.tmpl | 36 +++++ 16 files changed, 616 insertions(+), 68 deletions(-) create mode 100644 codefresh/cfclient/gitops_account_settings.go create mode 100644 codefresh/data_account_gitops_settings.go create mode 100644 codefresh/internal/gitops/account_settings.go create mode 100644 codefresh/internal/gitops/doc.go create mode 100644 codefresh/resource_account_gitops_settings.go create mode 100644 codefresh/resource_account_gitops_settings_test.go create mode 100644 docs/data-sources/account_gitops_settings.md create mode 100644 docs/resources/account_gitops_settings.md create mode 100644 templates/resources/account_gitops_settings.md.tmpl diff --git a/codefresh/cfclient/current_account.go b/codefresh/cfclient/current_account.go index ec57dbb..6e5f00a 100644 --- a/codefresh/cfclient/current_account.go +++ b/codefresh/cfclient/current_account.go @@ -60,7 +60,7 @@ func (client *Client) GetCurrentAccount() (*CurrentAccount, error) { currentAccount.ID = accX.Get("id").String() admins := accX.Get("admins").InterSlice() for _, adminI := range admins { - accountAdminsIDs = append(accountAdminsIDs ,adminI.(string)) + accountAdminsIDs = append(accountAdminsIDs, adminI.(string)) } break } diff --git a/codefresh/cfclient/gitops_account_settings.go b/codefresh/cfclient/gitops_account_settings.go new file mode 100644 index 0000000..810452f --- /dev/null +++ b/codefresh/cfclient/gitops_account_settings.go @@ -0,0 +1,83 @@ +package cfclient + +import ( + "fmt" +) + +type GitopsActiveAccountResponse struct { + Data struct { + Me struct { + ActiveAccount GitopsActiveAccountInfo `json:"activeAccount,omitempty"` + } `json:"me,omitempty"` + } `json:"data,omitempty"` +} + +type GitopsActiveAccountInfo struct { + ID string `json:"id,omitempty"` + AccountName string `json:"name,omitempty"` + GitProvider string `json:"gitProvider,omitempty"` + GitApiUrl string `json:"gitApiUrl,omitempty"` + SharedConfigRepo string `json:"sharedConfigRepo,omitempty"` + Admins []string `json:"admins,omitempty"` +} + +func (client *Client) GetActiveGitopsAccountInfo() (*GitopsActiveAccountInfo, error) { + request := GraphQLRequest{ + Query: ` + query AccountInfo { + me { + activeAccount { + id + name + gitProvider + gitApiUrl + sharedConfigRepo + admins + } + } + } + `, + } + + response, err := client.SendGqlRequest(request) + if err != nil { + fmt.Println("Error:", err) + return nil, err + } + + var gitopsAccountResponse GitopsActiveAccountResponse + + err = DecodeGraphQLResponseInto(response, &gitopsAccountResponse) + + if err != nil { + return nil, err + } + + gitopsActiveAccountInfo := gitopsAccountResponse.Data.Me.ActiveAccount + + return &gitopsActiveAccountInfo, nil +} + +func (client *Client) UpdateActiveGitopsAccountSettings(gitProvider string, gitProviderApiUrl string, sharedConfigRepo string) error { + request := GraphQLRequest{ + Query: ` + mutation updateCsdpSettings($gitProvider: GitProviders!, $gitApiUrl: String!, $sharedConfigRepo: String!) { + updateCsdpSettings(gitProvider: $gitProvider, gitApiUrl: $gitApiUrl, sharedConfigRepo: $sharedConfigRepo) + } + `, + Variables: map[string]interface{}{ + "gitProvider": gitProvider, + "gitApiUrl": gitProviderApiUrl, + "sharedConfigRepo": sharedConfigRepo, + }, + } + + _, err := client.SendGqlRequest(request) + + if err != nil { + fmt.Println("Error:", err) + return err + } + + return nil +} diff --git a/codefresh/cfclient/pipeline.go b/codefresh/cfclient/pipeline.go index c15bd69..dba6f11 100644 --- a/codefresh/cfclient/pipeline.go +++ b/codefresh/cfclient/pipeline.go @@ -91,14 +91,14 @@ type RuntimeEnvironment struct { } type ExternalResource struct { - ID string `json:"id,omitempty"` - Type string `json:"type"` - Source string `json:"source"` - Context string `json:"context"` + ID string `json:"id,omitempty"` + Type string `json:"type"` + Source string `json:"source"` + Context string `json:"context"` Destination string `json:"destination"` - IsFolder bool `json:"isFolder"` - Repo string `json:"repo"` - Revision string `json:"revision"` + IsFolder bool `json:"isFolder"` + Repo string `json:"repo"` + Revision string `json:"revision"` } func (t *Trigger) SetVariables(variables map[string]interface{}, encrypted bool) { @@ -134,7 +134,7 @@ type Spec struct { Hooks *Hooks `json:"hooks,omitempty"` Options map[string]bool `json:"options,omitempty"` PermitRestartFromFailedSteps bool `json:"permitRestartFromFailedSteps,omitempty"` - ExternalResources []ExternalResource `json:"externalResources,omitempty"` + ExternalResources []ExternalResource `json:"externalResources,omitempty"` } type Steps struct { diff --git a/codefresh/cfclient/user.go b/codefresh/cfclient/user.go index f4b4d36..37d4769 100644 --- a/codefresh/cfclient/user.go +++ b/codefresh/cfclient/user.go @@ -47,7 +47,7 @@ type User struct { HasPassword bool `json:"hasPassword,omitempty"` Notifications []NotificationEvent `json:"notifications,omitempty"` ShortProfile ShortProfile `json:"shortProfile,omitempty"` - PublicProfile PublicProfile `json:"publicProfile,omitempty"` + PublicProfile PublicProfile `json:"publicProfile,omitempty"` Logins []Login `json:"logins,omitempty"` InviteURL string `json:"inviteUrl,omitempty"` } @@ -389,7 +389,7 @@ func (client *Client) UpdateUserDetails(accountId, userId, userName, userEmail s return &respUser, nil } -func (client *Client) UpdateLocalUserPassword(userName, password string) (error) { +func (client *Client) UpdateLocalUserPassword(userName, password string) error { fullPath := "/admin/user/localProvider" @@ -410,7 +410,7 @@ func (client *Client) UpdateLocalUserPassword(userName, password string) (error) return nil } -func (client *Client) DeleteLocalUserPassword(userName string) (error) { +func (client *Client) DeleteLocalUserPassword(userName string) error { fullPath := fmt.Sprintf("/admin/user/localProvider?userName=%s", userName) diff --git a/codefresh/data_account_gitops_settings.go b/codefresh/data_account_gitops_settings.go new file mode 100644 index 0000000..4245a58 --- /dev/null +++ b/codefresh/data_account_gitops_settings.go @@ -0,0 +1,78 @@ +package codefresh + +import ( + "fmt" + + "github.com/codefresh-io/terraform-provider-codefresh/codefresh/cfclient" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceAccountGitopsSettings() *schema.Resource { + return &schema.Resource{ + Description: "This data source retrieves gitops settings for the active account", + Read: dataSourceAccountGitopsSettingsRead, + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Description: "Account Id", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Account name for active account", + }, + "git_provider": { + Type: schema.TypeString, + Computed: true, + Description: "Git provider name", + }, + "git_provider_api_url": { + Type: schema.TypeString, + Computed: true, + Description: "Git provider API url", + }, + "shared_config_repository": { + Type: schema.TypeString, + Computed: true, + Description: "Shared config repository url", + }, + "admins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + } +} + +func dataSourceAccountGitopsSettingsRead(d *schema.ResourceData, meta interface{}) error { + + client := meta.(*cfclient.Client) + var accountGitopsInfo *cfclient.GitopsActiveAccountInfo + + accountGitopsInfo, err := client.GetActiveGitopsAccountInfo() + + if err != nil { + return err + } + + return mapDataAccountGitopsSettingsToResource(accountGitopsInfo, d) +} + +func mapDataAccountGitopsSettingsToResource(account *cfclient.GitopsActiveAccountInfo, d *schema.ResourceData) error { + + if account == nil || account.ID == "" { + return fmt.Errorf("cannot get gitops settings as account wasn't properly retrived") + } + d.SetId(account.ID) + d.Set("name", account.AccountName) + d.Set("admins", account.Admins) + d.Set("git_provider", account.GitProvider) + d.Set("git_provider_api_url", account.GitApiUrl) + d.Set("shared_config_repository", account.SharedConfigRepo) + + return nil +} diff --git a/codefresh/internal/gitops/account_settings.go b/codefresh/internal/gitops/account_settings.go new file mode 100644 index 0000000..10afbe3 --- /dev/null +++ b/codefresh/internal/gitops/account_settings.go @@ -0,0 +1,36 @@ +package gitops + +import ( + "fmt" +) + +const ( + // Git providers enum from https://github.com/codefresh-io/argo-platform/blob/90f86de326422ca3bd1f64ca5dd26aeedf985e3e/libs/ql/schema/entities/common/integration.graphql#L200 + GitProviderGitHub string = "GITHUB" + GitProviderGerrit string = "GERRIT" + GitProviderGitlab string = "GITLAB" + GitProviderBitbucket string = "BITBUCKET" + GitProviderBitbucketServer string = "BITBUCKET_SERVER" +) + +func GetSupportedGitProvidersList() []string { + return []string{GitProviderGitHub, GitProviderGerrit, GitProviderGitlab, GitProviderBitbucket, GitProviderBitbucketServer} +} + +// Matching implementation for https://github.com/codefresh-io/argo-platform/blob/3c6af5b5cbb29aef58ef6617e71159e882987f5c/libs/git/src/helpers.ts#L37. +// Must be updated accordingly +func GetDefaultAPIUrlForProvider(gitProvider string) (*string, error) { + + defaultApiUrlProvider := map[string]string{ + GitProviderGitHub: "https://api.github.com", + GitProviderGitlab: "https://gitlab.com/api/v4", + GitProviderBitbucket: "https://api.bitbucket.org/2.0", + GitProviderGerrit: "https://gerrit-review.googlesource.com/a", + } + + if val, ok := defaultApiUrlProvider[gitProvider]; ok { + return &val, nil + } + + return nil, fmt.Errorf("no default API URL for provider %s can be found. For self hosted git providers URL must be provided explicitly", gitProvider) +} diff --git a/codefresh/internal/gitops/doc.go b/codefresh/internal/gitops/doc.go new file mode 100644 index 0000000..ba70d26 --- /dev/null +++ b/codefresh/internal/gitops/doc.go @@ -0,0 +1,2 @@ +// Shared types, schemas and functions for gitops +package gitops diff --git a/codefresh/provider.go b/codefresh/provider.go index 2f77def..ad08cfc 100644 --- a/codefresh/provider.go +++ b/codefresh/provider.go @@ -41,18 +41,19 @@ func Provider() *schema.Provider { }, }, DataSourcesMap: map[string]*schema.Resource{ - "codefresh_account": dataSourceAccount(), - "codefresh_context": dataSourceContext(), - "codefresh_current_account": dataSourceCurrentAccount(), - "codefresh_idps": dataSourceIdps(), - "codefresh_step_types": dataSourceStepTypes(), - "codefresh_team": dataSourceTeam(), - "codefresh_user": dataSourceUser(), - "codefresh_users": dataSourceUsers(), - "codefresh_registry": dataSourceRegistry(), - "codefresh_pipelines": dataSourcePipelines(), - "codefresh_account_idp": dataSourceAccountIdp(), - "codefresh_project": dataSourceProject(), + "codefresh_account": dataSourceAccount(), + "codefresh_context": dataSourceContext(), + "codefresh_current_account": dataSourceCurrentAccount(), + "codefresh_idps": dataSourceIdps(), + "codefresh_step_types": dataSourceStepTypes(), + "codefresh_team": dataSourceTeam(), + "codefresh_user": dataSourceUser(), + "codefresh_users": dataSourceUsers(), + "codefresh_registry": dataSourceRegistry(), + "codefresh_pipelines": dataSourcePipelines(), + "codefresh_account_idp": dataSourceAccountIdp(), + "codefresh_project": dataSourceProject(), + "codefresh_account_gitops_settings": dataSourceAccountGitopsSettings(), }, ResourcesMap: map[string]*schema.Resource{ "codefresh_account": resourceAccount(), @@ -72,6 +73,7 @@ func Provider() *schema.Provider { "codefresh_abac_rules": resourceGitopsAbacRule(), "codefresh_idp": resourceIdp(), "codefresh_account_idp": resourceAccountIdp(), + "codefresh_account_gitops_settings": resourceAccountGitopsSettings(), }, ConfigureFunc: configureProvider, } diff --git a/codefresh/resource_account_gitops_settings.go b/codefresh/resource_account_gitops_settings.go new file mode 100644 index 0000000..81dd852 --- /dev/null +++ b/codefresh/resource_account_gitops_settings.go @@ -0,0 +1,133 @@ +package codefresh + +import ( + "fmt" + "regexp" + "strings" + + "github.com/codefresh-io/terraform-provider-codefresh/codefresh/cfclient" + "github.com/codefresh-io/terraform-provider-codefresh/codefresh/internal/gitops" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceAccountGitopsSettings() *schema.Resource { + return &schema.Resource{ + Description: "Codefresh account gitops setting - such as git provider, API URL for the git provider and internal shared config repository", + Read: resourceAccountGitopsSettingsRead, + Create: resourceAccountGitopsSettingsUpdate, + Update: resourceAccountGitopsSettingsUpdate, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + // Delete not implemenented as gitops settings cannot be removed, only updated + Delete: resourceAccountGitopsSettingsDelete, + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Description: "Account Id", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Account name for active account", + Computed: true, + }, + "git_provider": { + Type: schema.TypeString, + Description: fmt.Sprintf("Git provider name - currently supported values are: %s", strings.Join(gitops.GetSupportedGitProvidersList(), " ,")), + Required: true, + ValidateFunc: validation.StringInSlice(gitops.GetSupportedGitProvidersList(), false), + }, + "git_provider_api_url": { + Type: schema.TypeString, + Description: "Git provider API url. If not provided can automatically be set for known SaaS git providers. For example - for github it will be set to https://api.github.com", + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^(https?:\/\/)(\S+)$`), "must be a valid url"), + Optional: true, + // When an empty value for provider url is provided, check if the old one was set by getting the default and surpress diff in such case + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if new == "" { + defaultProviderUrl, err := gitops.GetDefaultAPIUrlForProvider(d.Get("git_provider").(string)) + + if err != nil { + return false + } + + if *defaultProviderUrl == old { + return true + } + } + return false + }, + }, + "shared_config_repository": { + Type: schema.TypeString, + Description: "Shared config repository url. Must be a valid git url which contains `.git`. May also include path and branch references", + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^(https?:\/\/)(\S+)(.git)(\S*)$`), "must be a valid git url and must contain .git For example https://github.com/owner/repo.git or https://github.com/owner/repo.git/some/path?ref=branch-name"), + Required: true, + }, + }, + } +} + +func resourceAccountGitopsSettingsRead(d *schema.ResourceData, meta interface{}) error { + + client := meta.(*cfclient.Client) + var accountGitopsInfo *cfclient.GitopsActiveAccountInfo + + accountGitopsInfo, err := client.GetActiveGitopsAccountInfo() + + if err != nil { + return err + } + + return mapAccountGitopsSettingsToResource(accountGitopsInfo, d) +} + +func resourceAccountGitopsSettingsUpdate(d *schema.ResourceData, meta interface{}) error { + + client := meta.(*cfclient.Client) + + var gitApiUrl string + + if _, ok := d.GetOk("git_provider_api_url"); !ok { + url, err := gitops.GetDefaultAPIUrlForProvider(d.Get("git_provider").(string)) + + if err != nil { + return err + } + + gitApiUrl = *url + + } else { + gitApiUrl = d.Get("git_provider_api_url").(string) + } + + err := client.UpdateActiveGitopsAccountSettings(d.Get("git_provider").(string), gitApiUrl, d.Get("shared_config_repository").(string)) + + if err != nil { + return err + } + + return resourceAccountGitopsSettingsRead(d, meta) +} + +// Settings cannot be deleted, only updated +func resourceAccountGitopsSettingsDelete(d *schema.ResourceData, meta interface{}) error { + return nil +} + +func mapAccountGitopsSettingsToResource(account *cfclient.GitopsActiveAccountInfo, d *schema.ResourceData) error { + + if account == nil || account.ID == "" { + return fmt.Errorf("cannot get gitops settings as account wasn't properly retrived") + } + + d.SetId(account.ID) + d.Set("name", account.AccountName) + d.Set("git_provider", account.GitProvider) + d.Set("git_provider_api_url", account.GitApiUrl) + d.Set("shared_config_repository", account.SharedConfigRepo) + + return nil +} diff --git a/codefresh/resource_account_gitops_settings_test.go b/codefresh/resource_account_gitops_settings_test.go new file mode 100644 index 0000000..5a615e7 --- /dev/null +++ b/codefresh/resource_account_gitops_settings_test.go @@ -0,0 +1,100 @@ +package codefresh + +import ( + "fmt" + "testing" + + "github.com/codefresh-io/terraform-provider-codefresh/codefresh/cfclient" + "github.com/codefresh-io/terraform-provider-codefresh/codefresh/internal/gitops" + + //"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccCodefreshAccountGitopsSettings_basic(t *testing.T) { + resourceName := "codefresh_account_gitops_settings.test" + + expectedDefaultApiURLGithub, _ := gitops.GetDefaultAPIUrlForProvider(gitops.GitProviderGitHub) + //expectedDefaultApiURLGithub := "https://bnlah.com" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + //CheckDestroy: testAccCheckCodefreshProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccountGitopsSettingsGithubDefaultApiUrl("https://github.com/codefresh-io/terraform-provider-isc-test.git"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGitopsSettings(resourceName, gitops.GitProviderGitHub, *expectedDefaultApiURLGithub, "https://github.com/codefresh-io/terraform-provider-isc-test.git"), + resource.TestCheckResourceAttr(resourceName, "git_provider", gitops.GitProviderGitHub), + ), + }, + { + Config: testAccountGitopsSettingsGithubExplicitApiUrl("https://github.com/codefresh-io/terraform-provider-isc-test.git", "https://api.mygithub.com"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGitopsSettings(resourceName, gitops.GitProviderGitHub, "https://api.mygithub.com", "https://github.com/codefresh-io/terraform-provider-isc-test.git"), + resource.TestCheckResourceAttr(resourceName, "git_provider", gitops.GitProviderGitHub), + resource.TestCheckResourceAttr(resourceName, "git_provider_api_url", "https://api.mygithub.com"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckGitopsSettings(resource string, gitProvider string, gitProviderApiUrl string, sharedConfigRepository string) resource.TestCheckFunc { + return func(state *terraform.State) error { + rs, ok := state.RootModule().Resources[resource] + if !ok { + return fmt.Errorf("Not found: %s", resource) + } + if rs.Primary.ID == "" { + return fmt.Errorf("No Record ID is set") + } + + apiClient := testAccProvider.Meta().(*cfclient.Client) + + accGitopsInfo, err := apiClient.GetActiveGitopsAccountInfo() + + if err != nil { + return fmt.Errorf("failed getting gitops settings with error %s", err) + } + + if accGitopsInfo.GitApiUrl != gitProviderApiUrl { + return fmt.Errorf("expecting APIUrl to be %s but got %s", gitProviderApiUrl, accGitopsInfo.GitApiUrl) + } + + if accGitopsInfo.GitProvider != gitProvider { + return fmt.Errorf("expecting provider to be %s but got %s", gitProvider, accGitopsInfo.GitProvider) + } + + if accGitopsInfo.SharedConfigRepo != sharedConfigRepository { + return fmt.Errorf("expecting shared config repository to be %s but got %s", sharedConfigRepository, accGitopsInfo.SharedConfigRepo) + } + + return nil + } +} + +// CONFIGS +func testAccountGitopsSettingsGithubDefaultApiUrl(sharedConfigRepository string) string { + return fmt.Sprintf(` + resource "codefresh_account_gitops_settings" "test" { + git_provider = "GITHUB" + shared_config_repository = "%s" + }`, sharedConfigRepository) +} + +func testAccountGitopsSettingsGithubExplicitApiUrl(sharedConfigRepository string, gitProviderApiUrl string) string { + return fmt.Sprintf(` + resource "codefresh_account_gitops_settings" "test" { + git_provider = "GITHUB" + shared_config_repository = "%s" + git_provider_api_url = "%s" + }`, sharedConfigRepository, gitProviderApiUrl) +} diff --git a/codefresh/resource_pipeline.go b/codefresh/resource_pipeline.go index 35adc3b..92c2b5b 100644 --- a/codefresh/resource_pipeline.go +++ b/codefresh/resource_pipeline.go @@ -642,53 +642,53 @@ Pipeline concurrency policy: Builds on 'Pending Approval' state should be: }, }, "external_resource": { - Type: schema.TypeList, + Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "id" : { - Type: schema.TypeString, + "id": { + Type: schema.TypeString, Computed: true, }, - "type" : { - Type: schema.TypeString, - Optional: true, + "type": { + Type: schema.TypeString, + Optional: true, Description: "Type of the external resource. Currently only 'git' is supported", ValidateFunc: validation.StringInSlice([]string{ "git", }, false), Default: "git", }, - "repo" : { - Type: schema.TypeString, - Required: true, + "repo": { + Type: schema.TypeString, + Required: true, Description: "git repository url", }, - "context" : { - Type: schema.TypeString, - Required: true, + "context": { + Type: schema.TypeString, + Required: true, Description: "Context name for the git repository", }, "revision": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, Description: "Revision/branch in the git repository", }, "is_folder": { - Type: schema.TypeBool, + Type: schema.TypeBool, Description: "Whether or not the resource specified in source_path is a folder", - Optional: true, - Default: false, + Optional: true, + Default: false, }, "source_path": { - Type: schema.TypeString, + Type: schema.TypeString, Description: "The source folder in the repository (use relative path)", - Required: true, + Required: true, }, "target_path": { - Type: schema.TypeString, + Type: schema.TypeString, Description: "The target folder in the pipeline workspace where the file/folder will be copied to (use absolute path)", - Required: true, + Required: true, }, }, }, @@ -1224,14 +1224,14 @@ func mapResourceToPipeline(d *schema.ResourceData) (*cfclient.Pipeline, error) { if externalResources, ok := d.GetOk("spec.0.external_resource"); ok { for idx := range externalResources.([]interface{}) { codefreshExternalResource := cfclient.ExternalResource{ - Type: d.Get(fmt.Sprintf("spec.0.external_resource.%v.type", idx)).(string), - Repo: d.Get(fmt.Sprintf("spec.0.external_resource.%v.repo", idx)).(string), - Revision: d.Get(fmt.Sprintf("spec.0.external_resource.%v.revision", idx)).(string), - Context: d.Get(fmt.Sprintf("spec.0.external_resource.%v.context", idx)).(string), - Source: d.Get(fmt.Sprintf("spec.0.external_resource.%v.source_path", idx)).(string), + Type: d.Get(fmt.Sprintf("spec.0.external_resource.%v.type", idx)).(string), + Repo: d.Get(fmt.Sprintf("spec.0.external_resource.%v.repo", idx)).(string), + Revision: d.Get(fmt.Sprintf("spec.0.external_resource.%v.revision", idx)).(string), + Context: d.Get(fmt.Sprintf("spec.0.external_resource.%v.context", idx)).(string), + Source: d.Get(fmt.Sprintf("spec.0.external_resource.%v.source_path", idx)).(string), Destination: d.Get(fmt.Sprintf("spec.0.external_resource.%v.target_path", idx)).(string), - IsFolder: d.Get(fmt.Sprintf("spec.0.external_resource.%v.is_folder", idx)).(bool), - ID: d.Get(fmt.Sprintf("spec.0.external_resource.%v.id", idx)).(string), + IsFolder: d.Get(fmt.Sprintf("spec.0.external_resource.%v.is_folder", idx)).(bool), + ID: d.Get(fmt.Sprintf("spec.0.external_resource.%v.id", idx)).(string), } pipeline.Spec.ExternalResources = append(pipeline.Spec.ExternalResources, codefreshExternalResource) diff --git a/codefresh/resource_pipeline_test.go b/codefresh/resource_pipeline_test.go index 8e52d61..9a6388a 100644 --- a/codefresh/resource_pipeline_test.go +++ b/codefresh/resource_pipeline_test.go @@ -711,9 +711,9 @@ func TestAccCodefreshPipeline_ExternalResources(t *testing.T) { CheckDestroy: testAccCheckCodefreshPipelineDestroy, Steps: []resource.TestStep{ { - Config: testAccCodefreshPipelineExternalResources(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", - "github", "codefresh-io/external-resources1", "master", "test.py", "/codefresh/volume/test.py", - "github2", "codefresh-io/external-resources2", "main", "test2.py", "/codefresh/volume/test2.py"), + Config: testAccCodefreshPipelineExternalResources(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", + "github", "codefresh-io/external-resources1", "master", "test.py", "/codefresh/volume/test.py", + "github2", "codefresh-io/external-resources2", "main", "test2.py", "/codefresh/volume/test2.py"), Check: resource.ComposeTestCheckFunc( testAccCheckCodefreshPipelineExists(resourceName, &pipeline), resource.TestCheckResourceAttr(resourceName, "spec.0.external_resource.0.context", "github"), @@ -735,8 +735,8 @@ func TestAccCodefreshPipeline_ExternalResources(t *testing.T) { }, { Config: testAccCodefreshPipelineExternalResources(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", - "github2", "codefresh-io/external-resources2", "main", "test2.py", "/codefresh/volume/test2.py", - "github", "codefresh-io/external-resources1", "master", "test.py", "/codefresh/volume/test.py"), + "github2", "codefresh-io/external-resources2", "main", "test2.py", "/codefresh/volume/test2.py", + "github", "codefresh-io/external-resources1", "master", "test.py", "/codefresh/volume/test.py"), Check: resource.ComposeTestCheckFunc( testAccCheckCodefreshPipelineExists(resourceName, &pipeline), resource.TestCheckResourceAttr(resourceName, "spec.0.external_resource.1.context", "github"), @@ -1571,7 +1571,7 @@ resource "codefresh_pipeline" "test" { } } `, -rName, repo, path, revision, context, -extResource1Context, extResource1Repo ,extResource1Revision, extResourse1SourcePath, extResource1DestPath, -extResource2Context, extResource2Repo ,extResource2Revision, extResourse2SourcePath, extResource2DestPath) + rName, repo, path, revision, context, + extResource1Context, extResource1Repo, extResource1Revision, extResourse1SourcePath, extResource1DestPath, + extResource2Context, extResource2Repo, extResource2Revision, extResourse2SourcePath, extResource2DestPath) } diff --git a/codefresh/resource_user.go b/codefresh/resource_user.go index df8a113..c73ecf0 100644 --- a/codefresh/resource_user.go +++ b/codefresh/resource_user.go @@ -27,14 +27,14 @@ func resourceUser() *schema.Resource { }, "password": { Description: "Password - for users without SSO.", - Type: schema.TypeString, - Optional: true, - Sensitive: true, + Type: schema.TypeString, + Optional: true, + Sensitive: true, }, - "has_password" : { + "has_password": { Description: "Whether the user has a local password.", - Type: schema.TypeBool, - Computed: true, + Type: schema.TypeBool, + Computed: true, }, "email": { Description: "The email of the user.", @@ -353,7 +353,7 @@ func mapResourceToNewUser(d *schema.ResourceData) *cfclient.NewUser { func updateUserLocalPassword(d *schema.ResourceData, client *cfclient.Client) error { - if (d.HasChange("password")) { + if d.HasChange("password") { hasPassword := d.Get("has_password").(bool) if _, ok := d.GetOk("user_name"); !ok { @@ -368,7 +368,7 @@ func updateUserLocalPassword(d *schema.ResourceData, client *cfclient.Client) er if err != nil { return err } - // If password is not set but has_password returns true, it means that it was removed + // If password is not set but has_password returns true, it means that it was removed } else if hasPassword { err := client.DeleteLocalUserPassword(userName) diff --git a/docs/data-sources/account_gitops_settings.md b/docs/data-sources/account_gitops_settings.md new file mode 100644 index 0000000..a0890b7 --- /dev/null +++ b/docs/data-sources/account_gitops_settings.md @@ -0,0 +1,27 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "codefresh_account_gitops_settings Data Source - terraform-provider-codefresh" +subcategory: "" +description: |- + This data source retrieves gitops settings for the active account +--- + +# codefresh_account_gitops_settings (Data Source) + +This data source retrieves gitops settings for the active account + + + + +## Schema + +### Read-Only + +- `admins` (List of String) +- `git_provider` (String) Git provider name +- `git_provider_api_url` (String) Git provider API url +- `id` (String) Account Id +- `name` (String) Account name for active account +- `shared_config_repository` (String) Shared config repository url + + diff --git a/docs/resources/account_gitops_settings.md b/docs/resources/account_gitops_settings.md new file mode 100644 index 0000000..b8be9f7 --- /dev/null +++ b/docs/resources/account_gitops_settings.md @@ -0,0 +1,51 @@ +--- +page_title: "codefresh_account_gitops_settings Resource - terraform-provider-codefresh" +subcategory: "" +description: |- + Codefresh account gitops setting - such as git provider, API URL for the git provider and internal shared config repository +--- + +# codefresh_account_gitops_settings (Resource) + +Codefresh account gitops setting - such as git provider, API URL for the git provider and internal shared config repository + +## Example usage +```hcl +resource "codefresh_account_gitops_settings" "gitops-settings" { + git_provider = "GITHUB" + shared_config_repository = "https://github.com/example-org/codefresh-internal-shared-config.git?ref=main" +} +``` +```hcl +resource "codefresh_account_gitops_settings" "gitops-settings" { + git_provider = "BITBUCKET_SERVER" + git_provider_api_url = https://bitbucket.example.com/rest/api/1.0 + shared_config_repository = "http://example-bitbucket.com/scm/proj/codefresh-internal-shared-config.git" +} +``` + + +## Schema + +### Required + +- `git_provider` (String) Git provider name - currently supported values are: GITHUB ,GERRIT ,GITLAB ,BITBUCKET ,BITBUCKET_SERVER +- `shared_config_repository` (String) Shared config repository url. Must be a valid git url which contains `.git`. May also include path and branch references + +### Optional + +- `git_provider_api_url` (String) Git provider API url. If not provided can automatically be set for known SaaS git providers. For example - for github it will be set to https://api.github.com + +### Read-Only + +- `id` (String) Account Id +- `name` (String) Account name for active account + +[!WARNING] +Once internal config repository is cloned successfully by one or more runtimes it can no longer be changed and all attempted updates will fail. +If you need to change the repository please contact Codefresh support. + +## Import +```sh +terraform import codefresh_account_idp.test +``` diff --git a/templates/resources/account_gitops_settings.md.tmpl b/templates/resources/account_gitops_settings.md.tmpl new file mode 100644 index 0000000..1966bbf --- /dev/null +++ b/templates/resources/account_gitops_settings.md.tmpl @@ -0,0 +1,36 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example usage +```hcl +resource "codefresh_account_gitops_settings" "gitops-settings" { + git_provider = "GITHUB" + shared_config_repository = "https://github.com/example-org/codefresh-internal-shared-config.git?ref=main" +} +``` +```hcl +resource "codefresh_account_gitops_settings" "gitops-settings" { + git_provider = "BITBUCKET_SERVER" + git_provider_api_url = https://bitbucket.example.com/rest/api/1.0 + shared_config_repository = "http://example-bitbucket.com/scm/proj/codefresh-internal-shared-config.git" +} +``` + +{{ .SchemaMarkdown | trimspace }} + +[!WARNING] +Once internal config repository is cloned successfully by one or more runtimes it can no longer be changed and all attempted updates will fail. +If you need to change the repository please contact Codefresh support. + +## Import +```sh +terraform import codefresh_account_idp.test +```