-
Notifications
You must be signed in to change notification settings - Fork 549
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
PKI: Add support for CPS URL in custom policy identifiers #1495
Conversation
Update the `vault_resource_pki_secret_backend_role` to support specifying the CPS URL when specifying policy identifiers in line with the recent changes to the PKI Secrets Engine in Vault 1.11: hashicorp/vault#15751 We do this by deprecating the existing `policy_identifiers` argument and creating a new block, `policy_identifier`, which can be specified multiple times. If both `policy_identifiers` and `policy_identifier` blocks are present, then `policy_identifier` is ignored. (Otherwise, refreshing would delete one or the other, and the state wouldn't have round trip stability.) This was also tested locally with, for example, a terraform file like: ```hcl provider "vault" { } resource "vault_mount" "pki" { path = "pki" type = "pki" default_lease_ttl_seconds = 3600 max_lease_ttl_seconds = 86400 } resource "vault_pki_secret_backend_role" "role" { name = "example-dot-com" backend = vault_mount.pki.path allowed_domains = ["example.com"] allow_subdomains = true allow_bare_domains = true allow_glob_domains = true allow_ip_sans = true allow_localhost = "true" generate_lease = true organization = ["Hashi test"] country = ["USA"] locality = ["Area 51"] province = ["NV"] max_ttl = "720h" policy_identifiers = ["2.5.29.32","1.2.3"] // or policy_identifier { oid = "2.5.29.32" cps = "https://example.com/cps" notice = "Some notice" } policy_identifier { oid = "1.2.3" } } ```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR is looking great! Had some comments/questions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! I left some initial feedback/suggestions.
@@ -79,7 +79,7 @@ The following arguments are supported: | |||
|
|||
* `email_protection_flag` - (Optional) Flag to specify certificates for email protection use | |||
|
|||
* `key_type` - (Optional) The generated key type, choices: `rsa`, `ec`, `ed25519`, `any` | |||
* `key_type` - (Optional) The generated key type, choices: `rsa`, `ec`, `ed25519`, `any` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the trailing double space denotes a line beak in Markdown. I think this was intentional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh. Weird. My text editor isn't going to like that :) I'll see if I can add it back.
vault/pki.go
Outdated
// into a list of strings (the OIDs) or the JSON serialization of the `policy_identifier` blocks, | ||
// respectively. | ||
func readPolicyIdentifiers(d *schema.ResourceData) interface{} { | ||
policyIdentifiersList := d.Get("policy_identifiers").([]interface{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we me make the two fields mutually exclusive by setting ConflictsWith
on their schema.Schema
, then we can update this function to only have to support the Set
type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
vault/pki.go
Outdated
@@ -0,0 +1,79 @@ | |||
package vault |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great if we could make this the beginning of a new package under internal/
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can do. I was mostly following the pattern I saw of other utilities, e.g., gcp.go
@@ -112,7 +112,14 @@ The following arguments are supported: | |||
|
|||
* `require_cn` - (Optional) Flag to force CN usage | |||
|
|||
* `policy_identifiers` - (Optional) Specify the list of allowed policies IODs | |||
* `policy_identifiers` - (Optional) Specify the list of allowed policies OIDs; Deprecated: use `policy_identifier` blocks instead |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe we have deprecated this field yet. We probably just want to say that it is used for Vault 1.10 and below, or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -12,6 +12,17 @@ import ( | |||
"github.com/hashicorp/terraform-provider-vault/testutil" | |||
) | |||
|
|||
var legacyPolicyIdentifiers = `policy_identifiers = ["1.2.3.4"]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the vault
project is already so massive, I'd suggest that we either move theses vars within the test's scope, or include test
in their names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
internal/pki.go
Outdated
@@ -0,0 +1,64 @@ | |||
package internal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be better to instead make this live under internal/pki
and call it something like package pki
. We did something similar for packages like internal/consts
and internal/identity/entity
. Importing might make things more explictly clear as well with things like pki.ReadPolicyIdentifierBlocks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 makes sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice update! I have a few more comments/suggestions.
internal/pki.go
Outdated
@@ -0,0 +1,64 @@ | |||
package internal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, I was thinking more of moving this code to a package called pki
under internal/
, sorry if I wasn't clear.
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "policy_identifier.*", map[string]string{"oid": "1.2.3.4.5.6"}), | ||
)..., | ||
), | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to add an import
TestStep
after each Config
step. This will ensure that a terraform import
will work.
Similar to:
{ | |
ResourceName: resourcePath, | |
ImportState: true, | |
ImportStateVerify: true, | |
ImportStateVerifyIgnore: importIgnoreKeys, | |
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
policyIdentifiers := make([]string, 0, len(iPolicyIdentifiers)) | ||
for _, iIdentifier := range iPolicyIdentifiers { | ||
policyIdentifiers = append(policyIdentifiers, iIdentifier.(string)) | ||
legacyPolicyIdentifiers, newPolicyIdentifiers, err := internal.MakePkiPolicyIdentifiersListOrSet(secret.Data["policy_identifiers"].([]interface{})) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might panic here on the type assertion in the case of a value other than []interface{}
. We probably want to call MakePkiPolicyIdentifiersListOrSet()
conditionally when policy_identifiers
in the resp.Data
, and guard against the type assert panic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -413,8 +439,10 @@ func pkiSecretBackendRoleCreate(d *schema.ResourceData, meta interface{}) error | |||
data["ext_key_usage"] = extKeyUsage | |||
} | |||
|
|||
if len(policyIdentifiers) > 0 { | |||
data["policy_identifiers"] = policyIdentifiers | |||
if len(policyIdentifiersList) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think calling d.GetOk()
on each field would probably do the same, and then we could avoid the extra variable assignments above.
policyIdentifiersList := d.Get("policy_identifiers").([]interface{}) | ||
policyIdentifierBlocks := internal.ReadPolicyIdentifierBlocks(d.Get("policy_identifier").(*schema.Set)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can probably drop these with the suggestion below.
policyIdentifiersList := d.Get("policy_identifiers").([]interface{}) | |
policyIdentifierBlocks := internal.ReadPolicyIdentifierBlocks(d.Get("policy_identifier").(*schema.Set)) |
if len(policyIdentifiersList) > 0 { | ||
data["policy_identifiers"] = policyIdentifiersList | ||
} else if policyIdentifierBlocks != "" { | ||
data["policy_identifiers"] = policyIdentifierBlocks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same suggestion as in the Read()
method. Ideally we would merge the two and rely on d.HasChange()
, but I think that is probably out of scope for this PR.
if len(policyIdentifiersList) > 0 { | |
data["policy_identifiers"] = policyIdentifiersList | |
} else if policyIdentifierBlocks != "" { | |
data["policy_identifiers"] = policyIdentifierBlocks | |
if v, ok := d.GetOk("policy_identifiers"); ok { | |
data["policy_identifiers"] = v | |
} else if v, ok := d.GetOk("policy_identifier"); ok { | |
data["policy_identifiers"] = internal.ReadPolicyIdentifierBlocks(v.(*schema.Set)) | |
} |
policyIdentifiersList := d.Get("policy_identifiers").([]interface{}) | ||
policyIdentifierBlocks := internal.ReadPolicyIdentifierBlocks(d.Get("policy_identifier").(*schema.Set)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
policyIdentifiersList := d.Get("policy_identifiers").([]interface{}) | |
policyIdentifierBlocks := internal.ReadPolicyIdentifierBlocks(d.Get("policy_identifier").(*schema.Set)) |
* `policy_identifiers` - (Optional) Specify the list of allowed policies IODs | ||
* `policy_identifiers` - (Optional) Specify the list of allowed policies OIDs. Use with Vault 1.10 or before. For Vault 1.11+, use `policy_identifier` blocks instead | ||
|
||
* `policy_identifier` - (Optional) (Vault 1.11+ only) A block for specifying policy identifers. The `policy_identifier` block can be repeated, and supports the following arguments: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth adding a new example for this new feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
)..., | ||
), | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want test that the two fields are mutually exclusive by adding a ExpectError
TestStep
similar to:
terraform-provider-vault/vault/data_source_gcp_auth_backend_role_test.go
Lines 99 to 104 in 70a1872
{ | |
Config: testAccGCPAuthBackendRoleDataSourceConfig(backend, name), | |
ExpectError: regexp.MustCompile( | |
fmt.Sprintf("role not found at %q", gcpRoleResourcePath(backend, name)), | |
), | |
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, perfect. I had wanted to do that, but didn't quite know how. That helps.
@@ -9,7 +9,7 @@ import ( | |||
|
|||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | |||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" | |||
|
|||
"github.com/hashicorp/terraform-provider-vault/internal/pki" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Thanks for all of the helpful feedback! |
…1495) PKI: Add support for CPS URL in custom policy identifiers Update the `vault_resource_pki_secret_backend_role` to support specifying the CPS URL when specifying policy identifiers in line with the recent changes to the PKI Secrets Engine in Vault 1.11: hashicorp/vault#15751 We do this by deprecating the existing `policy_identifiers` argument and creating a new block, `policy_identifier`, which can be specified multiple times. If both `policy_identifiers` and `policy_identifier` blocks are present, then `policy_identifier` is ignored. (Otherwise, refreshing would delete one or the other, and the state wouldn't have round trip stability.) This was also tested locally with, for example, a terraform file like: ```hcl provider "vault" { } resource "vault_mount" "pki" { path = "pki" type = "pki" default_lease_ttl_seconds = 3600 max_lease_ttl_seconds = 86400 } resource "vault_pki_secret_backend_role" "role" { name = "example-dot-com" backend = vault_mount.pki.path allowed_domains = ["example.com"] allow_subdomains = true allow_bare_domains = true allow_glob_domains = true allow_ip_sans = true allow_localhost = "true" generate_lease = true organization = ["Hashi test"] country = ["USA"] locality = ["Area 51"] province = ["NV"] max_ttl = "720h" policy_identifiers = ["2.5.29.32","1.2.3"] // or policy_identifier { oid = "2.5.29.32" cps = "https://example.com/cps" notice = "Some notice" } policy_identifier { oid = "1.2.3" } } ```
Update the
vault_resource_pki_secret_backend_role
to supportspecifying the CPS URL when specifying policy identifiers in line with
the recent changes to the PKI Secrets Engine in Vault 1.11:
hashicorp/vault#15751
We do this by deprecating the existing
policy_identifiers
argument andcreating a new block,
policy_identifier
, which can be specifiedmultiple times.
If both
policy_identifiers
andpolicy_identifier
blocks are present,then
policy_identifier
is ignored. (Otherwise, refreshing would deleteone or the other, and the state wouldn't have round trip stability.)
This was also tested locally with, for example, a terraform file like:
Community Note
Release note for CHANGELOG:
Output from acceptance testing: