From 7eaf52036b74bb5e6add76a86a8c8e0d0a1d5f47 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Sun, 26 May 2024 13:55:06 +0300 Subject: [PATCH 01/11] add gitops account settings data source --- codefresh/cfclient/current_account.go | 2 +- codefresh/cfclient/gitops_account_settings.go | 59 ++ codefresh/cfclient/pipeline.go | 16 +- codefresh/cfclient/user.go | 6 +- codefresh/data_account_gitops_settings.go | 74 +++ codefresh/internal/idp copy/doc.go | 2 + codefresh/internal/idp copy/schema.go | 504 ++++++++++++++++++ codefresh/internal/idp copy/types.go | 15 + codefresh/provider.go | 25 +- codefresh/resource_pipeline.go | 56 +- codefresh/resource_pipeline_test.go | 16 +- codefresh/resource_user.go | 16 +- 12 files changed, 723 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/idp copy/doc.go create mode 100644 codefresh/internal/idp copy/schema.go create mode 100644 codefresh/internal/idp copy/types.go diff --git a/codefresh/cfclient/current_account.go b/codefresh/cfclient/current_account.go index ec57dbb5..6e5f00a0 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 00000000..850c96aa --- /dev/null +++ b/codefresh/cfclient/gitops_account_settings.go @@ -0,0 +1,59 @@ +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 +} diff --git a/codefresh/cfclient/pipeline.go b/codefresh/cfclient/pipeline.go index c15bd692..dba6f11e 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 0a3c5936..2ce09e61 100644 --- a/codefresh/cfclient/user.go +++ b/codefresh/cfclient/user.go @@ -48,7 +48,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"` } @@ -374,7 +374,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" @@ -395,7 +395,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 00000000..d1b26104 --- /dev/null +++ b/codefresh/data_account_gitops_settings.go @@ -0,0 +1,74 @@ +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, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "git_provider": { + Type: schema.TypeString, + Computed: true, + }, + "git_provider_api_url": { + Type: schema.TypeString, + Computed: true, + }, + "shared_config_repo": { + Type: schema.TypeString, + Computed: true, + }, + "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("data.codefresh_account - failed to mapDataAccountToResource") + } + d.SetId(account.ID) + d.Set("_id", 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_repo", account.SharedConfigRepo) + + return nil +} diff --git a/codefresh/internal/idp copy/doc.go b/codefresh/internal/idp copy/doc.go new file mode 100644 index 00000000..fe3c330b --- /dev/null +++ b/codefresh/internal/idp copy/doc.go @@ -0,0 +1,2 @@ +// Package idp is shared by idp-related resources. +package idp diff --git a/codefresh/internal/idp copy/schema.go b/codefresh/internal/idp copy/schema.go new file mode 100644 index 00000000..5851b984 --- /dev/null +++ b/codefresh/internal/idp copy/schema.go @@ -0,0 +1,504 @@ +package idp + +import ( + "regexp" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +var ( + SupportedIdps = []string{GitHub, GitLab, Okta, Google, Auth0, Azure, OneLogin, Keycloak, SAML, LDAP} + IdpSchema = map[string]*schema.Schema{ + "display_name": { + Description: "The display name for the IDP.", + Type: schema.TypeString, + Required: true, + }, + "name": { + Description: "Name of the IDP, will be generated if not set", + Type: schema.TypeString, + Computed: true, + Optional: true, + }, + "client_type": { + Description: "Type of the IDP. Derived from idp specific config object (github, gitlab etc)", + Type: schema.TypeString, + Computed: true, + ForceNew: true, + }, + "redirect_url": { + Description: "API Callback url for the identity provider", + Type: schema.TypeString, + Computed: true, + }, + "redirect_ui_url": { + Description: "UI Callback url for the identity provider", + Type: schema.TypeString, + Computed: true, + }, + "login_url": { + Description: "Login url using the IDP to Codefresh", + Type: schema.TypeString, + Computed: true, + }, + "github": { + Description: "Settings for GitHub IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Description: "Client ID from Github", + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Description: "Client secret from GitHub", + Required: true, + Sensitive: true, + }, + "authentication_url": { + Type: schema.TypeString, + Description: "Authentication url, Defaults to https://github.com/login/oauth/authorize", + Optional: true, + Default: "https://github.com/login/oauth/authorize", + }, + "token_url": { + Type: schema.TypeString, + Description: "GitHub token endpoint url, Defaults to https://github.com/login/oauth/access_token", + Optional: true, + Default: "https://github.com/login/oauth/access_token", + }, + "user_profile_url": { + Type: schema.TypeString, + Description: "GitHub user profile url, Defaults to https://api.github.com/user", + Optional: true, + Default: "https://api.github.com/user", + }, + "api_host": { + Type: schema.TypeString, + Description: "GitHub API host, Defaults to api.github.com", + Optional: true, + Default: "api.github.com", + }, + "api_path_prefix": { + Type: schema.TypeString, + Description: "GitHub API url path prefix, defaults to /", + Optional: true, + Default: "/", + }, + }, + }, + }, + "gitlab": { + Description: "Settings for GitLab IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Description: "Client ID from Gitlab", + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Description: "Client secret from Gitlab", + Required: true, + Sensitive: true, + }, + "authentication_url": { + Type: schema.TypeString, + Description: "Authentication url, Defaults to https://gitlab.com", + Optional: true, + Default: "https://gitlab.com", + }, + "user_profile_url": { + Type: schema.TypeString, + Description: "User profile url, Defaults to https://gitlab.com/api/v4/user", + Optional: true, + Default: "https://gitlab.com/api/v4/user", + }, + "api_url": { + Type: schema.TypeString, + Description: "Base url for Gitlab API, Defaults to https://gitlab.com/api/v4/", + Optional: true, + Default: "https://gitlab.com/api/v4/", + }, + }, + }, + }, + "okta": { + Description: "Settings for Okta IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Description: "Client ID in Okta, must be unique across all identity providers in Codefresh", + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Description: "Client secret in Okta", + Required: true, + Sensitive: true, + }, + "client_host": { + Type: schema.TypeString, + Description: "The OKTA organization URL, for example, https://.okta.com", + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^(https?:\/\/)(\S+)(\.okta(preview|-emea)?\.com$)`), "must be a valid okta url"), + Required: true, + }, + "app_id": { + Type: schema.TypeString, + Description: "The Codefresh application ID in your OKTA organization", + Optional: true, + }, + "sync_mirror_accounts": { + Type: schema.TypeList, + Description: "The names of the additional Codefresh accounts to be synced from Okta", + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "access_token": { + Type: schema.TypeString, + Description: "The Okta API token generated in Okta, used to sync groups and their users from Okta to Codefresh", + Optional: true, + }, + }, + }, + }, + "google": { + Description: "Settings for Google IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Description: "Client ID in Google, must be unique across all identity providers in Codefresh", + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Description: "Client secret in Google", + Required: true, + Sensitive: true, + }, + "admin_email": { + Type: schema.TypeString, + Description: "Email of a user with admin permissions on google, relevant only for synchronization", + Optional: true, + }, + "json_keyfile": { + Type: schema.TypeString, + Description: "JSON keyfile for google service account used for synchronization", + Optional: true, + }, + "allowed_groups_for_sync": { + Type: schema.TypeString, + Description: "Comma separated list of groups to sync", + Optional: true, + }, + "sync_field": { + Type: schema.TypeString, + Description: "Relevant for custom schema-based synchronization only. See Codefresh documentation", + Optional: true, + }, + }, + }, + }, + "auth0": { + Description: "Settings for Auth0 IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Description: "Client ID from Auth0", + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Description: "Client secret from Auth0", + Required: true, + Sensitive: true, + }, + "domain": { + Type: schema.TypeString, + Description: "The domain of the Auth0 application", + Required: true, + }, + }, + }, + }, + "azure": { + Description: "Settings for Azure IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_secret": { + Type: schema.TypeString, + Description: "Client secret from Azure", + Required: true, + Sensitive: true, + }, + "app_id": { + Type: schema.TypeString, + Description: "The Application ID from your Enterprise Application Properties in Azure AD", + Required: true, + }, + "tenant": { + Type: schema.TypeString, + Description: "Azure tenant", + Optional: true, + }, + "object_id": { + Type: schema.TypeString, + Description: "The Object ID from your Enterprise Application Properties in Azure AD", + Optional: true, + }, + "autosync_teams_and_users": { + Type: schema.TypeBool, + Description: "Set to true to sync user accounts in Azure AD to your Codefresh account", + Optional: true, + Default: false, + }, + "sync_interval": { + Type: schema.TypeInt, + Description: "Sync interval in hours for syncing user accounts in Azure AD to your Codefresh account. If not set the sync inteval will be 12 hours", + Optional: true, + }, + }, + }, + }, + "onelogin": { + Description: "Settings for onelogin IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Description: "Client ID from Onelogin", + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Description: "Client secret from Onelogin", + Required: true, + Sensitive: true, + }, + "domain": { + Type: schema.TypeString, + Description: "The domain to be used for authentication", + Required: true, + }, + "app_id": { + Type: schema.TypeString, + Description: "The Codefresh application ID in your Onelogin", + Optional: true, + }, + "api_client_id": { + Type: schema.TypeString, + Description: "Client ID for onelogin API, only needed if syncing users and groups from Onelogin", + Optional: true, + }, + "api_client_secret": { + Type: schema.TypeString, + Description: "Client secret for onelogin API, only needed if syncing users and groups from Onelogin", + Optional: true, + // When onelogin IDP is created on account level, after the first apply the client secret is returned obfuscated + // DiffSuppressFunc: surpressObfuscatedFields(), + }, + }, + }, + }, + "keycloak": { + Description: "Settings for Keycloak IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Description: "Client ID from Keycloak", + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Description: "Client secret from Keycloak", + Required: true, + Sensitive: true, + }, + "host": { + Type: schema.TypeString, + Description: "The Keycloak URL", + Required: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^(https?:\/\/)(\S+)$`), "must be a valid url"), + }, + "realm": { + Type: schema.TypeString, + Description: "The Realm ID for Codefresh in Keycloak. Defaults to master", + Optional: true, + Default: "master", + }, + }, + }, + }, + "saml": { + Description: "Settings for SAML IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "endpoint": { + Type: schema.TypeString, + Description: "The SSO endpoint of your Identity Provider", + Required: true, + }, + "application_certificate": { + Type: schema.TypeString, + Description: "The security certificate of your Identity Provider. Paste the value directly on the field. Do not convert to base64 or any other encoding by hand", + Required: true, + Sensitive: true, + }, + "provider": { + Type: schema.TypeString, + Description: "SAML provider. Currently supported values - GSuite, okta or empty string for generic provider. Defaults to empty string", + Optional: true, + Default: "", + ValidateFunc: validation.StringInSlice([]string{"", "okta", "GSuite"}, false), + }, + "allowed_groups_for_sync": { + Type: schema.TypeString, + Description: "Valid for GSuite only: Comma separated list of groups to sync", + Optional: true, + }, + "autosync_teams_and_users": { + Type: schema.TypeBool, + Description: "Valid for Okta/GSuite: Set to true to sync user accounts and teams in okta/gsuite to your Codefresh account", + Optional: true, + Default: false, + }, + "sync_interval": { + Type: schema.TypeInt, + Description: "Valid for Okta/GSuite: Sync interval in hours for syncing user accounts in okta/gsuite to your Codefresh account. If not set the sync inteval will be 12 hours", + Optional: true, + }, + "activate_users_after_sync": { + Type: schema.TypeBool, + Description: "Valid for Okta only: If set to true, Codefresh will automatically invite and activate new users added during the automated sync, without waiting for the users to accept the invitations. Defaults to false", + Optional: true, + Default: false, + }, + "app_id": { + Type: schema.TypeString, + Description: "Valid for Okta only: The Codefresh application ID in Okta", + Optional: true, + }, + "client_host": { + Type: schema.TypeString, + Description: "Valid for Okta only: OKTA organization URL, for example, https://.okta.com", + Optional: true, + }, + "json_keyfile": { + Type: schema.TypeString, + Description: "Valid for GSuite only: JSON keyfile for google service account used for synchronization", + Optional: true, + }, + "admin_email": { + Type: schema.TypeString, + Description: "Valid for GSuite only: Email of a user with admin permissions on google, relevant only for synchronization", + Optional: true, + }, + "access_token": { + Type: schema.TypeString, + Description: "Valid for Okta only: The Okta API token generated in Okta, used to sync groups and their users from Okta to Codefresh", + Optional: true, + }, + }, + }, + }, + "ldap": { + Description: "Settings for Keycloak IDP", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: SupportedIdps, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "url": { + Type: schema.TypeString, + Description: "ldap server url", + Required: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^ldap(s?):\/\/`), "must be a valid ldap url (must start with ldap:// or ldaps://)"), + }, + "password": { + Type: schema.TypeString, + Description: "The password of the user defined in Distinguished name that will be used to search other users", + Required: true, + Sensitive: true, + }, + "distinguished_name": { + Type: schema.TypeString, + Description: "The username to be used to search other users in LDAP notation (combination of cn, ou,dc)", + Optional: true, + Computed: true, + }, + "search_base": { + Type: schema.TypeString, + Description: "The search-user scope in LDAP notation", + Required: true, + }, + "search_filter": { + Type: schema.TypeString, + Description: "The attribute by which to search for the user on the LDAP server. By default, set to uid. For the Azure LDAP server, set this field to sAMAccountName", + Optional: true, + }, + "certificate": { + Type: schema.TypeString, + Description: "For ldaps only: The security certificate of the LDAP server. Do not convert to base64 or any other encoding", + Optional: true, + }, + "allowed_groups_for_sync": { + Type: schema.TypeString, + Description: "To sync only by specified groups - specify a comma separated list of groups, by default all groups will be synced", + Optional: true, + }, + "search_base_for_sync": { + Type: schema.TypeString, + Description: "Synchronize using a custom search base, by deafult seach_base is used", + Optional: true, + }, + }, + }, + }, + } +) diff --git a/codefresh/internal/idp copy/types.go b/codefresh/internal/idp copy/types.go new file mode 100644 index 00000000..feaff769 --- /dev/null +++ b/codefresh/internal/idp copy/types.go @@ -0,0 +1,15 @@ +package idp + +const ( + GitHub string = "github" + GitLab string = "gitlab" + Bitbucket string = "bitbucket" + Okta string = "okta" + Google string = "google" + Auth0 string = "auth0" + Azure string = "azure" + OneLogin string = "onelogin" + Keycloak string = "keycloak" + SAML string = "saml" + LDAP string = "ldap" +) diff --git a/codefresh/provider.go b/codefresh/provider.go index 2f77def2..c6d9f98d 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(), diff --git a/codefresh/resource_pipeline.go b/codefresh/resource_pipeline.go index 35adc3b9..92c2b5b0 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 8e52d612..9a6388aa 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 df8a1138..c73ecf02 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) From bf48dc059123003f3c393ae016743543aec4a814 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Sun, 26 May 2024 19:02:08 +0300 Subject: [PATCH 02/11] initial resource implementation --- codefresh/cfclient/gitops_account_settings.go | 24 + codefresh/data_account_gitops_settings.go | 6 +- codefresh/internal/gitops/account_settings.go | 36 ++ codefresh/internal/gitops/doc.go | 2 + codefresh/internal/idp copy/doc.go | 2 - codefresh/internal/idp copy/schema.go | 504 ------------------ codefresh/internal/idp copy/types.go | 15 - codefresh/provider.go | 1 + codefresh/resource_account_gitops_settings.go | 129 +++++ 9 files changed, 195 insertions(+), 524 deletions(-) create mode 100644 codefresh/internal/gitops/account_settings.go create mode 100644 codefresh/internal/gitops/doc.go delete mode 100644 codefresh/internal/idp copy/doc.go delete mode 100644 codefresh/internal/idp copy/schema.go delete mode 100644 codefresh/internal/idp copy/types.go create mode 100644 codefresh/resource_account_gitops_settings.go diff --git a/codefresh/cfclient/gitops_account_settings.go b/codefresh/cfclient/gitops_account_settings.go index 850c96aa..810452f3 100644 --- a/codefresh/cfclient/gitops_account_settings.go +++ b/codefresh/cfclient/gitops_account_settings.go @@ -57,3 +57,27 @@ func (client *Client) GetActiveGitopsAccountInfo() (*GitopsActiveAccountInfo, er 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/data_account_gitops_settings.go b/codefresh/data_account_gitops_settings.go index d1b26104..56c20277 100644 --- a/codefresh/data_account_gitops_settings.go +++ b/codefresh/data_account_gitops_settings.go @@ -28,7 +28,7 @@ func dataSourceAccountGitopsSettings() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "shared_config_repo": { + "shared_config_repository": { Type: schema.TypeString, Computed: true, }, @@ -60,7 +60,7 @@ func dataSourceAccountGitopsSettingsRead(d *schema.ResourceData, meta interface{ func mapDataAccountGitopsSettingsToResource(account *cfclient.GitopsActiveAccountInfo, d *schema.ResourceData) error { if account == nil || account.ID == "" { - return fmt.Errorf("data.codefresh_account - failed to mapDataAccountToResource") + return fmt.Errorf("cannot get gitops settings as account wasn't properly retrived") } d.SetId(account.ID) d.Set("_id", account.ID) @@ -68,7 +68,7 @@ func mapDataAccountGitopsSettingsToResource(account *cfclient.GitopsActiveAccoun d.Set("admins", account.Admins) d.Set("git_provider", account.GitProvider) d.Set("git_provider_api_url", account.GitApiUrl) - d.Set("shared_config_repo", account.SharedConfigRepo) + 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 00000000..10afbe36 --- /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 00000000..ba70d26b --- /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/internal/idp copy/doc.go b/codefresh/internal/idp copy/doc.go deleted file mode 100644 index fe3c330b..00000000 --- a/codefresh/internal/idp copy/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package idp is shared by idp-related resources. -package idp diff --git a/codefresh/internal/idp copy/schema.go b/codefresh/internal/idp copy/schema.go deleted file mode 100644 index 5851b984..00000000 --- a/codefresh/internal/idp copy/schema.go +++ /dev/null @@ -1,504 +0,0 @@ -package idp - -import ( - "regexp" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" -) - -var ( - SupportedIdps = []string{GitHub, GitLab, Okta, Google, Auth0, Azure, OneLogin, Keycloak, SAML, LDAP} - IdpSchema = map[string]*schema.Schema{ - "display_name": { - Description: "The display name for the IDP.", - Type: schema.TypeString, - Required: true, - }, - "name": { - Description: "Name of the IDP, will be generated if not set", - Type: schema.TypeString, - Computed: true, - Optional: true, - }, - "client_type": { - Description: "Type of the IDP. Derived from idp specific config object (github, gitlab etc)", - Type: schema.TypeString, - Computed: true, - ForceNew: true, - }, - "redirect_url": { - Description: "API Callback url for the identity provider", - Type: schema.TypeString, - Computed: true, - }, - "redirect_ui_url": { - Description: "UI Callback url for the identity provider", - Type: schema.TypeString, - Computed: true, - }, - "login_url": { - Description: "Login url using the IDP to Codefresh", - Type: schema.TypeString, - Computed: true, - }, - "github": { - Description: "Settings for GitHub IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_id": { - Type: schema.TypeString, - Description: "Client ID from Github", - Required: true, - }, - "client_secret": { - Type: schema.TypeString, - Description: "Client secret from GitHub", - Required: true, - Sensitive: true, - }, - "authentication_url": { - Type: schema.TypeString, - Description: "Authentication url, Defaults to https://github.com/login/oauth/authorize", - Optional: true, - Default: "https://github.com/login/oauth/authorize", - }, - "token_url": { - Type: schema.TypeString, - Description: "GitHub token endpoint url, Defaults to https://github.com/login/oauth/access_token", - Optional: true, - Default: "https://github.com/login/oauth/access_token", - }, - "user_profile_url": { - Type: schema.TypeString, - Description: "GitHub user profile url, Defaults to https://api.github.com/user", - Optional: true, - Default: "https://api.github.com/user", - }, - "api_host": { - Type: schema.TypeString, - Description: "GitHub API host, Defaults to api.github.com", - Optional: true, - Default: "api.github.com", - }, - "api_path_prefix": { - Type: schema.TypeString, - Description: "GitHub API url path prefix, defaults to /", - Optional: true, - Default: "/", - }, - }, - }, - }, - "gitlab": { - Description: "Settings for GitLab IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_id": { - Type: schema.TypeString, - Description: "Client ID from Gitlab", - Required: true, - }, - "client_secret": { - Type: schema.TypeString, - Description: "Client secret from Gitlab", - Required: true, - Sensitive: true, - }, - "authentication_url": { - Type: schema.TypeString, - Description: "Authentication url, Defaults to https://gitlab.com", - Optional: true, - Default: "https://gitlab.com", - }, - "user_profile_url": { - Type: schema.TypeString, - Description: "User profile url, Defaults to https://gitlab.com/api/v4/user", - Optional: true, - Default: "https://gitlab.com/api/v4/user", - }, - "api_url": { - Type: schema.TypeString, - Description: "Base url for Gitlab API, Defaults to https://gitlab.com/api/v4/", - Optional: true, - Default: "https://gitlab.com/api/v4/", - }, - }, - }, - }, - "okta": { - Description: "Settings for Okta IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_id": { - Type: schema.TypeString, - Description: "Client ID in Okta, must be unique across all identity providers in Codefresh", - Required: true, - }, - "client_secret": { - Type: schema.TypeString, - Description: "Client secret in Okta", - Required: true, - Sensitive: true, - }, - "client_host": { - Type: schema.TypeString, - Description: "The OKTA organization URL, for example, https://.okta.com", - ValidateFunc: validation.StringMatch(regexp.MustCompile(`^(https?:\/\/)(\S+)(\.okta(preview|-emea)?\.com$)`), "must be a valid okta url"), - Required: true, - }, - "app_id": { - Type: schema.TypeString, - Description: "The Codefresh application ID in your OKTA organization", - Optional: true, - }, - "sync_mirror_accounts": { - Type: schema.TypeList, - Description: "The names of the additional Codefresh accounts to be synced from Okta", - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "access_token": { - Type: schema.TypeString, - Description: "The Okta API token generated in Okta, used to sync groups and their users from Okta to Codefresh", - Optional: true, - }, - }, - }, - }, - "google": { - Description: "Settings for Google IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_id": { - Type: schema.TypeString, - Description: "Client ID in Google, must be unique across all identity providers in Codefresh", - Required: true, - }, - "client_secret": { - Type: schema.TypeString, - Description: "Client secret in Google", - Required: true, - Sensitive: true, - }, - "admin_email": { - Type: schema.TypeString, - Description: "Email of a user with admin permissions on google, relevant only for synchronization", - Optional: true, - }, - "json_keyfile": { - Type: schema.TypeString, - Description: "JSON keyfile for google service account used for synchronization", - Optional: true, - }, - "allowed_groups_for_sync": { - Type: schema.TypeString, - Description: "Comma separated list of groups to sync", - Optional: true, - }, - "sync_field": { - Type: schema.TypeString, - Description: "Relevant for custom schema-based synchronization only. See Codefresh documentation", - Optional: true, - }, - }, - }, - }, - "auth0": { - Description: "Settings for Auth0 IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_id": { - Type: schema.TypeString, - Description: "Client ID from Auth0", - Required: true, - }, - "client_secret": { - Type: schema.TypeString, - Description: "Client secret from Auth0", - Required: true, - Sensitive: true, - }, - "domain": { - Type: schema.TypeString, - Description: "The domain of the Auth0 application", - Required: true, - }, - }, - }, - }, - "azure": { - Description: "Settings for Azure IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_secret": { - Type: schema.TypeString, - Description: "Client secret from Azure", - Required: true, - Sensitive: true, - }, - "app_id": { - Type: schema.TypeString, - Description: "The Application ID from your Enterprise Application Properties in Azure AD", - Required: true, - }, - "tenant": { - Type: schema.TypeString, - Description: "Azure tenant", - Optional: true, - }, - "object_id": { - Type: schema.TypeString, - Description: "The Object ID from your Enterprise Application Properties in Azure AD", - Optional: true, - }, - "autosync_teams_and_users": { - Type: schema.TypeBool, - Description: "Set to true to sync user accounts in Azure AD to your Codefresh account", - Optional: true, - Default: false, - }, - "sync_interval": { - Type: schema.TypeInt, - Description: "Sync interval in hours for syncing user accounts in Azure AD to your Codefresh account. If not set the sync inteval will be 12 hours", - Optional: true, - }, - }, - }, - }, - "onelogin": { - Description: "Settings for onelogin IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_id": { - Type: schema.TypeString, - Description: "Client ID from Onelogin", - Required: true, - }, - "client_secret": { - Type: schema.TypeString, - Description: "Client secret from Onelogin", - Required: true, - Sensitive: true, - }, - "domain": { - Type: schema.TypeString, - Description: "The domain to be used for authentication", - Required: true, - }, - "app_id": { - Type: schema.TypeString, - Description: "The Codefresh application ID in your Onelogin", - Optional: true, - }, - "api_client_id": { - Type: schema.TypeString, - Description: "Client ID for onelogin API, only needed if syncing users and groups from Onelogin", - Optional: true, - }, - "api_client_secret": { - Type: schema.TypeString, - Description: "Client secret for onelogin API, only needed if syncing users and groups from Onelogin", - Optional: true, - // When onelogin IDP is created on account level, after the first apply the client secret is returned obfuscated - // DiffSuppressFunc: surpressObfuscatedFields(), - }, - }, - }, - }, - "keycloak": { - Description: "Settings for Keycloak IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_id": { - Type: schema.TypeString, - Description: "Client ID from Keycloak", - Required: true, - }, - "client_secret": { - Type: schema.TypeString, - Description: "Client secret from Keycloak", - Required: true, - Sensitive: true, - }, - "host": { - Type: schema.TypeString, - Description: "The Keycloak URL", - Required: true, - ValidateFunc: validation.StringMatch(regexp.MustCompile(`^(https?:\/\/)(\S+)$`), "must be a valid url"), - }, - "realm": { - Type: schema.TypeString, - Description: "The Realm ID for Codefresh in Keycloak. Defaults to master", - Optional: true, - Default: "master", - }, - }, - }, - }, - "saml": { - Description: "Settings for SAML IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "endpoint": { - Type: schema.TypeString, - Description: "The SSO endpoint of your Identity Provider", - Required: true, - }, - "application_certificate": { - Type: schema.TypeString, - Description: "The security certificate of your Identity Provider. Paste the value directly on the field. Do not convert to base64 or any other encoding by hand", - Required: true, - Sensitive: true, - }, - "provider": { - Type: schema.TypeString, - Description: "SAML provider. Currently supported values - GSuite, okta or empty string for generic provider. Defaults to empty string", - Optional: true, - Default: "", - ValidateFunc: validation.StringInSlice([]string{"", "okta", "GSuite"}, false), - }, - "allowed_groups_for_sync": { - Type: schema.TypeString, - Description: "Valid for GSuite only: Comma separated list of groups to sync", - Optional: true, - }, - "autosync_teams_and_users": { - Type: schema.TypeBool, - Description: "Valid for Okta/GSuite: Set to true to sync user accounts and teams in okta/gsuite to your Codefresh account", - Optional: true, - Default: false, - }, - "sync_interval": { - Type: schema.TypeInt, - Description: "Valid for Okta/GSuite: Sync interval in hours for syncing user accounts in okta/gsuite to your Codefresh account. If not set the sync inteval will be 12 hours", - Optional: true, - }, - "activate_users_after_sync": { - Type: schema.TypeBool, - Description: "Valid for Okta only: If set to true, Codefresh will automatically invite and activate new users added during the automated sync, without waiting for the users to accept the invitations. Defaults to false", - Optional: true, - Default: false, - }, - "app_id": { - Type: schema.TypeString, - Description: "Valid for Okta only: The Codefresh application ID in Okta", - Optional: true, - }, - "client_host": { - Type: schema.TypeString, - Description: "Valid for Okta only: OKTA organization URL, for example, https://.okta.com", - Optional: true, - }, - "json_keyfile": { - Type: schema.TypeString, - Description: "Valid for GSuite only: JSON keyfile for google service account used for synchronization", - Optional: true, - }, - "admin_email": { - Type: schema.TypeString, - Description: "Valid for GSuite only: Email of a user with admin permissions on google, relevant only for synchronization", - Optional: true, - }, - "access_token": { - Type: schema.TypeString, - Description: "Valid for Okta only: The Okta API token generated in Okta, used to sync groups and their users from Okta to Codefresh", - Optional: true, - }, - }, - }, - }, - "ldap": { - Description: "Settings for Keycloak IDP", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ExactlyOneOf: SupportedIdps, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "url": { - Type: schema.TypeString, - Description: "ldap server url", - Required: true, - ValidateFunc: validation.StringMatch(regexp.MustCompile(`^ldap(s?):\/\/`), "must be a valid ldap url (must start with ldap:// or ldaps://)"), - }, - "password": { - Type: schema.TypeString, - Description: "The password of the user defined in Distinguished name that will be used to search other users", - Required: true, - Sensitive: true, - }, - "distinguished_name": { - Type: schema.TypeString, - Description: "The username to be used to search other users in LDAP notation (combination of cn, ou,dc)", - Optional: true, - Computed: true, - }, - "search_base": { - Type: schema.TypeString, - Description: "The search-user scope in LDAP notation", - Required: true, - }, - "search_filter": { - Type: schema.TypeString, - Description: "The attribute by which to search for the user on the LDAP server. By default, set to uid. For the Azure LDAP server, set this field to sAMAccountName", - Optional: true, - }, - "certificate": { - Type: schema.TypeString, - Description: "For ldaps only: The security certificate of the LDAP server. Do not convert to base64 or any other encoding", - Optional: true, - }, - "allowed_groups_for_sync": { - Type: schema.TypeString, - Description: "To sync only by specified groups - specify a comma separated list of groups, by default all groups will be synced", - Optional: true, - }, - "search_base_for_sync": { - Type: schema.TypeString, - Description: "Synchronize using a custom search base, by deafult seach_base is used", - Optional: true, - }, - }, - }, - }, - } -) diff --git a/codefresh/internal/idp copy/types.go b/codefresh/internal/idp copy/types.go deleted file mode 100644 index feaff769..00000000 --- a/codefresh/internal/idp copy/types.go +++ /dev/null @@ -1,15 +0,0 @@ -package idp - -const ( - GitHub string = "github" - GitLab string = "gitlab" - Bitbucket string = "bitbucket" - Okta string = "okta" - Google string = "google" - Auth0 string = "auth0" - Azure string = "azure" - OneLogin string = "onelogin" - Keycloak string = "keycloak" - SAML string = "saml" - LDAP string = "ldap" -) diff --git a/codefresh/provider.go b/codefresh/provider.go index c6d9f98d..ad08cfca 100644 --- a/codefresh/provider.go +++ b/codefresh/provider.go @@ -73,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 00000000..962c02b9 --- /dev/null +++ b/codefresh/resource_account_gitops_settings.go @@ -0,0 +1,129 @@ +package codefresh + +import ( + "fmt" + "regexp" + + "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: "This data source retrieves gitops settings for the active account", + Read: resourceAccountGitopsSettingsRead, + Create: resourceAccountGitopsSettingsUpdate, + Update: resourceAccountGitopsSettingsUpdate, + // 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", + Computed: true, + }, + "git_provider": { + Type: schema.TypeString, + Description: "Git provider name", + 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 includ 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) +} + +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("_id", 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 +} From d01d63583e8d08ff854ee08e51d65f278fe9d88c Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Sun, 26 May 2024 19:14:23 +0300 Subject: [PATCH 03/11] update description --- codefresh/resource_account_gitops_settings.go | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/codefresh/resource_account_gitops_settings.go b/codefresh/resource_account_gitops_settings.go index 962c02b9..327aa1fe 100644 --- a/codefresh/resource_account_gitops_settings.go +++ b/codefresh/resource_account_gitops_settings.go @@ -17,16 +17,16 @@ func resourceAccountGitopsSettings() *schema.Resource { Create: resourceAccountGitopsSettingsUpdate, Update: resourceAccountGitopsSettingsUpdate, // Delete not implemenented as gitops settings cannot be removed, only updated - Delete: resourceAccountGitopsSettingsDelete, + Delete: resourceAccountGitopsSettingsDelete, Schema: map[string]*schema.Schema{ "_id": { Type: schema.TypeString, - Description: "Account ID", + Description: "Account ID for active account", Computed: true, }, "name": { Type: schema.TypeString, - Description: "Account name", + Description: "Account name for active account", Computed: true, }, "git_provider": { @@ -43,18 +43,18 @@ func resourceAccountGitopsSettings() *schema.Resource { // 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)) + defaultProviderUrl, err := gitops.GetDefaultAPIUrlForProvider(d.Get("git_provider").(string)) - if err != nil { - return false - } + if err != nil { + return false + } - if *defaultProviderUrl == old { - return true - } + if *defaultProviderUrl == old { + return true + } } return false - }, + }, }, "shared_config_repository": { Type: schema.TypeString, @@ -108,8 +108,8 @@ func resourceAccountGitopsSettingsUpdate(d *schema.ResourceData, meta interface{ return resourceAccountGitopsSettingsRead(d, meta) } +// Settings cannot be deleted, only updated func resourceAccountGitopsSettingsDelete(d *schema.ResourceData, meta interface{}) error { - return nil } From 78a39019e4b64c510dbf1b500322117e76a0f9d9 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Mon, 27 May 2024 19:20:32 +0300 Subject: [PATCH 04/11] add basic test --- codefresh/resource_account_gitops_settings.go | 3 + .../resource_account_gitops_settings_test.go | 82 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 codefresh/resource_account_gitops_settings_test.go diff --git a/codefresh/resource_account_gitops_settings.go b/codefresh/resource_account_gitops_settings.go index 327aa1fe..23ce2998 100644 --- a/codefresh/resource_account_gitops_settings.go +++ b/codefresh/resource_account_gitops_settings.go @@ -16,6 +16,9 @@ func resourceAccountGitopsSettings() *schema.Resource { 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{ diff --git a/codefresh/resource_account_gitops_settings_test.go b/codefresh/resource_account_gitops_settings_test.go new file mode 100644 index 00000000..c1f874b8 --- /dev/null +++ b/codefresh/resource_account_gitops_settings_test.go @@ -0,0 +1,82 @@ +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), + ), + }, + { + 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) +} From 05a8216c6d5631c229c6c302425f274019d4b9e0 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Tue, 28 May 2024 15:24:22 +0300 Subject: [PATCH 05/11] add docs --- codefresh/data_account_gitops_settings.go | 4 -- codefresh/resource_account_gitops_settings.go | 10 ++-- .../resource_account_gitops_settings_test.go | 18 +++++++ docs/data-sources/account_gitops_settings.md | 28 ++++++++++ docs/resources/account_gitops_settings.md | 52 +++++++++++++++++++ .../resources/account_gitops_settings.md.tmpl | 36 +++++++++++++ 6 files changed, 137 insertions(+), 11 deletions(-) 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/data_account_gitops_settings.go b/codefresh/data_account_gitops_settings.go index 56c20277..2a26c892 100644 --- a/codefresh/data_account_gitops_settings.go +++ b/codefresh/data_account_gitops_settings.go @@ -12,10 +12,6 @@ func dataSourceAccountGitopsSettings() *schema.Resource { Description: "This data source retrieves gitops settings for the active account", Read: dataSourceAccountGitopsSettingsRead, Schema: map[string]*schema.Schema{ - "_id": { - Type: schema.TypeString, - Computed: true, - }, "name": { Type: schema.TypeString, Computed: true, diff --git a/codefresh/resource_account_gitops_settings.go b/codefresh/resource_account_gitops_settings.go index 23ce2998..a5613f57 100644 --- a/codefresh/resource_account_gitops_settings.go +++ b/codefresh/resource_account_gitops_settings.go @@ -3,6 +3,7 @@ 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" @@ -12,7 +13,7 @@ import ( func resourceAccountGitopsSettings() *schema.Resource { return &schema.Resource{ - Description: "This data source retrieves gitops settings for the active account", + 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, @@ -22,11 +23,6 @@ func resourceAccountGitopsSettings() *schema.Resource { // 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 for active account", - Computed: true, - }, "name": { Type: schema.TypeString, Description: "Account name for active account", @@ -34,7 +30,7 @@ func resourceAccountGitopsSettings() *schema.Resource { }, "git_provider": { Type: schema.TypeString, - Description: "Git provider name", + Description: fmt.Sprintf("Git provider name - currently supported values are: %s", strings.Join(gitops.GetSupportedGitProvidersList(), " ,")), Required: true, ValidateFunc: validation.StringInSlice(gitops.GetSupportedGitProvidersList(), false), }, diff --git a/codefresh/resource_account_gitops_settings_test.go b/codefresh/resource_account_gitops_settings_test.go index c1f874b8..5a615e79 100644 --- a/codefresh/resource_account_gitops_settings_test.go +++ b/codefresh/resource_account_gitops_settings_test.go @@ -6,6 +6,7 @@ import ( "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" @@ -29,6 +30,14 @@ func TestAccCodefreshAccountGitopsSettings_basic(t *testing.T) { 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, @@ -80,3 +89,12 @@ func testAccountGitopsSettingsGithubDefaultApiUrl(sharedConfigRepository string) 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/docs/data-sources/account_gitops_settings.md b/docs/data-sources/account_gitops_settings.md new file mode 100644 index 00000000..09887d2e --- /dev/null +++ b/docs/data-sources/account_gitops_settings.md @@ -0,0 +1,28 @@ +--- +# 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 + +- `_id` (String) +- `admins` (List of String) +- `git_provider` (String) +- `git_provider_api_url` (String) +- `id` (String) The ID of this resource. +- `name` (String) +- `shared_config_repository` (String) + + diff --git a/docs/resources/account_gitops_settings.md b/docs/resources/account_gitops_settings.md new file mode 100644 index 00000000..c83f51fd --- /dev/null +++ b/docs/resources/account_gitops_settings.md @@ -0,0 +1,52 @@ +--- +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" +} +``` +```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 includ 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 for active account +- `id` (String) The ID of this resource. +- `name` (String) Account name for active account + + +-> 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 00000000..b8fbfddd --- /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" +} +``` +```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 updated will fail. +If you need to change the repository please contact Codefresh support. + +## Import +```sh +terraform import codefresh_account_idp.test +``` From cad7705e4922106e66dca025c40c633c7d2c93a6 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Thu, 30 May 2024 10:50:26 +0300 Subject: [PATCH 06/11] run docs --- docs/data-sources/account_gitops_settings.md | 1 - docs/resources/account_gitops_settings.md | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/data-sources/account_gitops_settings.md b/docs/data-sources/account_gitops_settings.md index 09887d2e..1ee8aa67 100644 --- a/docs/data-sources/account_gitops_settings.md +++ b/docs/data-sources/account_gitops_settings.md @@ -17,7 +17,6 @@ This data source retrieves gitops settings for the active account ### Read-Only -- `_id` (String) - `admins` (List of String) - `git_provider` (String) - `git_provider_api_url` (String) diff --git a/docs/resources/account_gitops_settings.md b/docs/resources/account_gitops_settings.md index c83f51fd..c2a8a297 100644 --- a/docs/resources/account_gitops_settings.md +++ b/docs/resources/account_gitops_settings.md @@ -38,12 +38,11 @@ resource "codefresh_account_gitops_settings" "gitops-settings" { ### Read-Only -- `_id` (String) Account ID for active account - `id` (String) The ID of this resource. - `name` (String) Account name for active account - --> Once internal config repository is cloned successfully by one or more runtimes it can no longer be changed and all attempted updates will fail. +[!WARNING] +Once internal config repository is cloned successfully by one or more runtimes it can no longer be changed and all attempted updated will fail. If you need to change the repository please contact Codefresh support. ## Import From 32bec9d51bc2db9b2974e8f69568d465f6f776ba Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Thu, 30 May 2024 14:18:25 +0300 Subject: [PATCH 07/11] fix id --- codefresh/data_account_gitops_settings.go | 6 +++++- codefresh/resource_account_gitops_settings.go | 7 ++++++- docs/data-sources/account_gitops_settings.md | 2 +- docs/resources/account_gitops_settings.md | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/codefresh/data_account_gitops_settings.go b/codefresh/data_account_gitops_settings.go index 2a26c892..3854b0a5 100644 --- a/codefresh/data_account_gitops_settings.go +++ b/codefresh/data_account_gitops_settings.go @@ -12,6 +12,11 @@ func dataSourceAccountGitopsSettings() *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, @@ -59,7 +64,6 @@ func mapDataAccountGitopsSettingsToResource(account *cfclient.GitopsActiveAccoun return fmt.Errorf("cannot get gitops settings as account wasn't properly retrived") } d.SetId(account.ID) - d.Set("_id", account.ID) d.Set("name", account.AccountName) d.Set("admins", account.Admins) d.Set("git_provider", account.GitProvider) diff --git a/codefresh/resource_account_gitops_settings.go b/codefresh/resource_account_gitops_settings.go index a5613f57..6ac6460b 100644 --- a/codefresh/resource_account_gitops_settings.go +++ b/codefresh/resource_account_gitops_settings.go @@ -23,6 +23,11 @@ func resourceAccountGitopsSettings() *schema.Resource { // 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", @@ -117,8 +122,8 @@ func mapAccountGitopsSettingsToResource(account *cfclient.GitopsActiveAccountInf if account == nil || account.ID == "" { return fmt.Errorf("cannot get gitops settings as account wasn't properly retrived") } + d.SetId(account.ID) - d.Set("_id", account.ID) d.Set("name", account.AccountName) d.Set("git_provider", account.GitProvider) d.Set("git_provider_api_url", account.GitApiUrl) diff --git a/docs/data-sources/account_gitops_settings.md b/docs/data-sources/account_gitops_settings.md index 1ee8aa67..f0b6c1fb 100644 --- a/docs/data-sources/account_gitops_settings.md +++ b/docs/data-sources/account_gitops_settings.md @@ -20,7 +20,7 @@ This data source retrieves gitops settings for the active account - `admins` (List of String) - `git_provider` (String) - `git_provider_api_url` (String) -- `id` (String) The ID of this resource. +- `id` (String) Account Id - `name` (String) - `shared_config_repository` (String) diff --git a/docs/resources/account_gitops_settings.md b/docs/resources/account_gitops_settings.md index c2a8a297..b5663e54 100644 --- a/docs/resources/account_gitops_settings.md +++ b/docs/resources/account_gitops_settings.md @@ -38,7 +38,7 @@ resource "codefresh_account_gitops_settings" "gitops-settings" { ### Read-Only -- `id` (String) The ID of this resource. +- `id` (String) Account Id - `name` (String) Account name for active account [!WARNING] From 28710ae151803f15c433e81f4ea43514a634fe12 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Sun, 2 Jun 2024 15:55:31 +0300 Subject: [PATCH 08/11] fix some typos --- codefresh/resource_account_gitops_settings.go | 2 +- docs/resources/account_gitops_settings.md | 6 +++--- templates/resources/account_gitops_settings.md.tmpl | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/codefresh/resource_account_gitops_settings.go b/codefresh/resource_account_gitops_settings.go index 6ac6460b..81dd852d 100644 --- a/codefresh/resource_account_gitops_settings.go +++ b/codefresh/resource_account_gitops_settings.go @@ -62,7 +62,7 @@ func resourceAccountGitopsSettings() *schema.Resource { }, "shared_config_repository": { Type: schema.TypeString, - Description: "Shared config repository url. Must be a valid git url which contains `.git`. May also includ path and branch references", + 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, }, diff --git a/docs/resources/account_gitops_settings.md b/docs/resources/account_gitops_settings.md index b5663e54..b8be9f7d 100644 --- a/docs/resources/account_gitops_settings.md +++ b/docs/resources/account_gitops_settings.md @@ -13,7 +13,7 @@ Codefresh account gitops setting - such as git provider, API URL for the git pro ```hcl resource "codefresh_account_gitops_settings" "gitops-settings" { git_provider = "GITHUB" - shared_config_repository = "https://github.com/example-org/codefresh-internal-shared-config.git" + shared_config_repository = "https://github.com/example-org/codefresh-internal-shared-config.git?ref=main" } ``` ```hcl @@ -30,7 +30,7 @@ resource "codefresh_account_gitops_settings" "gitops-settings" { ### 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 includ path and branch references +- `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 @@ -42,7 +42,7 @@ resource "codefresh_account_gitops_settings" "gitops-settings" { - `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 updated will fail. +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 diff --git a/templates/resources/account_gitops_settings.md.tmpl b/templates/resources/account_gitops_settings.md.tmpl index b8fbfddd..1966bbf6 100644 --- a/templates/resources/account_gitops_settings.md.tmpl +++ b/templates/resources/account_gitops_settings.md.tmpl @@ -13,7 +13,7 @@ description: |- ```hcl resource "codefresh_account_gitops_settings" "gitops-settings" { git_provider = "GITHUB" - shared_config_repository = "https://github.com/example-org/codefresh-internal-shared-config.git" + shared_config_repository = "https://github.com/example-org/codefresh-internal-shared-config.git?ref=main" } ``` ```hcl @@ -27,7 +27,7 @@ resource "codefresh_account_gitops_settings" "gitops-settings" { {{ .SchemaMarkdown | trimspace }} [!WARNING] -Once internal config repository is cloned successfully by one or more runtimes it can no longer be changed and all attempted updated will fail. +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 From 7fd5cb33b764e50c7e62ceeab5b284f9c2590ef0 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Sun, 2 Jun 2024 15:59:42 +0300 Subject: [PATCH 09/11] add description for datasource --- codefresh/data_account_gitops_settings.go | 4 ++++ docs/data-sources/account_gitops_settings.md | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/codefresh/data_account_gitops_settings.go b/codefresh/data_account_gitops_settings.go index 3854b0a5..70f02c79 100644 --- a/codefresh/data_account_gitops_settings.go +++ b/codefresh/data_account_gitops_settings.go @@ -20,18 +20,22 @@ func dataSourceAccountGitopsSettings() *schema.Resource { "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: "Codefresh shared config repository url", }, "admins": { Type: schema.TypeList, diff --git a/docs/data-sources/account_gitops_settings.md b/docs/data-sources/account_gitops_settings.md index f0b6c1fb..5a34dfc9 100644 --- a/docs/data-sources/account_gitops_settings.md +++ b/docs/data-sources/account_gitops_settings.md @@ -18,10 +18,10 @@ This data source retrieves gitops settings for the active account ### Read-Only - `admins` (List of String) -- `git_provider` (String) -- `git_provider_api_url` (String) +- `git_provider` (String) Git provider name +- `git_provider_api_url` (String) Git provider API url - `id` (String) Account Id -- `name` (String) -- `shared_config_repository` (String) +- `name` (String) Account name for active account +- `shared_config_repository` (String) Codefresh shared config repository url From 1bfd1a5c5ebede9b1a8f4c91d6e5e521f083aa01 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Sun, 2 Jun 2024 16:00:17 +0300 Subject: [PATCH 10/11] add description for datasource --- codefresh/data_account_gitops_settings.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codefresh/data_account_gitops_settings.go b/codefresh/data_account_gitops_settings.go index 70f02c79..4245a580 100644 --- a/codefresh/data_account_gitops_settings.go +++ b/codefresh/data_account_gitops_settings.go @@ -35,7 +35,7 @@ func dataSourceAccountGitopsSettings() *schema.Resource { "shared_config_repository": { Type: schema.TypeString, Computed: true, - Description: "Codefresh shared config repository url", + Description: "Shared config repository url", }, "admins": { Type: schema.TypeList, From 22f396fdd9a4653b06d2c3f22d76ff90446bd48a Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Sun, 2 Jun 2024 16:01:53 +0300 Subject: [PATCH 11/11] add description for datasource --- docs/data-sources/account_gitops_settings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data-sources/account_gitops_settings.md b/docs/data-sources/account_gitops_settings.md index 5a34dfc9..a0890b71 100644 --- a/docs/data-sources/account_gitops_settings.md +++ b/docs/data-sources/account_gitops_settings.md @@ -22,6 +22,6 @@ This data source retrieves gitops settings for the active account - `git_provider_api_url` (String) Git provider API url - `id` (String) Account Id - `name` (String) Account name for active account -- `shared_config_repository` (String) Codefresh shared config repository url +- `shared_config_repository` (String) Shared config repository url