From 61124a2184ffaf62c0e65f2472aecdc22c473bd0 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Fri, 25 Feb 2022 15:59:07 -0800 Subject: [PATCH] Add PrivateCA CertificateAuthority data source (#5750) * Add CA ds * Provider * Fmt * Add CA datasource * Write docs * Check err --- .../data_source_certificate_authority.go | 76 +++++++++++++++ .../data_source_certificate_authority_test.go | 94 +++++++++++++++++++ .../terraform/utils/provider.go.erb | 1 + ...vateca_certificate_authority.html.markdown | 47 ++++++++++ 4 files changed, 218 insertions(+) create mode 100644 mmv1/third_party/terraform/data_sources/data_source_certificate_authority.go create mode 100644 mmv1/third_party/terraform/tests/data_source_certificate_authority_test.go create mode 100644 mmv1/third_party/terraform/website/docs/d/privateca_certificate_authority.html.markdown diff --git a/mmv1/third_party/terraform/data_sources/data_source_certificate_authority.go b/mmv1/third_party/terraform/data_sources/data_source_certificate_authority.go new file mode 100644 index 000000000000..bdbff677d0f4 --- /dev/null +++ b/mmv1/third_party/terraform/data_sources/data_source_certificate_authority.go @@ -0,0 +1,76 @@ +package google + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourcePrivatecaCertificateAuthority() *schema.Resource { + dsSchema := datasourceSchemaFromResourceSchema(resourcePrivatecaCertificateAuthority().Schema) + addOptionalFieldsToSchema(dsSchema, "project") + addOptionalFieldsToSchema(dsSchema, "location") + addOptionalFieldsToSchema(dsSchema, "pool") + addOptionalFieldsToSchema(dsSchema, "certificate_authority_id") + + dsSchema["pem_csr"] = &schema.Schema{ + Type: schema.TypeString, + Computed: true, + } + + return &schema.Resource{ + Read: dataSourcePrivatecaCertificateAuthorityRead, + Schema: dsSchema, + } +} + +func dataSourcePrivatecaCertificateAuthorityRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return fmt.Errorf("Error generating user agent: %s", err) + } + + id, err := replaceVars(d, config, "projects/{{project}}/locations/{{location}}/caPools/{{pool}}/certificateAuthorities/{{certificate_authority_id}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + + d.SetId(id) + + err = resourcePrivatecaCertificateAuthorityRead(d, meta) + if err != nil { + return err + } + + // pem_csr is only applicable for SUBORDINATE CertificateAuthorities + if d.Get("type") == "SUBORDINATE" { + url, err := replaceVars(d, config, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/caPools/{{pool}}/certificateAuthorities/{{certificate_authority_id}}:fetch") + if err != nil { + return err + } + + billingProject := "" + + project, err := getProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for CertificateAuthority: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("PrivatecaCertificateAuthority %q", d.Id())) + } + if err := d.Set("pem_csr", res["pemCsr"]); err != nil { + return fmt.Errorf("Error fetching CertificateAuthority: %s", err) + } + } + + return nil +} diff --git a/mmv1/third_party/terraform/tests/data_source_certificate_authority_test.go b/mmv1/third_party/terraform/tests/data_source_certificate_authority_test.go new file mode 100644 index 000000000000..09cd47bf8d75 --- /dev/null +++ b/mmv1/third_party/terraform/tests/data_source_certificate_authority_test.go @@ -0,0 +1,94 @@ +package google + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourcePrivatecaCertificateAuthority_privatecaCertificateAuthorityBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "pool_name": BootstrapSharedCaPoolInLocation(t, "us-central1"), + "pool_location": "us-central1", + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPrivatecaCertificateAuthorityDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccDataSourcePrivatecaCertificateAuthority_privatecaCertificateAuthorityBasicExample(context), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.google_privateca_certificate_authority.default", "pem_csr"), + ), + }, + }, + }) +} + +func testAccDataSourcePrivatecaCertificateAuthority_privatecaCertificateAuthorityBasicExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_privateca_certificate_authority" "default" { + // This example assumes this pool already exists. + // Pools cannot be deleted in normal test circumstances, so we depend on static pools + pool = "%{pool_name}" + certificate_authority_id = "tf-test-my-certificate-authority%{random_suffix}" + location = "%{pool_location}" + type = "SUBORDINATE" + config { + subject_config { + subject { + organization = "HashiCorp" + common_name = "my-certificate-authority" + } + subject_alt_name { + dns_names = ["hashicorp.com"] + } + } + x509_config { + ca_options { + is_ca = true + max_issuer_path_length = 10 + } + key_usage { + base_key_usage { + digital_signature = true + content_commitment = true + key_encipherment = false + data_encipherment = true + key_agreement = true + cert_sign = true + crl_sign = true + decipher_only = true + } + extended_key_usage { + server_auth = true + client_auth = false + email_protection = true + code_signing = true + time_stamping = true + } + } + } + } + lifetime = "86400s" + key_spec { + algorithm = "RSA_PKCS1_4096_SHA256" + } +} + +data "google_privateca_certificate_authority" "default" { + location = google_privateca_certificate_authority.default.location + pool = google_privateca_certificate_authority.default.pool + certificate_authority_id = google_privateca_certificate_authority.default.certificate_authority_id +} + +output "csr" { + value = data.google_privateca_certificate_authority.default.pem_csr +} +`, context) +} diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index 8774d1285068..7d9fc8a6b2eb 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -285,6 +285,7 @@ func Provider() *schema.Provider { "google_monitoring_uptime_check_ips": dataSourceGoogleMonitoringUptimeCheckIps(), "google_netblock_ip_ranges": dataSourceGoogleNetblockIpRanges(), "google_organization": dataSourceGoogleOrganization(), + "google_privateca_certificate_authority": dataSourcePrivatecaCertificateAuthority(), "google_project": dataSourceGoogleProject(), "google_projects": dataSourceGoogleProjects(), "google_project_organization_policy": dataSourceGoogleProjectOrganizationPolicy(), diff --git a/mmv1/third_party/terraform/website/docs/d/privateca_certificate_authority.html.markdown b/mmv1/third_party/terraform/website/docs/d/privateca_certificate_authority.html.markdown new file mode 100644 index 000000000000..0aa9c2f01411 --- /dev/null +++ b/mmv1/third_party/terraform/website/docs/d/privateca_certificate_authority.html.markdown @@ -0,0 +1,47 @@ +--- +subcategory: "Certificate Authority Service" +layout: "google" +page_title: "Google: google_privateca_certificate_authority" +sidebar_current: "docs-google-datasource-privateca-certificate-authority" +description: |- + Contains the data that describes a Certificate Authority +--- +# google_privateca_certificate_authority + +Get info about a Google Cloud IAP Client. + +## Example Usage + +```tf +data "google_privateca_certificate_authority" "default" { + location = "us-west1" + pool = "pool-name" + certificate_authority_id = "ca-id" +} + +output "csr" { + value = data.google_privateca_certificate_authority.default.pem_csr +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `location` - (Required) The location the certificate authority exists in. + +* `pool` - (Required) The name of the pool the certificate authority belongs to. + +* `certificate_authority_id` - (Required) ID of the certificate authority. + +- - - + +* `project` - (Optional) The ID of the project in which the resource belongs. If it + is not provided, the provider project is used. + +## Attributes Reference + +See [google_privateca_certificate_authority](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/privateca_certificate_authority) resource for details of the available attributes. + +* `pem_csr` - The PEM-encoded signed certificate signing request (CSR). This is only set on subordinate certificate authorities. \ No newline at end of file