Skip to content

Commit 1e82786

Browse files
Private CA - Differentiate unset and default values for is_ca/max_issuer_path_length in Certificate Templates (#14070) (#22981)
[upstream:894dcc3caac54d3cffcc9192ee06bce929409db2] Signed-off-by: Modular Magician <[email protected]>
1 parent 36be55e commit 1e82786

7 files changed

+874
-666
lines changed

.changelog/14070.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
privateca: added support for setting default values for basic constraints for `google_privateca_certificate_template` via the `null_ca` and `zero_max_issuer_path_length` fields. also added `name_constraints` field for `google_privateca_certificate_template`.
3+
```

google/services/privateca/privateca_utils.go

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ import (
2424
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
2525
)
2626

27-
// This file contains shared flatteners between PrivateCA Certificate, CaPool and CertificateAuthority.
28-
// These resources share the x509Config (Certificate, CertificateAuthorty)/baselineValues (CaPool) object.
27+
// This file contains shared flatteners between PrivateCA Certificate, CaPool, CertificateTemplate and
28+
// CertificateAuthority. These resources share the x509Config (Certificate, CertificateAuthority)/
29+
// baselineValues (CaPool) object. CertificateTemplate contains the predefinedValues object, which is slightly
30+
// different from the other two, and so requires its own functions to process. These functions are also contained
31+
// in this file.
32+
//
2933
// The API does not return this object if it only contains booleans with the default (false) value. This
3034
// causes problems if a user specifies only default values, as Terraform detects that the object has been
3135
// deleted on the API-side. This flattener creates default objects for sub-objects that match this pattern
@@ -80,6 +84,50 @@ func expandPrivatecaCertificateConfigX509ConfigCaOptions(v interface{}, d tpgres
8084
return transformed, nil
8185
}
8286

87+
func expandPrivatecaCertificateTemplateConfigX509ConfigCaOptions(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
88+
// Similar to expandPrivatecaCertificateConfigX509ConfigCaOptions, but only for use in
89+
// Certificate Templates, which use a null_ca field instead of the non_ca field.
90+
// Fields null_ca, zero_max_issuer_path_length are used to distinguish between
91+
// unset booleans and booleans set with a default value.
92+
// Unset is_ca or unset max_issuer_path_length either allow any values for these fields when
93+
// used in an issuance policy, or allow the API to use default values when used in a
94+
// certificate config. A default value of is_ca=false means that issued certificates cannot
95+
// be CA certificates. A default value of max_issuer_path_length=0 means that the CA cannot
96+
// issue CA certificates.
97+
if v == nil {
98+
return nil, nil
99+
}
100+
l := v.([]interface{})
101+
if len(l) == 0 || l[0] == nil {
102+
return nil, nil
103+
}
104+
raw := l[0]
105+
original := raw.(map[string]interface{})
106+
107+
nullCa := original["null_ca"].(bool)
108+
isCa := original["is_ca"].(bool)
109+
110+
zeroPathLength := original["zero_max_issuer_path_length"].(bool)
111+
maxIssuerPathLength := original["max_issuer_path_length"].(int)
112+
113+
transformed := make(map[string]interface{})
114+
115+
if nullCa && isCa {
116+
return nil, fmt.Errorf("null_ca, is_ca can not be set to true at the same time.")
117+
}
118+
if zeroPathLength && maxIssuerPathLength > 0 {
119+
return nil, fmt.Errorf("zero_max_issuer_path_length can not be set to true while max_issuer_path_length being set to a positive integer.")
120+
}
121+
122+
if !nullCa {
123+
transformed["isCa"] = original["is_ca"]
124+
}
125+
if maxIssuerPathLength > 0 || zeroPathLength {
126+
transformed["maxIssuerPathLength"] = original["max_issuer_path_length"]
127+
}
128+
return transformed, nil
129+
}
130+
83131
func expandPrivatecaCertificateConfigX509ConfigKeyUsage(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
84132
if v == nil {
85133
return v, nil
@@ -377,6 +425,33 @@ func flattenPrivatecaCertificateConfigX509ConfigCaOptions(v interface{}, d *sche
377425

378426
return []interface{}{transformed}
379427
}
428+
429+
func flattenPrivatecaCertificateTemplateConfigX509ConfigCaOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
430+
// Special case here as the CaPool API returns an empty object rather than nil unlike the Certificate
431+
// and CertificateAuthority APIs.
432+
if v == nil || len(v.(map[string]interface{})) == 0 {
433+
v = make(map[string]interface{})
434+
}
435+
original := v.(map[string]interface{})
436+
transformed := make(map[string]interface{})
437+
438+
val, exists := original["isCa"]
439+
transformed["is_ca"] =
440+
flattenPrivatecaCertificateConfigX509ConfigCaOptionsIsCa(val, d, config)
441+
if !exists {
442+
transformed["null_ca"] = true
443+
}
444+
445+
val, exists = original["maxIssuerPathLength"]
446+
transformed["max_issuer_path_length"] =
447+
flattenPrivatecaCertificateConfigX509ConfigCaOptionsMaxIssuerPathLength(val, d, config)
448+
if exists && int(val.(float64)) == 0 {
449+
transformed["zero_max_issuer_path_length"] = true
450+
}
451+
452+
return []interface{}{transformed}
453+
}
454+
380455
func flattenPrivatecaCertificateConfigX509ConfigCaOptionsIsCa(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
381456
return v
382457
}

0 commit comments

Comments
 (0)