Skip to content

Commit 3cca7aa

Browse files
authored
Support sub-CA to be activated into staged state (#12162)
1 parent e3afb57 commit 3cca7aa

File tree

3 files changed

+164
-4
lines changed

3 files changed

+164
-4
lines changed

mmv1/templates/terraform/constants/privateca_certificate_authority.go.tmpl

-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ func resourcePrivateCaCACustomDiff(_ context.Context, diff *schema.ResourceDiff,
33
_, new := diff.GetChange("desired_state")
44

55
if tpgresource.IsNewResource(diff) {
6-
if diff.Get("type").(string) == "SUBORDINATE" {
7-
return fmt.Errorf("`desired_state` can not be specified when creating a SUBORDINATE CA")
8-
}
96
if new.(string) != "STAGED" && new.(string) != "ENABLED" {
107
return fmt.Errorf("`desired_state` can only be set to `STAGED` or `ENABLED` when creating a new CA")
118
}

mmv1/templates/terraform/post_create/privateca_certificate_authority.go.tmpl

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ if d.Get("type").(string) == "SUBORDINATE" {
1515

1616
// Enable the CA if `desired_state` is unspecified or specified as `ENABLED`.
1717
if p, ok := d.GetOk("desired_state"); !ok || p.(string) == "ENABLED" {
18-
// Skip enablement on SUBORDINATE CA for backward compatible.
1918
if staged {
2019
if err := enableCA(config, d, project, billingProject, userAgent); err != nil {
2120
return fmt.Errorf("Error enabling CertificateAuthority: %v", err)

mmv1/third_party/terraform/services/privateca/resource_privateca_certificate_authority_test.go

+164
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,33 @@ func TestAccPrivatecaCertificateAuthority_subordinateCaActivatedByFirstPartyIssu
147147
})
148148
}
149149

150+
func TestAccPrivatecaCertificateAuthority_subordinateCaActivatedByFirstPartyIssuerOnCreationInStagedState(t *testing.T) {
151+
t.Parallel()
152+
acctest.SkipIfVcr(t)
153+
154+
random_suffix := acctest.RandString(t, 10)
155+
context := map[string]interface{}{
156+
"root_location": "us-central1",
157+
"sub_location": "australia-southeast1",
158+
"random_suffix": random_suffix,
159+
}
160+
161+
resourceName := "google_privateca_certificate_authority.sub-1"
162+
acctest.VcrTest(t, resource.TestCase{
163+
PreCheck: func() { acctest.AccTestPreCheck(t) },
164+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
165+
CheckDestroy: testAccCheckPrivatecaCertificateAuthorityDestroyProducer(t),
166+
Steps: []resource.TestStep{
167+
{
168+
Config: testAccPrivatecaCertificateAuthority_privatecaCertificateAuthoritySubordinateStagedWithFirstPartyIssuer(context),
169+
Check: resource.ComposeTestCheckFunc(
170+
resource.TestCheckResourceAttr(resourceName, "state", "STAGED"),
171+
),
172+
},
173+
},
174+
})
175+
}
176+
150177
func testAccPrivatecaCertificateAuthority_privatecaCertificateAuthorityBasicRoot(context map[string]interface{}) string {
151178
return acctest.Nprintf(`
152179
resource "google_privateca_certificate_authority" "default" {
@@ -448,3 +475,140 @@ resource "google_privateca_certificate_authority" "sub-1" {
448475
}
449476
`, context)
450477
}
478+
479+
// testAccPrivatecaCertificateAuthority_privatecaCertificateAuthoritySubordinateStagedWithFirstPartyIssuer provides a config
480+
// which contains
481+
// * A CaPool for root CA
482+
// * A root CA
483+
// * A CaPool for sub CA
484+
// * A subordinate CA which should be activated by the above root CA
485+
func testAccPrivatecaCertificateAuthority_privatecaCertificateAuthoritySubordinateStagedWithFirstPartyIssuer(context map[string]interface{}) string {
486+
return acctest.Nprintf(`
487+
resource "google_privateca_ca_pool" "root-pool" {
488+
name = "root-pool-%{random_suffix}"
489+
location = "%{root_location}"
490+
tier = "ENTERPRISE"
491+
publishing_options {
492+
publish_ca_cert = true
493+
publish_crl = true
494+
}
495+
}
496+
497+
resource "google_privateca_certificate_authority" "root-1" {
498+
pool = google_privateca_ca_pool.root-pool.name
499+
certificate_authority_id = "tf-test-my-certificate-authority-root-%{random_suffix}"
500+
location = "%{root_location}"
501+
config {
502+
subject_config {
503+
subject {
504+
organization = "HashiCorp"
505+
common_name = "my-certificate-authority"
506+
}
507+
subject_alt_name {
508+
dns_names = ["hashicorp.com"]
509+
}
510+
}
511+
x509_config {
512+
ca_options {
513+
is_ca = true
514+
max_issuer_path_length = 10
515+
}
516+
key_usage {
517+
base_key_usage {
518+
digital_signature = true
519+
content_commitment = true
520+
key_encipherment = false
521+
data_encipherment = true
522+
key_agreement = true
523+
cert_sign = true
524+
crl_sign = true
525+
decipher_only = true
526+
}
527+
extended_key_usage {
528+
server_auth = true
529+
client_auth = false
530+
email_protection = true
531+
code_signing = true
532+
time_stamping = true
533+
}
534+
}
535+
}
536+
}
537+
lifetime = "86400s"
538+
key_spec {
539+
algorithm = "RSA_PKCS1_4096_SHA256"
540+
}
541+
542+
// Disable CA deletion related safe checks for easier cleanup.
543+
deletion_protection = false
544+
skip_grace_period = true
545+
ignore_active_certificates_on_deletion = true
546+
}
547+
548+
resource "google_privateca_ca_pool" "sub-pool" {
549+
name = "sub-pool-%{random_suffix}"
550+
location = "%{sub_location}"
551+
tier = "ENTERPRISE"
552+
publishing_options {
553+
publish_ca_cert = true
554+
publish_crl = true
555+
}
556+
}
557+
558+
resource "google_privateca_certificate_authority" "sub-1" {
559+
pool = google_privateca_ca_pool.sub-pool.name
560+
certificate_authority_id = "tf-test-my-certificate-authority-sub-%{random_suffix}"
561+
location = "%{sub_location}"
562+
desired_state = "STAGED"
563+
subordinate_config {
564+
certificate_authority = google_privateca_certificate_authority.root-1.name
565+
}
566+
config {
567+
subject_config {
568+
subject {
569+
organization = "HashiCorp"
570+
common_name = "my-certificate-authority"
571+
}
572+
subject_alt_name {
573+
dns_names = ["hashicorp.com"]
574+
}
575+
}
576+
x509_config {
577+
ca_options {
578+
is_ca = true
579+
max_issuer_path_length = 10
580+
}
581+
key_usage {
582+
base_key_usage {
583+
digital_signature = true
584+
content_commitment = true
585+
key_encipherment = false
586+
data_encipherment = true
587+
key_agreement = true
588+
cert_sign = true
589+
crl_sign = true
590+
decipher_only = true
591+
}
592+
extended_key_usage {
593+
server_auth = true
594+
client_auth = false
595+
email_protection = true
596+
code_signing = true
597+
time_stamping = true
598+
}
599+
}
600+
}
601+
}
602+
lifetime = "86400s"
603+
key_spec {
604+
algorithm = "RSA_PKCS1_4096_SHA256"
605+
}
606+
type = "SUBORDINATE"
607+
608+
// Disable CA deletion related safe checks for easier cleanup.
609+
deletion_protection = false
610+
skip_grace_period = true
611+
ignore_active_certificates_on_deletion = true
612+
}
613+
`, context)
614+
}

0 commit comments

Comments
 (0)