Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private ca ga #4919

Merged
merged 16 commits into from
Jun 30, 2021
1,054 changes: 869 additions & 185 deletions mmv1/products/privateca/api.yaml

Large diffs are not rendered by default.

99 changes: 53 additions & 46 deletions mmv1/products/privateca/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,28 @@
overrides: !ruby/object:Overrides::ResourceOverrides
CertificateAuthority: !ruby/object:Overrides::Terraform::ResourceOverride
autogen_async: true
iam_policy: !ruby/object:Api::Resource::IamPolicy
parent_resource_attribute: certificate_authority
allowed_iam_role: 'roles/privateca.certificateManager'
method_name_separator: ':'
example_config_body: 'templates/terraform/iam/example_config_body/privateca_certificate_authority.tf.erb'
base_url: '{{name}}'
description: |
{{description}}

~> **Warning:** Please remember that all resources created during preview (via the terraform-provider-google-beta)
will be deleted when CA service transitions to General Availability (GA). Relying on these
certificate authorities for production traffic is discouraged.
import_format: ["projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority_id}}"]
import_format: ["projects/{{project}}/locations/{{location}}/caPools/{{pool}}/certificateAuthorities/{{certificate_authority_id}}"]
rileykarson marked this conversation as resolved.
Show resolved Hide resolved
custom_code: !ruby/object:Provider::Terraform::CustomCode
test_check_destroy: templates/terraform/custom_check_destroy/privateca_certificate_authority.go.erb
examples:
- !ruby/object:Provider::Terraform::Examples
name: "privateca_certificate_authority_basic"
min_version: "beta"
primary_resource_id: "default"
vars:
certificate_authority_id: "my-certificate-authority"
- !ruby/object:Provider::Terraform::Examples
name: "privateca_certificate_authority_full"
min_version: "beta"
primary_resource_id: "default"
vars:
certificate_authority_id: "my-certificate-authority"
test_vars_overrides:
pool: "\"static-ca-pool\""
- !ruby/object:Provider::Terraform::Examples
min_version: beta
name: "privateca_certificate_authority_cmek"
slevenick marked this conversation as resolved.
Show resolved Hide resolved
min_version: "beta"
primary_resource_id: "default"
# Multiple IAM bindings on the same key cause non-determinism
skip_vcr: true
vars:
kms_key_name: "projects/keys-project/locations/us-central1/keyRings/key-ring/cryptoKeys/crypto-key"
certificate_authority_id: "my-certificate-authority"
test_vars_overrides:
kms_key_name: 'BootstrapKMSKeyWithPurposeInLocation(t, "ASYMMETRIC_SIGN", "us-central1").CryptoKey.Name'
virtual_fields:
- !ruby/object:Api::Type::Boolean
name: 'disable_on_delete'
default_value: false
description: |
If set to `true`, the Certificate Authority will be disabled
on delete. If the Certitificate Authorities is not disabled,
it cannot be deleted. Use with care. Defaults to `false`.
pool: "\"static-ca-pool\""
properties:
type: !ruby/object:Overrides::Terraform::PropertyOverride
description: |
Expand All @@ -68,17 +45,13 @@ overrides: !ruby/object:Overrides::ResourceOverrides
~> **Note:** For `SUBORDINATE` Certificate Authorities, they need to
be manually activated (via Cloud Console of `gcloud`) before they can
issue certificates.
config.reusableConfig.reusableConfig: !ruby/object:Overrides::Terraform::PropertyOverride
description: |
{{description}}. Alternatively, one of the short names
found by running `gcloud beta privateca reusable-configs list`.
diff_suppress_func: 'certificateAuthorityReusableConfigDiffSuppress'
config.x509Config: !ruby/object:Overrides::Terraform::PropertyOverride
custom_flatten: 'templates/terraform/custom_flatten/privateca_certificate_509_config.go.erb'
custom_code: !ruby/object:Provider::Terraform::CustomCode
constants: templates/terraform/constants/certificate_authority.go.erb
encoder: templates/terraform/encoders/certificate_authority.go.erb
pre_delete: templates/terraform/pre_delete/privateca_certificate_authority.go.erb
decoder: templates/terraform/decoders/treat_deleted_state_as_gone.go.erb
post_create: templates/terraform/post_create/privateca_authority_enable.go.erb

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if this is always going to be a good thing, since CAs are (by default) created in the STAGED state to allow for pre-production validation, and it's not possible to get back to this state after enabling a CA.

Can this auto-enablement behavior be gated by a flag, so that customers who want to keep it STAGED can do so?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a little complicated as it would require manual steps outside of Terraform to enable the CA, or somewhat complicated state management within Terraform itself. It should be possible in the future to enable this via Terraform, but I believe this is a reasonable default behavior at the moment

pre_delete: templates/terraform/pre_delete/privateca_authority_disable.go.erb
test_check_destroy: templates/terraform/custom_check_destroy/privateca_certificate_authority.go.erb

Certificate: !ruby/object:Overrides::Terraform::ResourceOverride
autogen_async: true
# This resource is a child resource
Expand All @@ -88,30 +61,64 @@ overrides: !ruby/object:Overrides::ResourceOverrides

~> **Note:** The Certificate Authority that is referenced by this resource **must** be
`tier = "ENTERPRISE"`

~> **Warning:** Please remember that all resources created during preview (via the terraform-provider-google-beta)
will be deleted when CA service transitions to General Availability (GA). Relying on these
certificate authorities for production traffic is discouraged.
import_format: ["projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates/{{name}}"]
properties:
config.x509Config: !ruby/object:Overrides::Terraform::PropertyOverride
custom_flatten: 'templates/terraform/custom_flatten/privateca_certificate_509_config.go.erb'
examples:
- !ruby/object:Provider::Terraform::Examples
name: "privateca_certificate_config"
min_version: "beta"
primary_resource_id: "default"
vars:
certificate_authority_id: "my-certificate-authority"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the new v1 resource model it's uncommon to require a CA ID for a certificate, since certificates are nested directly under CaPool resources (not CAs) and the idea is to decouple certs from their specific issuing CAs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This field isn't required, and there is a test that tests this behavior. I think this fits with the new model by allowing the option

certificate_name: "my-certificate"
test_env_vars:
project: :PROJECT_NAME
test_vars_overrides:
pool: "\"static-ca-pool\""
- !ruby/object:Provider::Terraform::Examples
name: "privateca_certificate_csr"
min_version: "beta"
primary_resource_id: "default"
vars:
certificate_name: "my-certificate"
certificate_authority_id: "my-certificate-authority"
test_env_vars:
project: :PROJECT_NAME
test_vars_overrides:
pool: "\"static-ca-pool\""
- !ruby/object:Provider::Terraform::Examples
name: "privateca_certificate_no_authority"
primary_resource_id: "default"
vars:
certificate_name: "my-certificate"
certificate_authority_id: "my-authority"
test_env_vars:
project: :PROJECT_NAME
test_vars_overrides:
pool: "\"static-ca-pool\""
custom_code: !ruby/object:Provider::Terraform::CustomCode
pre_create: templates/terraform/pre_create/privateca_certificate.go.erb
test_check_destroy: templates/terraform/custom_check_destroy/privateca_certificate.go.erb
CaPool: !ruby/object:Overrides::Terraform::ResourceOverride
properties:
issuancePolicy.baselineValues: !ruby/object:Overrides::Terraform::PropertyOverride
custom_flatten: 'templates/terraform/custom_flatten/privateca_certificate_509_config.go.erb'
iam_policy: !ruby/object:Api::Resource::IamPolicy
allowed_iam_role: 'roles/privateca.certificateManager'
method_name_separator: ':'
parent_resource_attribute: ca_pool
example_config_body: 'templates/terraform/iam/example_config_body/privateca_ca_pool.tf.erb'
autogen_async: true
import_format: ["projects/{{project}}/locations/{{location}}/caPools/{{name}}"]
examples:
- !ruby/object:Provider::Terraform::Examples
name: "privateca_capool_basic"
primary_resource_name: "fmt.Sprintf(\"tf-test-my-pool%s\", context[\"random_suffix\"])"
primary_resource_id: "default"
vars:
name: "my-pool"
- !ruby/object:Provider::Terraform::Examples
name: "privateca_capool_all_fields"
primary_resource_id: "default"
vars:
name: "my-pool"

11 changes: 0 additions & 11 deletions mmv1/templates/terraform/constants/certificate_authority.go.erb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
config := googleProviderConfig(t)

