From c18e05e4febb5568b0892b6781a4c08b38f8d75f Mon Sep 17 00:00:00 2001 From: The Magician Date: Fri, 27 Jan 2023 11:42:15 -0800 Subject: [PATCH] Adding Cloud Build Connection and Repository resources to beta provider. (#7157) (#5140) Signed-off-by: Modular Magician --- .changelog/7157.txt | 6 + google-beta/provider_dcl_client_creation.go | 24 + google-beta/provider_dcl_endpoints.go | 12 + google-beta/provider_dcl_resources.go | 2 + .../resource_cloudbuildv2_connection.go | 647 ++++++++++++++++++ ..._cloudbuildv2_connection_generated_test.go | 406 +++++++++++ ...ce_cloudbuildv2_connection_sweeper_test.go | 71 ++ .../resource_cloudbuildv2_repository.go | 296 ++++++++ ..._cloudbuildv2_repository_generated_test.go | 192 ++++++ .../r/cloudbuildv2_connection.html.markdown | 211 ++++++ .../r/cloudbuildv2_repository.html.markdown | 149 ++++ 11 files changed, 2016 insertions(+) create mode 100644 .changelog/7157.txt create mode 100644 google-beta/resource_cloudbuildv2_connection.go create mode 100644 google-beta/resource_cloudbuildv2_connection_generated_test.go create mode 100644 google-beta/resource_cloudbuildv2_connection_sweeper_test.go create mode 100644 google-beta/resource_cloudbuildv2_repository.go create mode 100644 google-beta/resource_cloudbuildv2_repository_generated_test.go create mode 100644 website/docs/r/cloudbuildv2_connection.html.markdown create mode 100644 website/docs/r/cloudbuildv2_repository.html.markdown diff --git a/.changelog/7157.txt b/.changelog/7157.txt new file mode 100644 index 0000000000..dae7a4761d --- /dev/null +++ b/.changelog/7157.txt @@ -0,0 +1,6 @@ +```release-note:new-resource +`google_cloudbuildv2_connection` (beta) +``` +```release-note:new-resource +`google_cloudbuildv2_repository` (beta) +``` diff --git a/google-beta/provider_dcl_client_creation.go b/google-beta/provider_dcl_client_creation.go index 831544ef56..b534c166e8 100644 --- a/google-beta/provider_dcl_client_creation.go +++ b/google-beta/provider_dcl_client_creation.go @@ -23,6 +23,7 @@ import ( assuredworkloads "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/assuredworkloads/beta" bigqueryreservation "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/bigqueryreservation/beta" cloudbuild "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/cloudbuild/beta" + cloudbuildv2 "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/cloudbuildv2/beta" clouddeploy "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/clouddeploy/beta" cloudresourcemanager "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/cloudresourcemanager/beta" compute "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/compute/beta" @@ -134,6 +135,29 @@ func NewDCLCloudbuildClient(config *Config, userAgent, billingProject string, ti return cloudbuild.NewClient(dclConfig) } +func NewDCLCloudbuildv2Client(config *Config, userAgent, billingProject string, timeout time.Duration) *cloudbuildv2.Client { + configOptions := []dcl.ConfigOption{ + dcl.WithHTTPClient(config.client), + dcl.WithUserAgent(userAgent), + dcl.WithLogger(dclLogger{}), + dcl.WithBasePath(config.Cloudbuildv2BasePath), + } + + if timeout != 0 { + configOptions = append(configOptions, dcl.WithTimeout(timeout)) + } + + if config.UserProjectOverride { + configOptions = append(configOptions, dcl.WithUserProjectOverride()) + if billingProject != "" { + configOptions = append(configOptions, dcl.WithBillingProject(billingProject)) + } + } + + dclConfig := dcl.NewConfig(configOptions...) + return cloudbuildv2.NewClient(dclConfig) +} + func NewDCLClouddeployClient(config *Config, userAgent, billingProject string, timeout time.Duration) *clouddeploy.Client { configOptions := []dcl.ConfigOption{ dcl.WithHTTPClient(config.client), diff --git a/google-beta/provider_dcl_endpoints.go b/google-beta/provider_dcl_endpoints.go index d75b9a5788..45ef9b5a42 100644 --- a/google-beta/provider_dcl_endpoints.go +++ b/google-beta/provider_dcl_endpoints.go @@ -49,6 +49,15 @@ var CloudBuildWorkerPoolEndpointEntry = &schema.Schema{ }, ""), } +var Cloudbuildv2EndpointEntryKey = "cloudbuildv2_custom_endpoint" +var Cloudbuildv2EndpointEntry = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "GOOGLE_CLOUDBUILDV2_CUSTOM_ENDPOINT", + }, ""), +} + var ClouddeployEndpointEntryKey = "clouddeploy_custom_endpoint" var ClouddeployEndpointEntry = &schema.Schema{ Type: schema.TypeString, @@ -125,6 +134,7 @@ type DCLConfig struct { ApikeysBasePath string AssuredWorkloadsBasePath string CloudBuildWorkerPoolBasePath string + Cloudbuildv2BasePath string ClouddeployBasePath string CloudResourceManagerBasePath string DataplexBasePath string @@ -139,6 +149,7 @@ func configureDCLProvider(provider *schema.Provider) { provider.Schema[ApikeysEndpointEntryKey] = ApikeysEndpointEntry provider.Schema[AssuredWorkloadsEndpointEntryKey] = AssuredWorkloadsEndpointEntry provider.Schema[CloudBuildWorkerPoolEndpointEntryKey] = CloudBuildWorkerPoolEndpointEntry + provider.Schema[Cloudbuildv2EndpointEntryKey] = Cloudbuildv2EndpointEntry provider.Schema[ClouddeployEndpointEntryKey] = ClouddeployEndpointEntry provider.Schema[CloudResourceManagerEndpointEntryKey] = CloudResourceManagerEndpointEntry provider.Schema[DataplexEndpointEntryKey] = DataplexEndpointEntry @@ -153,6 +164,7 @@ func providerDCLConfigure(d *schema.ResourceData, config *Config) interface{} { config.ApikeysBasePath = d.Get(ApikeysEndpointEntryKey).(string) config.AssuredWorkloadsBasePath = d.Get(AssuredWorkloadsEndpointEntryKey).(string) config.CloudBuildWorkerPoolBasePath = d.Get(CloudBuildWorkerPoolEndpointEntryKey).(string) + config.Cloudbuildv2BasePath = d.Get(Cloudbuildv2EndpointEntryKey).(string) config.ClouddeployBasePath = d.Get(ClouddeployEndpointEntryKey).(string) config.CloudResourceManagerBasePath = d.Get(CloudResourceManagerEndpointEntryKey).(string) config.DataplexBasePath = d.Get(DataplexEndpointEntryKey).(string) diff --git a/google-beta/provider_dcl_resources.go b/google-beta/provider_dcl_resources.go index 16c653b691..84a9c9502f 100644 --- a/google-beta/provider_dcl_resources.go +++ b/google-beta/provider_dcl_resources.go @@ -24,6 +24,8 @@ var dclResources = map[string]*schema.Resource{ "google_assured_workloads_workload": resourceAssuredWorkloadsWorkload(), "google_bigquery_reservation_assignment": resourceBigqueryReservationAssignment(), "google_cloudbuild_worker_pool": resourceCloudbuildWorkerPool(), + "google_cloudbuildv2_connection": resourceCloudbuildv2Connection(), + "google_cloudbuildv2_repository": resourceCloudbuildv2Repository(), "google_clouddeploy_delivery_pipeline": resourceClouddeployDeliveryPipeline(), "google_clouddeploy_target": resourceClouddeployTarget(), "google_compute_firewall_policy": resourceComputeFirewallPolicy(), diff --git a/google-beta/resource_cloudbuildv2_connection.go b/google-beta/resource_cloudbuildv2_connection.go new file mode 100644 index 0000000000..dd0d6965be --- /dev/null +++ b/google-beta/resource_cloudbuildv2_connection.go @@ -0,0 +1,647 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: DCL *** +// +// ---------------------------------------------------------------------------- +// +// This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules) +// and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library). +// Changes will need to be made to the DCL or Magic Modules instead of here. +// +// We are not currently able to accept contributions to this file. If changes +// are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl" + cloudbuildv2 "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/cloudbuildv2/beta" +) + +func resourceCloudbuildv2Connection() *schema.Resource { + return &schema.Resource{ + Create: resourceCloudbuildv2ConnectionCreate, + Read: resourceCloudbuildv2ConnectionRead, + Update: resourceCloudbuildv2ConnectionUpdate, + Delete: resourceCloudbuildv2ConnectionDelete, + + Importer: &schema.ResourceImporter{ + State: resourceCloudbuildv2ConnectionImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Update: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The location for the resource", + }, + + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Immutable. The resource name of the connection, in the format `projects/{project}/locations/{location}/connections/{connection_id}`.", + }, + + "annotations": { + Type: schema.TypeMap, + Optional: true, + Description: "Allows clients to store small amounts of arbitrary data.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "disabled": { + Type: schema.TypeBool, + Optional: true, + Description: "If disabled is set to true, functionality is disabled for this connection. Repository based API methods and webhooks processing for repositories in this connection will be disabled.", + }, + + "github_config": { + Type: schema.TypeList, + Optional: true, + Description: "Configuration for connections to github.com.", + MaxItems: 1, + Elem: Cloudbuildv2ConnectionGithubConfigSchema(), + ConflictsWith: []string{"github_enterprise_config"}, + }, + + "github_enterprise_config": { + Type: schema.TypeList, + Optional: true, + Description: "Configuration for connections to an instance of GitHub Enterprise.", + MaxItems: 1, + Elem: Cloudbuildv2ConnectionGithubEnterpriseConfigSchema(), + ConflictsWith: []string{"github_config"}, + }, + + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "The project for the resource", + }, + + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Output only. Server assigned timestamp for when the connection was created.", + }, + + "etag": { + Type: schema.TypeString, + Computed: true, + Description: "This checksum is computed by the server based on the value of other fields, and may be sent on update and delete requests to ensure the client has an up-to-date value before proceeding.", + }, + + "installation_state": { + Type: schema.TypeList, + Computed: true, + Description: "Output only. Installation state of the Connection.", + Elem: Cloudbuildv2ConnectionInstallationStateSchema(), + }, + + "reconciling": { + Type: schema.TypeBool, + Computed: true, + Description: "Output only. Set to true when the connection is being set up or updated in the background.", + }, + + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: "Output only. Server assigned timestamp for when the connection was updated.", + }, + }, + } +} + +func Cloudbuildv2ConnectionGithubConfigSchema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "app_installation_id": { + Type: schema.TypeInt, + Optional: true, + Description: "GitHub App installation id.", + }, + + "authorizer_credential": { + Type: schema.TypeList, + Optional: true, + Description: "OAuth credential of the account that authorized the Cloud Build GitHub App. It is recommended to use a robot account instead of a human user account. The OAuth token must be tied to the Cloud Build GitHub App.", + MaxItems: 1, + Elem: Cloudbuildv2ConnectionGithubConfigAuthorizerCredentialSchema(), + }, + }, + } +} + +func Cloudbuildv2ConnectionGithubConfigAuthorizerCredentialSchema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "oauth_token_secret_version": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "A SecretManager resource containing the OAuth token that authorizes the Cloud Build connection. Format: `projects/*/secrets/*/versions/*`.", + }, + + "username": { + Type: schema.TypeString, + Computed: true, + Description: "The username associated to this token.", + }, + }, + } +} + +func Cloudbuildv2ConnectionGithubEnterpriseConfigSchema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "host_uri": { + Type: schema.TypeString, + Required: true, + Description: "Required. The URI of the GitHub Enterprise host this connection is for.", + }, + + "app_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Id of the GitHub App created from the manifest.", + }, + + "app_installation_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the installation of the GitHub App.", + }, + + "app_slug": { + Type: schema.TypeString, + Optional: true, + Description: "The URL-friendly name of the GitHub App.", + }, + + "private_key_secret_version": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "SecretManager resource containing the private key of the GitHub App, formatted as `projects/*/secrets/*/versions/*`.", + }, + + "service_directory_config": { + Type: schema.TypeList, + Optional: true, + Description: "Configuration for using Service Directory to privately connect to a GitHub Enterprise server. This should only be set if the GitHub Enterprise server is hosted on-premises and not reachable by public internet. If this field is left empty, calls to the GitHub Enterprise server will be made over the public internet.", + MaxItems: 1, + Elem: Cloudbuildv2ConnectionGithubEnterpriseConfigServiceDirectoryConfigSchema(), + }, + + "ssl_ca": { + Type: schema.TypeString, + Optional: true, + Description: "SSL certificate to use for requests to GitHub Enterprise.", + }, + + "webhook_secret_secret_version": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "SecretManager resource containing the webhook secret of the GitHub App, formatted as `projects/*/secrets/*/versions/*`.", + }, + }, + } +} + +func Cloudbuildv2ConnectionGithubEnterpriseConfigServiceDirectoryConfigSchema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "service": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "Required. The Service Directory service name. Format: projects/{project}/locations/{location}/namespaces/{namespace}/services/{service}.", + }, + }, + } +} + +func Cloudbuildv2ConnectionInstallationStateSchema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "action_uri": { + Type: schema.TypeString, + Computed: true, + Description: "Output only. Link to follow for next action. Empty string if the installation is already complete.", + }, + + "message": { + Type: schema.TypeString, + Computed: true, + Description: "Output only. Message of what the user should do next to continue the installation. Empty string if the installation is already complete.", + }, + + "stage": { + Type: schema.TypeString, + Computed: true, + Description: "Output only. Current step of the installation process. Possible values: STAGE_UNSPECIFIED, PENDING_CREATE_APP, PENDING_USER_OAUTH, PENDING_INSTALL_APP, COMPLETE", + }, + }, + } +} + +func resourceCloudbuildv2ConnectionCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &cloudbuildv2.Connection{ + Location: dcl.String(d.Get("location").(string)), + Name: dcl.String(d.Get("name").(string)), + Annotations: checkStringMap(d.Get("annotations")), + Disabled: dcl.Bool(d.Get("disabled").(bool)), + GithubConfig: expandCloudbuildv2ConnectionGithubConfig(d.Get("github_config")), + GithubEnterpriseConfig: expandCloudbuildv2ConnectionGithubEnterpriseConfig(d.Get("github_enterprise_config")), + Project: dcl.String(project), + } + + id, err := obj.ID() + if err != nil { + return fmt.Errorf("error constructing id: %s", err) + } + d.SetId(id) + directive := CreateDirective + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLCloudbuildv2Client(config, userAgent, billingProject, d.Timeout(schema.TimeoutCreate)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + res, err := client.ApplyConnection(context.Background(), obj, directive...) + + if _, ok := err.(dcl.DiffAfterApplyError); ok { + log.Printf("[DEBUG] Diff after apply returned from the DCL: %s", err) + } else if err != nil { + // The resource didn't actually create + d.SetId("") + return fmt.Errorf("Error creating Connection: %s", err) + } + + log.Printf("[DEBUG] Finished creating Connection %q: %#v", d.Id(), res) + + return resourceCloudbuildv2ConnectionRead(d, meta) +} + +func resourceCloudbuildv2ConnectionRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &cloudbuildv2.Connection{ + Location: dcl.String(d.Get("location").(string)), + Name: dcl.String(d.Get("name").(string)), + Annotations: checkStringMap(d.Get("annotations")), + Disabled: dcl.Bool(d.Get("disabled").(bool)), + GithubConfig: expandCloudbuildv2ConnectionGithubConfig(d.Get("github_config")), + GithubEnterpriseConfig: expandCloudbuildv2ConnectionGithubEnterpriseConfig(d.Get("github_enterprise_config")), + Project: dcl.String(project), + } + + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLCloudbuildv2Client(config, userAgent, billingProject, d.Timeout(schema.TimeoutRead)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + res, err := client.GetConnection(context.Background(), obj) + if err != nil { + resourceName := fmt.Sprintf("Cloudbuildv2Connection %q", d.Id()) + return handleNotFoundDCLError(err, d, resourceName) + } + + if err = d.Set("location", res.Location); err != nil { + return fmt.Errorf("error setting location in state: %s", err) + } + if err = d.Set("name", res.Name); err != nil { + return fmt.Errorf("error setting name in state: %s", err) + } + if err = d.Set("annotations", res.Annotations); err != nil { + return fmt.Errorf("error setting annotations in state: %s", err) + } + if err = d.Set("disabled", res.Disabled); err != nil { + return fmt.Errorf("error setting disabled in state: %s", err) + } + if err = d.Set("github_config", flattenCloudbuildv2ConnectionGithubConfig(res.GithubConfig)); err != nil { + return fmt.Errorf("error setting github_config in state: %s", err) + } + if err = d.Set("github_enterprise_config", flattenCloudbuildv2ConnectionGithubEnterpriseConfig(res.GithubEnterpriseConfig)); err != nil { + return fmt.Errorf("error setting github_enterprise_config in state: %s", err) + } + if err = d.Set("project", res.Project); err != nil { + return fmt.Errorf("error setting project in state: %s", err) + } + if err = d.Set("create_time", res.CreateTime); err != nil { + return fmt.Errorf("error setting create_time in state: %s", err) + } + if err = d.Set("etag", res.Etag); err != nil { + return fmt.Errorf("error setting etag in state: %s", err) + } + if err = d.Set("installation_state", flattenCloudbuildv2ConnectionInstallationState(res.InstallationState)); err != nil { + return fmt.Errorf("error setting installation_state in state: %s", err) + } + if err = d.Set("reconciling", res.Reconciling); err != nil { + return fmt.Errorf("error setting reconciling in state: %s", err) + } + if err = d.Set("update_time", res.UpdateTime); err != nil { + return fmt.Errorf("error setting update_time in state: %s", err) + } + + return nil +} +func resourceCloudbuildv2ConnectionUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &cloudbuildv2.Connection{ + Location: dcl.String(d.Get("location").(string)), + Name: dcl.String(d.Get("name").(string)), + Annotations: checkStringMap(d.Get("annotations")), + Disabled: dcl.Bool(d.Get("disabled").(bool)), + GithubConfig: expandCloudbuildv2ConnectionGithubConfig(d.Get("github_config")), + GithubEnterpriseConfig: expandCloudbuildv2ConnectionGithubEnterpriseConfig(d.Get("github_enterprise_config")), + Project: dcl.String(project), + } + directive := UpdateDirective + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + billingProject := "" + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLCloudbuildv2Client(config, userAgent, billingProject, d.Timeout(schema.TimeoutUpdate)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + res, err := client.ApplyConnection(context.Background(), obj, directive...) + + if _, ok := err.(dcl.DiffAfterApplyError); ok { + log.Printf("[DEBUG] Diff after apply returned from the DCL: %s", err) + } else if err != nil { + // The resource didn't actually create + d.SetId("") + return fmt.Errorf("Error updating Connection: %s", err) + } + + log.Printf("[DEBUG] Finished creating Connection %q: %#v", d.Id(), res) + + return resourceCloudbuildv2ConnectionRead(d, meta) +} + +func resourceCloudbuildv2ConnectionDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &cloudbuildv2.Connection{ + Location: dcl.String(d.Get("location").(string)), + Name: dcl.String(d.Get("name").(string)), + Annotations: checkStringMap(d.Get("annotations")), + Disabled: dcl.Bool(d.Get("disabled").(bool)), + GithubConfig: expandCloudbuildv2ConnectionGithubConfig(d.Get("github_config")), + GithubEnterpriseConfig: expandCloudbuildv2ConnectionGithubEnterpriseConfig(d.Get("github_enterprise_config")), + Project: dcl.String(project), + } + + log.Printf("[DEBUG] Deleting Connection %q", d.Id()) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLCloudbuildv2Client(config, userAgent, billingProject, d.Timeout(schema.TimeoutDelete)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + if err := client.DeleteConnection(context.Background(), obj); err != nil { + return fmt.Errorf("Error deleting Connection: %s", err) + } + + log.Printf("[DEBUG] Finished deleting Connection %q", d.Id()) + return nil +} + +func resourceCloudbuildv2ConnectionImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + + if err := parseImportId([]string{ + "projects/(?P[^/]+)/locations/(?P[^/]+)/connections/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVarsForId(d, config, "projects/{{project}}/locations/{{location}}/connections/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func expandCloudbuildv2ConnectionGithubConfig(o interface{}) *cloudbuildv2.ConnectionGithubConfig { + if o == nil { + return cloudbuildv2.EmptyConnectionGithubConfig + } + objArr := o.([]interface{}) + if len(objArr) == 0 || objArr[0] == nil { + return cloudbuildv2.EmptyConnectionGithubConfig + } + obj := objArr[0].(map[string]interface{}) + return &cloudbuildv2.ConnectionGithubConfig{ + AppInstallationId: dcl.Int64(int64(obj["app_installation_id"].(int))), + AuthorizerCredential: expandCloudbuildv2ConnectionGithubConfigAuthorizerCredential(obj["authorizer_credential"]), + } +} + +func flattenCloudbuildv2ConnectionGithubConfig(obj *cloudbuildv2.ConnectionGithubConfig) interface{} { + if obj == nil || obj.Empty() { + return nil + } + transformed := map[string]interface{}{ + "app_installation_id": obj.AppInstallationId, + "authorizer_credential": flattenCloudbuildv2ConnectionGithubConfigAuthorizerCredential(obj.AuthorizerCredential), + } + + return []interface{}{transformed} + +} + +func expandCloudbuildv2ConnectionGithubConfigAuthorizerCredential(o interface{}) *cloudbuildv2.ConnectionGithubConfigAuthorizerCredential { + if o == nil { + return cloudbuildv2.EmptyConnectionGithubConfigAuthorizerCredential + } + objArr := o.([]interface{}) + if len(objArr) == 0 || objArr[0] == nil { + return cloudbuildv2.EmptyConnectionGithubConfigAuthorizerCredential + } + obj := objArr[0].(map[string]interface{}) + return &cloudbuildv2.ConnectionGithubConfigAuthorizerCredential{ + OAuthTokenSecretVersion: dcl.String(obj["oauth_token_secret_version"].(string)), + } +} + +func flattenCloudbuildv2ConnectionGithubConfigAuthorizerCredential(obj *cloudbuildv2.ConnectionGithubConfigAuthorizerCredential) interface{} { + if obj == nil || obj.Empty() { + return nil + } + transformed := map[string]interface{}{ + "oauth_token_secret_version": obj.OAuthTokenSecretVersion, + "username": obj.Username, + } + + return []interface{}{transformed} + +} + +func expandCloudbuildv2ConnectionGithubEnterpriseConfig(o interface{}) *cloudbuildv2.ConnectionGithubEnterpriseConfig { + if o == nil { + return cloudbuildv2.EmptyConnectionGithubEnterpriseConfig + } + objArr := o.([]interface{}) + if len(objArr) == 0 || objArr[0] == nil { + return cloudbuildv2.EmptyConnectionGithubEnterpriseConfig + } + obj := objArr[0].(map[string]interface{}) + return &cloudbuildv2.ConnectionGithubEnterpriseConfig{ + HostUri: dcl.String(obj["host_uri"].(string)), + AppId: dcl.Int64(int64(obj["app_id"].(int))), + AppInstallationId: dcl.Int64(int64(obj["app_installation_id"].(int))), + AppSlug: dcl.String(obj["app_slug"].(string)), + PrivateKeySecretVersion: dcl.String(obj["private_key_secret_version"].(string)), + ServiceDirectoryConfig: expandCloudbuildv2ConnectionGithubEnterpriseConfigServiceDirectoryConfig(obj["service_directory_config"]), + SslCa: dcl.String(obj["ssl_ca"].(string)), + WebhookSecretSecretVersion: dcl.String(obj["webhook_secret_secret_version"].(string)), + } +} + +func flattenCloudbuildv2ConnectionGithubEnterpriseConfig(obj *cloudbuildv2.ConnectionGithubEnterpriseConfig) interface{} { + if obj == nil || obj.Empty() { + return nil + } + transformed := map[string]interface{}{ + "host_uri": obj.HostUri, + "app_id": obj.AppId, + "app_installation_id": obj.AppInstallationId, + "app_slug": obj.AppSlug, + "private_key_secret_version": obj.PrivateKeySecretVersion, + "service_directory_config": flattenCloudbuildv2ConnectionGithubEnterpriseConfigServiceDirectoryConfig(obj.ServiceDirectoryConfig), + "ssl_ca": obj.SslCa, + "webhook_secret_secret_version": obj.WebhookSecretSecretVersion, + } + + return []interface{}{transformed} + +} + +func expandCloudbuildv2ConnectionGithubEnterpriseConfigServiceDirectoryConfig(o interface{}) *cloudbuildv2.ConnectionGithubEnterpriseConfigServiceDirectoryConfig { + if o == nil { + return cloudbuildv2.EmptyConnectionGithubEnterpriseConfigServiceDirectoryConfig + } + objArr := o.([]interface{}) + if len(objArr) == 0 || objArr[0] == nil { + return cloudbuildv2.EmptyConnectionGithubEnterpriseConfigServiceDirectoryConfig + } + obj := objArr[0].(map[string]interface{}) + return &cloudbuildv2.ConnectionGithubEnterpriseConfigServiceDirectoryConfig{ + Service: dcl.String(obj["service"].(string)), + } +} + +func flattenCloudbuildv2ConnectionGithubEnterpriseConfigServiceDirectoryConfig(obj *cloudbuildv2.ConnectionGithubEnterpriseConfigServiceDirectoryConfig) interface{} { + if obj == nil || obj.Empty() { + return nil + } + transformed := map[string]interface{}{ + "service": obj.Service, + } + + return []interface{}{transformed} + +} + +func flattenCloudbuildv2ConnectionInstallationState(obj *cloudbuildv2.ConnectionInstallationState) interface{} { + if obj == nil || obj.Empty() { + return nil + } + transformed := map[string]interface{}{ + "action_uri": obj.ActionUri, + "message": obj.Message, + "stage": obj.Stage, + } + + return []interface{}{transformed} + +} diff --git a/google-beta/resource_cloudbuildv2_connection_generated_test.go b/google-beta/resource_cloudbuildv2_connection_generated_test.go new file mode 100644 index 0000000000..0939304592 --- /dev/null +++ b/google-beta/resource_cloudbuildv2_connection_generated_test.go @@ -0,0 +1,406 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: DCL *** +// +// ---------------------------------------------------------------------------- +// +// This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules) +// and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library). +// Changes will need to be made to the DCL or Magic Modules instead of here. +// +// We are not currently able to accept contributions to this file. If changes +// are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "fmt" + dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl" + cloudbuildv2 "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/cloudbuildv2/beta" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "strings" + "testing" +) + +func TestAccCloudbuildv2Connection_GheCompleteConnection(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": getTestProjectFromEnv(), + "region": getTestRegionFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + + Providers: testAccProvidersOiCS, + CheckDestroy: testAccCheckCloudbuildv2ConnectionDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudbuildv2Connection_GheCompleteConnection(context), + }, + { + ResourceName: "google_cloudbuildv2_connection.primary", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccCloudbuildv2Connection_GheConnection(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": getTestProjectFromEnv(), + "region": getTestRegionFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + + Providers: testAccProvidersOiCS, + CheckDestroy: testAccCheckCloudbuildv2ConnectionDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudbuildv2Connection_GheConnection(context), + }, + { + ResourceName: "google_cloudbuildv2_connection.primary", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccCloudbuildv2Connection_GheConnectionUpdate0(context), + }, + { + ResourceName: "google_cloudbuildv2_connection.primary", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccCloudbuildv2Connection_GhePrivConnection(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": getTestProjectFromEnv(), + "region": getTestRegionFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + + Providers: testAccProvidersOiCS, + CheckDestroy: testAccCheckCloudbuildv2ConnectionDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudbuildv2Connection_GhePrivConnection(context), + }, + { + ResourceName: "google_cloudbuildv2_connection.primary", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccCloudbuildv2Connection_GhePrivUpdateConnection(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": getTestProjectFromEnv(), + "region": getTestRegionFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + + Providers: testAccProvidersOiCS, + CheckDestroy: testAccCheckCloudbuildv2ConnectionDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudbuildv2Connection_GhePrivUpdateConnection(context), + }, + { + ResourceName: "google_cloudbuildv2_connection.primary", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccCloudbuildv2Connection_GhePrivUpdateConnectionUpdate0(context), + }, + { + ResourceName: "google_cloudbuildv2_connection.primary", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccCloudbuildv2Connection_GithubConnection(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": getTestProjectFromEnv(), + "region": getTestRegionFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + + Providers: testAccProvidersOiCS, + CheckDestroy: testAccCheckCloudbuildv2ConnectionDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudbuildv2Connection_GithubConnection(context), + }, + { + ResourceName: "google_cloudbuildv2_connection.primary", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccCloudbuildv2Connection_GithubConnectionUpdate0(context), + }, + { + ResourceName: "google_cloudbuildv2_connection.primary", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCloudbuildv2Connection_GheCompleteConnection(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_connection" "primary" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + annotations = {} + + github_enterprise_config { + host_uri = "https://ghe.proctor-staging-test.com" + app_id = 516 + app_installation_id = 243 + app_slug = "myapp" + private_key_secret_version = "projects/gcb-terraform-creds/secrets/ghe-private-key/versions/latest" + webhook_secret_secret_version = "projects/gcb-terraform-creds/secrets/ghe-webhook-secret/versions/latest" + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCloudbuildv2Connection_GheConnection(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_connection" "primary" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + annotations = {} + + github_enterprise_config { + host_uri = "https://ghe.proctor-staging-test.com" + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCloudbuildv2Connection_GheConnectionUpdate0(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_connection" "primary" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + annotations = {} + + github_enterprise_config { + host_uri = "https://ghe.proctor-staging-test.com" + app_id = 516 + app_installation_id = 243 + app_slug = "myapp" + private_key_secret_version = "projects/gcb-terraform-creds/secrets/ghe-private-key/versions/latest" + webhook_secret_secret_version = "projects/gcb-terraform-creds/secrets/ghe-webhook-secret/versions/latest" + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCloudbuildv2Connection_GhePrivConnection(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_connection" "primary" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + annotations = {} + + github_enterprise_config { + host_uri = "https://ghe.proctor-private-ca.com" + + service_directory_config { + service = "projects/gcb-terraform-creds/locations/%{region}/namespaces/myns/services/serv" + } + + ssl_ca = "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIUANaBCc9j/xdKJHU0sgmv6yE2WCIwDQYJKoZIhvcNAQEL\nBQAwLDEUMBIGA1UEChMLUHJvY3RvciBFbmcxFDASBgNVBAMTC1Byb2N0b3ItZW5n\nMB4XDTIxMDcxNTIwMDcwMloXDTIyMDcxNTIwMDcwMVowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMVel7I88DkhwW445BNPBZvJNTV1AreHdz4um4U1\nop2+4L7JeNrUs5SRc0fzeOyOmA9ZzTDu9hBC7zj/sVNUy6cIQGCj32sr5SCAEIat\nnFZlzmVqJPT4J5NAaE37KO5347myTJEBrvpq8az4CtvX0yUzPK0gbUmaSaztVi4o\ndbJLKyv575xCLC/Hu6fIHBDH19eG1Ath9VpuAOkttRRoxu2VqijJZrGqaS+0o+OX\nrLi5HMtZbZjgQB4mc1g3ZDKX/gynxr+CDNaqNOqxuog33Tl5OcOk9DrR3MInaE7F\nyQFuH9mzF64AqOoTf7Tr/eAIz5XVt8K51nk+fSybEfKVwtMCAwEAAaOCAaEwggGd\nMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQU/9dYyqMz\nv9rOMwPZcoIRMDAQCjAfBgNVHSMEGDAWgBTkQGTiCkLCmv/Awxdz5TAVRmyFfDCB\njQYIKwYBBQUHAQEEgYAwfjB8BggrBgEFBQcwAoZwaHR0cDovL3ByaXZhdGVjYS1j\nb250ZW50LTYxYWEyYzA5LTAwMDAtMjJjMi05ZjYyLWQ0ZjU0N2Y4MDIwMC5zdG9y\nYWdlLmdvb2dsZWFwaXMuY29tLzQxNGU4ZTJjZjU2ZWEyYzQxNmM0L2NhLmNydDAo\nBgNVHREBAf8EHjAcghpnaGUucHJvY3Rvci1wcml2YXRlLWNhLmNvbTCBggYDVR0f\nBHsweTB3oHWgc4ZxaHR0cDovL3ByaXZhdGVjYS1jb250ZW50LTYxYWEyYzA5LTAw\nMDAtMjJjMi05ZjYyLWQ0ZjU0N2Y4MDIwMC5zdG9yYWdlLmdvb2dsZWFwaXMuY29t\nLzQxNGU4ZTJjZjU2ZWEyYzQxNmM0L2NybC5jcmwwDQYJKoZIhvcNAQELBQADggEB\nABo6BQLEZZ+YNiDuv2sRvcxSopQQb7fZjqIA9XOA35pNSKay2SncODnNvfsdRnOp\ncoy25sQSIzWyJ9zWl8DZ6evoOu5csZ2PoFqx5LsIq37w+ZcwD6DM8Zm7JqASxmxx\nGqTF0nHC4Aw8q8aJBeRD3PsSkfN5Q3DP3nTDnLyd0l+yPIkHUbZMoiFHX3BkhCng\nG96mYy/y3t16ghfV9lZkXpD/JK5aiN0bTHCDRc69owgfYiAcAqzBJ9gfZ90MBgzv\ngTTQel5dHg49SYXfnUpTy0HdQLEcoggOF8Q8V+xKdKa6eVbrvjJrkEJmvIQI5iCR\nhNvKR25mx8JUopqEXmONmqU=\n-----END CERTIFICATE-----\n\n-----BEGIN CERTIFICATE-----\nMIIDSDCCAjCgAwIBAgITMwWN+62nLcgyLa7p+jD1K90g6TANBgkqhkiG9w0BAQsF\nADAsMRQwEgYDVQQKEwtQcm9jdG9yIEVuZzEUMBIGA1UEAxMLUHJvY3Rvci1lbmcw\nHhcNMjEwNzEyMTM1OTQ0WhcNMzEwNzEwMTM1OTQzWjAsMRQwEgYDVQQKEwtQcm9j\ndG9yIEVuZzEUMBIGA1UEAxMLUHJvY3Rvci1lbmcwggEiMA0GCSqGSIb3DQEBAQUA\nA4IBDwAwggEKAoIBAQCYqJP5Qt90jIbld2dtuUV/zIkBFsTe4fapJfhBji03xBpN\nO1Yxj/jPSZ67Kdeoy0lEwvc2hL5FQGhIjLMR0mzOyN4fk/DZiA/4tAVi7hJyqpUC\n71JSwp7MwXL1b26CSE1MhcoCqA/E4iZxfJfF/ef4lhmC24UEmu8FEbldoy+6OysB\nRu7dGDwicW5F9h7eSkpGAsCRdJHh65iUx/IH0C4Ux2UZRDZdj6wVbuVu9tb938xF\nyRuVClONoLSn/lwdzeV7hQmBSm8qmfgbNPbYRaNLz3hOpsT+27aDQp2/pxue8hFJ\nd7We3+Lr5O4IL45PBwhVEAiFZqde6d4qViNEB2qTAgMBAAGjYzBhMA4GA1UdDwEB\n/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTkQGTiCkLCmv/Awxdz\n5TAVRmyFfDAfBgNVHSMEGDAWgBTkQGTiCkLCmv/Awxdz5TAVRmyFfDANBgkqhkiG\n9w0BAQsFAAOCAQEAfy5BJsWdx0oWWi7SFg9MbryWjBVPJl93UqACgG0Cgh813O/x\nlDZQhGO/ZFVhHz/WgooE/HgVNoVJTubKLLzz+zCkOB0wa3GMqJDyFjhFmUtd/3VM\nZh0ZQ+JWYsAiZW4VITj5xEn/d/B3xCFWGC1vhvhptEJ8Fo2cE1yM2pzk08NqFWoY\n4FaH0sbxWgyCKwTmtcYDbnx4FYuddryGCIxbYizqUK1dr4DGKeHonhm/d234Ew3x\n3vIBPoHMOfBec/coP1xAf5o+F+MRMO/sQ3tTGgyOH18lwsHo9SmXCrmOwVQPKrEw\nm+A+5TjXLmenyaBhqXa0vkAZYJhWdROhWC0VTA==\n-----END CERTIFICATE-----\n" + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCloudbuildv2Connection_GhePrivUpdateConnection(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_connection" "primary" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + annotations = {} + + github_enterprise_config { + host_uri = "https://ghe.proctor-staging-test.com" + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCloudbuildv2Connection_GhePrivUpdateConnectionUpdate0(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_connection" "primary" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + annotations = {} + + github_enterprise_config { + host_uri = "https://ghe.proctor-private-ca.com" + + service_directory_config { + service = "projects/gcb-terraform-creds/locations/%{region}/namespaces/myns/services/serv" + } + + ssl_ca = "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIUANaBCc9j/xdKJHU0sgmv6yE2WCIwDQYJKoZIhvcNAQEL\nBQAwLDEUMBIGA1UEChMLUHJvY3RvciBFbmcxFDASBgNVBAMTC1Byb2N0b3ItZW5n\nMB4XDTIxMDcxNTIwMDcwMloXDTIyMDcxNTIwMDcwMVowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMVel7I88DkhwW445BNPBZvJNTV1AreHdz4um4U1\nop2+4L7JeNrUs5SRc0fzeOyOmA9ZzTDu9hBC7zj/sVNUy6cIQGCj32sr5SCAEIat\nnFZlzmVqJPT4J5NAaE37KO5347myTJEBrvpq8az4CtvX0yUzPK0gbUmaSaztVi4o\ndbJLKyv575xCLC/Hu6fIHBDH19eG1Ath9VpuAOkttRRoxu2VqijJZrGqaS+0o+OX\nrLi5HMtZbZjgQB4mc1g3ZDKX/gynxr+CDNaqNOqxuog33Tl5OcOk9DrR3MInaE7F\nyQFuH9mzF64AqOoTf7Tr/eAIz5XVt8K51nk+fSybEfKVwtMCAwEAAaOCAaEwggGd\nMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQU/9dYyqMz\nv9rOMwPZcoIRMDAQCjAfBgNVHSMEGDAWgBTkQGTiCkLCmv/Awxdz5TAVRmyFfDCB\njQYIKwYBBQUHAQEEgYAwfjB8BggrBgEFBQcwAoZwaHR0cDovL3ByaXZhdGVjYS1j\nb250ZW50LTYxYWEyYzA5LTAwMDAtMjJjMi05ZjYyLWQ0ZjU0N2Y4MDIwMC5zdG9y\nYWdlLmdvb2dsZWFwaXMuY29tLzQxNGU4ZTJjZjU2ZWEyYzQxNmM0L2NhLmNydDAo\nBgNVHREBAf8EHjAcghpnaGUucHJvY3Rvci1wcml2YXRlLWNhLmNvbTCBggYDVR0f\nBHsweTB3oHWgc4ZxaHR0cDovL3ByaXZhdGVjYS1jb250ZW50LTYxYWEyYzA5LTAw\nMDAtMjJjMi05ZjYyLWQ0ZjU0N2Y4MDIwMC5zdG9yYWdlLmdvb2dsZWFwaXMuY29t\nLzQxNGU4ZTJjZjU2ZWEyYzQxNmM0L2NybC5jcmwwDQYJKoZIhvcNAQELBQADggEB\nABo6BQLEZZ+YNiDuv2sRvcxSopQQb7fZjqIA9XOA35pNSKay2SncODnNvfsdRnOp\ncoy25sQSIzWyJ9zWl8DZ6evoOu5csZ2PoFqx5LsIq37w+ZcwD6DM8Zm7JqASxmxx\nGqTF0nHC4Aw8q8aJBeRD3PsSkfN5Q3DP3nTDnLyd0l+yPIkHUbZMoiFHX3BkhCng\nG96mYy/y3t16ghfV9lZkXpD/JK5aiN0bTHCDRc69owgfYiAcAqzBJ9gfZ90MBgzv\ngTTQel5dHg49SYXfnUpTy0HdQLEcoggOF8Q8V+xKdKa6eVbrvjJrkEJmvIQI5iCR\nhNvKR25mx8JUopqEXmONmqU=\n-----END CERTIFICATE-----\n\n-----BEGIN CERTIFICATE-----\nMIIDSDCCAjCgAwIBAgITMwWN+62nLcgyLa7p+jD1K90g6TANBgkqhkiG9w0BAQsF\nADAsMRQwEgYDVQQKEwtQcm9jdG9yIEVuZzEUMBIGA1UEAxMLUHJvY3Rvci1lbmcw\nHhcNMjEwNzEyMTM1OTQ0WhcNMzEwNzEwMTM1OTQzWjAsMRQwEgYDVQQKEwtQcm9j\ndG9yIEVuZzEUMBIGA1UEAxMLUHJvY3Rvci1lbmcwggEiMA0GCSqGSIb3DQEBAQUA\nA4IBDwAwggEKAoIBAQCYqJP5Qt90jIbld2dtuUV/zIkBFsTe4fapJfhBji03xBpN\nO1Yxj/jPSZ67Kdeoy0lEwvc2hL5FQGhIjLMR0mzOyN4fk/DZiA/4tAVi7hJyqpUC\n71JSwp7MwXL1b26CSE1MhcoCqA/E4iZxfJfF/ef4lhmC24UEmu8FEbldoy+6OysB\nRu7dGDwicW5F9h7eSkpGAsCRdJHh65iUx/IH0C4Ux2UZRDZdj6wVbuVu9tb938xF\nyRuVClONoLSn/lwdzeV7hQmBSm8qmfgbNPbYRaNLz3hOpsT+27aDQp2/pxue8hFJ\nd7We3+Lr5O4IL45PBwhVEAiFZqde6d4qViNEB2qTAgMBAAGjYzBhMA4GA1UdDwEB\n/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTkQGTiCkLCmv/Awxdz\n5TAVRmyFfDAfBgNVHSMEGDAWgBTkQGTiCkLCmv/Awxdz5TAVRmyFfDANBgkqhkiG\n9w0BAQsFAAOCAQEAfy5BJsWdx0oWWi7SFg9MbryWjBVPJl93UqACgG0Cgh813O/x\nlDZQhGO/ZFVhHz/WgooE/HgVNoVJTubKLLzz+zCkOB0wa3GMqJDyFjhFmUtd/3VM\nZh0ZQ+JWYsAiZW4VITj5xEn/d/B3xCFWGC1vhvhptEJ8Fo2cE1yM2pzk08NqFWoY\n4FaH0sbxWgyCKwTmtcYDbnx4FYuddryGCIxbYizqUK1dr4DGKeHonhm/d234Ew3x\n3vIBPoHMOfBec/coP1xAf5o+F+MRMO/sQ3tTGgyOH18lwsHo9SmXCrmOwVQPKrEw\nm+A+5TjXLmenyaBhqXa0vkAZYJhWdROhWC0VTA==\n-----END CERTIFICATE-----\n" + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCloudbuildv2Connection_GithubConnection(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_connection" "primary" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + + annotations = { + somekey = "somevalue" + } + + disabled = true + + github_config { + app_installation_id = 0 + + authorizer_credential { + oauth_token_secret_version = "projects/gcb-terraform-creds/secrets/github-pat/versions/1" + } + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCloudbuildv2Connection_GithubConnectionUpdate0(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_connection" "primary" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + + annotations = { + otherkey = "othervalue" + + somekey = "somevalue" + } + + disabled = false + + github_config { + app_installation_id = 31300675 + + authorizer_credential { + oauth_token_secret_version = "projects/gcb-terraform-creds/secrets/github-pat/versions/latest" + } + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCheckCloudbuildv2ConnectionDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "rs.google_cloudbuildv2_connection" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := googleProviderConfig(t) + + billingProject := "" + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + obj := &cloudbuildv2.Connection{ + Location: dcl.String(rs.Primary.Attributes["location"]), + Name: dcl.String(rs.Primary.Attributes["name"]), + Disabled: dcl.Bool(rs.Primary.Attributes["disabled"] == "true"), + Project: dcl.StringOrNil(rs.Primary.Attributes["project"]), + CreateTime: dcl.StringOrNil(rs.Primary.Attributes["create_time"]), + Etag: dcl.StringOrNil(rs.Primary.Attributes["etag"]), + Reconciling: dcl.Bool(rs.Primary.Attributes["reconciling"] == "true"), + UpdateTime: dcl.StringOrNil(rs.Primary.Attributes["update_time"]), + } + + client := NewDCLCloudbuildv2Client(config, config.userAgent, billingProject, 0) + _, err := client.GetConnection(context.Background(), obj) + if err == nil { + return fmt.Errorf("google_cloudbuildv2_connection still exists %v", obj) + } + } + return nil + } +} diff --git a/google-beta/resource_cloudbuildv2_connection_sweeper_test.go b/google-beta/resource_cloudbuildv2_connection_sweeper_test.go new file mode 100644 index 0000000000..02e701536a --- /dev/null +++ b/google-beta/resource_cloudbuildv2_connection_sweeper_test.go @@ -0,0 +1,71 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: DCL *** +// +// ---------------------------------------------------------------------------- +// +// This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules) +// and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library). +// Changes will need to be made to the DCL or Magic Modules instead of here. +// +// We are not currently able to accept contributions to this file. If changes +// are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "log" + "testing" + + cloudbuildv2 "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/cloudbuildv2/beta" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func init() { + resource.AddTestSweepers("Cloudbuildv2Connection", &resource.Sweeper{ + Name: "Cloudbuildv2Connection", + F: testSweepCloudbuildv2Connection, + }) +} + +func testSweepCloudbuildv2Connection(region string) error { + log.Print("[INFO][SWEEPER_LOG] Starting sweeper for Cloudbuildv2Connection") + + config, err := sharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + t := &testing.T{} + billingId := getTestBillingAccountFromEnv(t) + + // Setup variables to be used for Delete arguments. + d := map[string]string{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + "billing_account": billingId, + } + + client := NewDCLCloudbuildv2Client(config, config.userAgent, "", 0) + err = client.DeleteAllConnection(context.Background(), d["project"], d["location"], isDeletableCloudbuildv2Connection) + if err != nil { + return err + } + return nil +} + +func isDeletableCloudbuildv2Connection(r *cloudbuildv2.Connection) bool { + return isSweepableTestResource(*r.Name) +} diff --git a/google-beta/resource_cloudbuildv2_repository.go b/google-beta/resource_cloudbuildv2_repository.go new file mode 100644 index 0000000000..f1039a8e59 --- /dev/null +++ b/google-beta/resource_cloudbuildv2_repository.go @@ -0,0 +1,296 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: DCL *** +// +// ---------------------------------------------------------------------------- +// +// This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules) +// and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library). +// Changes will need to be made to the DCL or Magic Modules instead of here. +// +// We are not currently able to accept contributions to this file. If changes +// are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl" + cloudbuildv2 "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/cloudbuildv2/beta" +) + +func resourceCloudbuildv2Repository() *schema.Resource { + return &schema.Resource{ + Create: resourceCloudbuildv2RepositoryCreate, + Read: resourceCloudbuildv2RepositoryRead, + Delete: resourceCloudbuildv2RepositoryDelete, + + Importer: &schema.ResourceImporter{ + State: resourceCloudbuildv2RepositoryImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Name of the repository.", + }, + + "parent_connection": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "The connection for the resource", + }, + + "remote_uri": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Required. Git Clone HTTPS URI.", + }, + + "annotations": { + Type: schema.TypeMap, + Optional: true, + ForceNew: true, + Description: "Allows clients to store small amounts of arbitrary data.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "location": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: "The location for the resource", + }, + + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "The project for the resource", + }, + + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Output only. Server assigned timestamp for when the connection was created.", + }, + + "etag": { + Type: schema.TypeString, + Computed: true, + Description: "This checksum is computed by the server based on the value of other fields, and may be sent on update and delete requests to ensure the client has an up-to-date value before proceeding.", + }, + + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: "Output only. Server assigned timestamp for when the connection was updated.", + }, + }, + } +} + +func resourceCloudbuildv2RepositoryCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &cloudbuildv2.Repository{ + Name: dcl.String(d.Get("name").(string)), + Connection: dcl.String(d.Get("parent_connection").(string)), + RemoteUri: dcl.String(d.Get("remote_uri").(string)), + Annotations: checkStringMap(d.Get("annotations")), + Location: dcl.StringOrNil(d.Get("location").(string)), + Project: dcl.String(project), + } + + id, err := obj.ID() + if err != nil { + return fmt.Errorf("error constructing id: %s", err) + } + d.SetId(id) + directive := CreateDirective + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLCloudbuildv2Client(config, userAgent, billingProject, d.Timeout(schema.TimeoutCreate)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + res, err := client.ApplyRepository(context.Background(), obj, directive...) + + if _, ok := err.(dcl.DiffAfterApplyError); ok { + log.Printf("[DEBUG] Diff after apply returned from the DCL: %s", err) + } else if err != nil { + // The resource didn't actually create + d.SetId("") + return fmt.Errorf("Error creating Repository: %s", err) + } + + log.Printf("[DEBUG] Finished creating Repository %q: %#v", d.Id(), res) + + return resourceCloudbuildv2RepositoryRead(d, meta) +} + +func resourceCloudbuildv2RepositoryRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &cloudbuildv2.Repository{ + Name: dcl.String(d.Get("name").(string)), + Connection: dcl.String(d.Get("parent_connection").(string)), + RemoteUri: dcl.String(d.Get("remote_uri").(string)), + Annotations: checkStringMap(d.Get("annotations")), + Location: dcl.StringOrNil(d.Get("location").(string)), + Project: dcl.String(project), + } + + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLCloudbuildv2Client(config, userAgent, billingProject, d.Timeout(schema.TimeoutRead)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + res, err := client.GetRepository(context.Background(), obj) + if err != nil { + resourceName := fmt.Sprintf("Cloudbuildv2Repository %q", d.Id()) + return handleNotFoundDCLError(err, d, resourceName) + } + + if err = d.Set("name", res.Name); err != nil { + return fmt.Errorf("error setting name in state: %s", err) + } + if err = d.Set("parent_connection", res.Connection); err != nil { + return fmt.Errorf("error setting parent_connection in state: %s", err) + } + if err = d.Set("remote_uri", res.RemoteUri); err != nil { + return fmt.Errorf("error setting remote_uri in state: %s", err) + } + if err = d.Set("annotations", res.Annotations); err != nil { + return fmt.Errorf("error setting annotations in state: %s", err) + } + if err = d.Set("location", res.Location); err != nil { + return fmt.Errorf("error setting location in state: %s", err) + } + if err = d.Set("project", res.Project); err != nil { + return fmt.Errorf("error setting project in state: %s", err) + } + if err = d.Set("create_time", res.CreateTime); err != nil { + return fmt.Errorf("error setting create_time in state: %s", err) + } + if err = d.Set("etag", res.Etag); err != nil { + return fmt.Errorf("error setting etag in state: %s", err) + } + if err = d.Set("update_time", res.UpdateTime); err != nil { + return fmt.Errorf("error setting update_time in state: %s", err) + } + + return nil +} + +func resourceCloudbuildv2RepositoryDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &cloudbuildv2.Repository{ + Name: dcl.String(d.Get("name").(string)), + Connection: dcl.String(d.Get("parent_connection").(string)), + RemoteUri: dcl.String(d.Get("remote_uri").(string)), + Annotations: checkStringMap(d.Get("annotations")), + Location: dcl.StringOrNil(d.Get("location").(string)), + Project: dcl.String(project), + } + + log.Printf("[DEBUG] Deleting Repository %q", d.Id()) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLCloudbuildv2Client(config, userAgent, billingProject, d.Timeout(schema.TimeoutDelete)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + if err := client.DeleteRepository(context.Background(), obj); err != nil { + return fmt.Errorf("Error deleting Repository: %s", err) + } + + log.Printf("[DEBUG] Finished deleting Repository %q", d.Id()) + return nil +} + +func resourceCloudbuildv2RepositoryImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + + if err := parseImportId([]string{ + "projects/(?P[^/]+)/locations/(?P[^/]+)/connections/(?P[^/]+)/repositories/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVarsForId(d, config, "projects/{{project}}/locations/{{location}}/connections/{{parent_connection}}/repositories/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} diff --git a/google-beta/resource_cloudbuildv2_repository_generated_test.go b/google-beta/resource_cloudbuildv2_repository_generated_test.go new file mode 100644 index 0000000000..b97123d8d8 --- /dev/null +++ b/google-beta/resource_cloudbuildv2_repository_generated_test.go @@ -0,0 +1,192 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: DCL *** +// +// ---------------------------------------------------------------------------- +// +// This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules) +// and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library). +// Changes will need to be made to the DCL or Magic Modules instead of here. +// +// We are not currently able to accept contributions to this file. If changes +// are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "fmt" + dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl" + cloudbuildv2 "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/cloudbuildv2/beta" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "strings" + "testing" +) + +func TestAccCloudbuildv2Repository_GheRepository(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": getTestProjectFromEnv(), + "region": getTestRegionFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + + Providers: testAccProvidersOiCS, + CheckDestroy: testAccCheckCloudbuildv2RepositoryDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudbuildv2Repository_GheRepository(context), + }, + { + ResourceName: "google_cloudbuildv2_repository.primary", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccCloudbuildv2Repository_GithubRepository(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": getTestProjectFromEnv(), + "region": getTestRegionFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + + Providers: testAccProvidersOiCS, + CheckDestroy: testAccCheckCloudbuildv2RepositoryDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudbuildv2Repository_GithubRepository(context), + }, + { + ResourceName: "google_cloudbuildv2_repository.primary", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCloudbuildv2Repository_GheRepository(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_repository" "primary" { + name = "tf-test-repository%{random_suffix}" + parent_connection = google_cloudbuildv2_connection.ghe_complete.name + remote_uri = "https://ghe.proctor-staging-test.com/proctorteam/regional_test.git" + + annotations = { + some-key = "some-value" + } + + location = "%{region}" + project = "%{project_name}" + provider = google-beta +} +resource "google_cloudbuildv2_connection" "ghe_complete" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + annotations = {} + + github_enterprise_config { + host_uri = "https://ghe.proctor-staging-test.com" + app_id = 516 + app_installation_id = 243 + app_slug = "myapp" + private_key_secret_version = "projects/gcb-terraform-creds/secrets/ghe-private-key/versions/latest" + webhook_secret_secret_version = "projects/gcb-terraform-creds/secrets/ghe-webhook-secret/versions/latest" + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCloudbuildv2Repository_GithubRepository(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloudbuildv2_repository" "primary" { + name = "tf-test-repository%{random_suffix}" + parent_connection = google_cloudbuildv2_connection.github_update.name + remote_uri = "https://github.com/gcb-repos-robot/tf-demo.git" + annotations = {} + location = "%{region}" + project = "%{project_name}" + provider = google-beta +} +resource "google_cloudbuildv2_connection" "github_update" { + location = "%{region}" + name = "tf-test-connection%{random_suffix}" + + annotations = { + otherkey = "othervalue" + + somekey = "somevalue" + } + + disabled = false + + github_config { + app_installation_id = 31300675 + + authorizer_credential { + oauth_token_secret_version = "projects/gcb-terraform-creds/secrets/github-pat/versions/latest" + } + } + + project = "%{project_name}" + provider = google-beta +} + +`, context) +} + +func testAccCheckCloudbuildv2RepositoryDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "rs.google_cloudbuildv2_repository" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := googleProviderConfig(t) + + billingProject := "" + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + obj := &cloudbuildv2.Repository{ + Name: dcl.String(rs.Primary.Attributes["name"]), + Connection: dcl.String(rs.Primary.Attributes["parent_connection"]), + RemoteUri: dcl.String(rs.Primary.Attributes["remote_uri"]), + Location: dcl.StringOrNil(rs.Primary.Attributes["location"]), + Project: dcl.StringOrNil(rs.Primary.Attributes["project"]), + CreateTime: dcl.StringOrNil(rs.Primary.Attributes["create_time"]), + Etag: dcl.StringOrNil(rs.Primary.Attributes["etag"]), + UpdateTime: dcl.StringOrNil(rs.Primary.Attributes["update_time"]), + } + + client := NewDCLCloudbuildv2Client(config, config.userAgent, billingProject, 0) + _, err := client.GetRepository(context.Background(), obj) + if err == nil { + return fmt.Errorf("google_cloudbuildv2_repository still exists %v", obj) + } + } + return nil + } +} diff --git a/website/docs/r/cloudbuildv2_connection.html.markdown b/website/docs/r/cloudbuildv2_connection.html.markdown new file mode 100644 index 0000000000..83654987e2 --- /dev/null +++ b/website/docs/r/cloudbuildv2_connection.html.markdown @@ -0,0 +1,211 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: DCL *** +# +# ---------------------------------------------------------------------------- +# +# This file is managed by Magic Modules (https:#github.com/GoogleCloudPlatform/magic-modules) +# and is based on the DCL (https:#github.com/GoogleCloudPlatform/declarative-resource-client-library). +# Changes will need to be made to the DCL or Magic Modules instead of here. +# +# We are not currently able to accept contributions to this file. If changes +# are required, please file an issue at https:#github.com/hashicorp/terraform-provider-google/issues/new/choose +# +# ---------------------------------------------------------------------------- +subcategory: "Cloud Build v2" +description: |- + Beta only: The Cloudbuildv2 Connection resource +--- + +# google_cloudbuildv2_connection + +Beta only: The Cloudbuildv2 Connection resource + +## Example Usage - GitHub Connection +Creates a Connection to github.com +```hcl +resource "google_secret_manager_secret" "github-token-secret" { + provider = google-beta + secret_id = "github-token-secret" + + replication { + automatic = true + } +} + +resource "google_secret_manager_secret_version" "github-token-secret-version" { + provider = google-beta + secret = google_secret_manager_secret.github-token-secret.id + secret_data = file("my-github-token.txt") +} + +data "google_iam_policy" "p4sa-secretAccessor" { + provider = google-beta + binding { + role = "roles/secretmanager.secretAccessor" + // Here, 123456789 is the Google Cloud project number for my-project-name. + members = ["serviceAccount:service-123456789@gcp-sa-cloudbuild.iam.gserviceaccount.com"] + } +} + +resource "google_secret_manager_secret_iam_policy" "policy" { + provider = google-beta + secret_id = google_secret_manager_secret.github-token-secret.secret_id + policy_data = data.google_iam_policy.p4sa-secretAccessor.policy_data +} + +resource "google_cloudbuildv2_connection" "my-connection" { + provider = google-beta + location = "us-west1" + name = "my-connection" + + github_config { + app_installation_id = 123123 + authorizer_credential { + oauth_token_secret_version = google_secret_manager_secret_version.github-token-secret-version.id + } + } +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `location` - + (Required) + The location for the resource + +* `name` - + (Required) + Immutable. The resource name of the connection, in the format `projects/{project}/locations/{location}/connections/{connection_id}`. + + + +- - - + +* `annotations` - + (Optional) + Allows clients to store small amounts of arbitrary data. + +* `disabled` - + (Optional) + If disabled is set to true, functionality is disabled for this connection. Repository based API methods and webhooks processing for repositories in this connection will be disabled. + +* `github_config` - + (Optional) + Configuration for connections to github.com. + +* `github_enterprise_config` - + (Optional) + Configuration for connections to an instance of GitHub Enterprise. + +* `project` - + (Optional) + The project for the resource + + + +The `github_config` block supports: + +* `app_installation_id` - + (Optional) + GitHub App installation id. + +* `authorizer_credential` - + (Optional) + OAuth credential of the account that authorized the Cloud Build GitHub App. It is recommended to use a robot account instead of a human user account. The OAuth token must be tied to the Cloud Build GitHub App. + +The `authorizer_credential` block supports: + +* `oauth_token_secret_version` - + (Optional) + A SecretManager resource containing the OAuth token that authorizes the Cloud Build connection. Format: `projects/*/secrets/*/versions/*`. + +* `username` - + The username associated to this token. + +The `github_enterprise_config` block supports: + +* `host_uri` - + (Required) + Required. The URI of the GitHub Enterprise host this connection is for. + +* `app_id` - + (Optional) + Id of the GitHub App created from the manifest. + +* `app_installation_id` - + (Optional) + ID of the installation of the GitHub App. + +* `app_slug` - + (Optional) + The URL-friendly name of the GitHub App. + +* `private_key_secret_version` - + (Optional) + SecretManager resource containing the private key of the GitHub App, formatted as `projects/*/secrets/*/versions/*`. + +* `service_directory_config` - + (Optional) + Configuration for using Service Directory to privately connect to a GitHub Enterprise server. This should only be set if the GitHub Enterprise server is hosted on-premises and not reachable by public internet. If this field is left empty, calls to the GitHub Enterprise server will be made over the public internet. + +* `ssl_ca` - + (Optional) + SSL certificate to use for requests to GitHub Enterprise. + +* `webhook_secret_secret_version` - + (Optional) + SecretManager resource containing the webhook secret of the GitHub App, formatted as `projects/*/secrets/*/versions/*`. + +The `service_directory_config` block supports: + +* `service` - + (Required) + Required. The Service Directory service name. Format: projects/{project}/locations/{location}/namespaces/{namespace}/services/{service}. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `projects/{{project}}/locations/{{location}}/connections/{{name}}` + +* `create_time` - + Output only. Server assigned timestamp for when the connection was created. + +* `etag` - + This checksum is computed by the server based on the value of other fields, and may be sent on update and delete requests to ensure the client has an up-to-date value before proceeding. + +* `installation_state` - + Output only. Installation state of the Connection. + +* `reconciling` - + Output only. Set to true when the connection is being set up or updated in the background. + +* `update_time` - + Output only. Server assigned timestamp for when the connection was updated. + +## Timeouts + +This resource provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `update` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + +Connection can be imported using any of these accepted formats: + +``` +$ terraform import google_cloudbuildv2_connection.default projects/{{project}}/locations/{{location}}/connections/{{name}} +$ terraform import google_cloudbuildv2_connection.default {{project}}/{{location}}/{{name}} +$ terraform import google_cloudbuildv2_connection.default {{location}}/{{name}} +``` + + + diff --git a/website/docs/r/cloudbuildv2_repository.html.markdown b/website/docs/r/cloudbuildv2_repository.html.markdown new file mode 100644 index 0000000000..32f74e1d0e --- /dev/null +++ b/website/docs/r/cloudbuildv2_repository.html.markdown @@ -0,0 +1,149 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: DCL *** +# +# ---------------------------------------------------------------------------- +# +# This file is managed by Magic Modules (https:#github.com/GoogleCloudPlatform/magic-modules) +# and is based on the DCL (https:#github.com/GoogleCloudPlatform/declarative-resource-client-library). +# Changes will need to be made to the DCL or Magic Modules instead of here. +# +# We are not currently able to accept contributions to this file. If changes +# are required, please file an issue at https:#github.com/hashicorp/terraform-provider-google/issues/new/choose +# +# ---------------------------------------------------------------------------- +subcategory: "Cloud Build v2" +description: |- + Beta only: The Cloudbuildv2 Repository resource +--- + +# google_cloudbuildv2_repository + +Beta only: The Cloudbuildv2 Repository resource + +## Example Usage - Repository in GitHub Connection +Creates a Repository resource inside a Connection to github.com +```hcl +resource "google_secret_manager_secret" "github-token-secret" { + provider = google-beta + secret_id = "github-token-secret" + + replication { + automatic = true + } +} + +resource "google_secret_manager_secret_version" "github-token-secret-version" { + provider = google-beta + secret = google_secret_manager_secret.github-token-secret.id + secret_data = file("my-github-token.txt") +} + +data "google_iam_policy" "p4sa-secretAccessor" { + provider = google-beta + binding { + role = "roles/secretmanager.secretAccessor" + // Here, 123456789 is the Google Cloud project number for my-project-name. + members = ["serviceAccount:service-123456789@gcp-sa-cloudbuild.iam.gserviceaccount.com"] + } +} + +resource "google_secret_manager_secret_iam_policy" "policy" { + provider = google-beta + secret_id = google_secret_manager_secret.github-token-secret.secret_id + policy_data = data.google_iam_policy.p4sa-secretAccessor.policy_data +} + +resource "google_cloudbuildv2_connection" "my-connection" { + provider = google-beta + location = "us-west1" + name = "my-connection" + + github_config { + app_installation_id = 123123 + authorizer_credential { + oauth_token_secret_version = google_secret_manager_secret_version.github-token-secret-version.id + } + } +} + +resource "google_cloudbuildv2_repository" "my-repository" { + provider = google-beta + location = "us-west1" + name = "my-repo" + parent_connection = google_cloudbuildv2_connection.my-connection.name + remote_uri = "https://github.com/myuser/myrepo.git" +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - + (Required) + Name of the repository. + +* `parent_connection` - + (Required) + The connection for the resource + +* `remote_uri` - + (Required) + Required. Git Clone HTTPS URI. + + + +- - - + +* `annotations` - + (Optional) + Allows clients to store small amounts of arbitrary data. + +* `location` - + (Optional) + The location for the resource + +* `project` - + (Optional) + The project for the resource + + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `projects/{{project}}/locations/{{location}}/connections/{{parent_connection}}/repositories/{{name}}` + +* `create_time` - + Output only. Server assigned timestamp for when the connection was created. + +* `etag` - + This checksum is computed by the server based on the value of other fields, and may be sent on update and delete requests to ensure the client has an up-to-date value before proceeding. + +* `update_time` - + Output only. Server assigned timestamp for when the connection was updated. + +## Timeouts + +This resource provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + +Repository can be imported using any of these accepted formats: + +``` +$ terraform import google_cloudbuildv2_repository.default projects/{{project}}/locations/{{location}}/connections/{{parent_connection}}/repositories/{{name}} +$ terraform import google_cloudbuildv2_repository.default {{project}}/{{location}}/{{parent_connection}}/{{name}} +$ terraform import google_cloudbuildv2_repository.default {{location}}/{{parent_connection}}/{{name}} +``` + + +