url, err := replaceVarsForTest(config, rs, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates/{{name}}")
url, err := replaceVarsForTest(config, rs, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/caPools/{{pool}}/certificates/{{name}}")

if err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
config := googleProviderConfig(t)

url, err := replaceVarsForTest(config, rs, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority_id}}")
url, err := replaceVarsForTest(config, rs, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/caPools/{{pool}}/certificateAuthorities/{{certificate_authority_id}}")
if err != nil {
return err
}
Expand All @@ -10,6 +10,6 @@ if err != nil {
return nil
}

if s := res["state"]; s != "PENDING_DELETION" {
return fmt.Errorf("CertificateAuthority %s got %s, want PENDING_DELETION", url, s)
if s := res["state"]; s != "DELETED" {
return fmt.Errorf("CertificateAuthority %s got %s, want DELETED", url, s)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<%# See mmv1/third_party/terraform/utils/privateca_utils.go for the sub-expanders and explanation %>
func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
v = make(map[string]interface{})
}
original := v.(map[string]interface{})
transformed := make(map[string]interface{})
transformed["additional_extensions"] =
flattenPrivatecaCertificateConfigX509ConfigAdditionalExtensions(original["additionalExtensions"], d, config)
transformed["policy_ids"] =
flattenPrivatecaCertificateConfigX509ConfigPolicyIds(original["policyIds"], d, config)
transformed["aia_ocsp_servers"] = flattenPrivatecaCertificateConfigX509ConfigAiaOcspServers(original["aiaOcspServers"], d, config)
transformed["ca_options"] =
flattenPrivatecaCertificateConfigX509ConfigCaOptions(original["caOptions"], d, config)
transformed["key_usage"] =
flattenPrivatecaCertificateConfigX509ConfigKeyUsage(original["keyUsage"], d, config)
return []interface{}{transformed}
}
13 changes: 0 additions & 13 deletions mmv1/templates/terraform/encoders/certificate_authority.go.erb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
resource "google_privateca_ca_pool" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]["name"] %>"
location = "us-central1"
tier = "ENTERPRISE"
publishing_options {
publish_ca_cert = false
publish_crl = true
}
labels = {
foo = "bar"
}
issuance_policy {
allowed_key_types {
elliptic_curve {
signature_algorithm = "ECDSA_P256"
}
}
allowed_key_types {
rsa {
min_modulus_size = 5
max_modulus_size = 10
}
}
maximum_lifetime = "50000s"
allowed_issuance_modes {
allow_csr_based_issuance = true
allow_config_based_issuance = true
}
identity_constraints {
allow_subject_passthrough = true
allow_subject_alt_names_passthrough = true
cel_expression {
expression = "subject_alt_names.all(san, san.type == DNS || san.type == EMAIL )"
title = "My title"
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no passthrough_extensions?

baseline_values {
aia_ocsp_servers = ["example.com"]
additional_extensions {
critical = true
value = "asdf"
object_id {
object_id_path = [123, 899]
}
}
policy_ids {
object_id_path = [123, 888]
}
policy_ids {
object_id_path = [456, 120]
}
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 = false
crl_sign = true
decipher_only = true
}
extended_key_usage {
server_auth = true
client_auth = false
email_protection = true
code_signing = true
time_stamping = true
}
}
}
}
}
12 changes: 12 additions & 0 deletions mmv1/templates/terraform/examples/privateca_capool_basic.tf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
resource "google_privateca_ca_pool" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]["name"] %>"
location = "us-central1"
tier = "ENTERPRISE"
publishing_options {
publish_ca_cert = true
publish_crl = true
}
labels = {
foo = "bar"
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,47 @@
resource "google_privateca_certificate_authority" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta
// This example assumes this pool already exists.
// Pools cannot be deleted in normal test circumstances, so we depend on static pools
pool = "<%= ctx[:vars]["pool"] %>"
certificate_authority_id = "<%= ctx[:vars]["certificate_authority_id"] %>"
location = "us-central1"
config {
subject_config {
subject {
organization = "HashiCorp"
common_name = "my-certificate-authority"
}
common_name = "my-certificate-authority"
subject_alt_name {
dns_names = ["hashicorp.com"]
}
}
reusable_config {
reusable_config = "projects/568668481468/locations/us-central1/reusableConfigs/root-unconstrained"
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"
}
disable_on_delete = true
}
Loading