Skip to content

Commit

Permalink
feat: add support for allowed_kubernetes_namespace_selector in `vau…
Browse files Browse the repository at this point in the history
…lt_kubernetes_secret_backend_role`
  • Loading branch information
alfredkrohmer committed Mar 21, 2024
1 parent 7325966 commit 31776fa
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Unreleased

* Add support for `allowed_kubernetes_namespace_selector` in `vault_kubernetes_secret_backend_role` ([#2180](https://github.com/hashicorp/terraform-provider-vault/pull/2180)).

## 4.1.0 (Mar 20, 2024)

CHANGES TO VAULT POLICY REQUIREMENTS:
Expand Down
44 changes: 32 additions & 12 deletions vault/resource_kubernetes_secret_backend_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ import (
var kubernetesSecretBackendFromPathRegex = regexp.MustCompile("^(.+)/roles/.+$")

const (
fieldAllowedKubernetesNamespaces = "allowed_kubernetes_namespaces"
fieldTokenMaxTTL = "token_max_ttl"
fieldTokenDefaultTTL = "token_default_ttl"
fieldServiceAccountName = "service_account_name"
fieldKubernetesRoleName = "kubernetes_role_name"
fieldKubernetesRoleType = "kubernetes_role_type"
fieldGeneratedRoleRules = "generated_role_rules"
fieldNameTemplate = "name_template"
fieldExtraAnnotations = "extra_annotations"
fieldExtraLabels = "extra_labels"
fieldAllowedKubernetesNamespaces = "allowed_kubernetes_namespaces"
fieldAllowedKubernetesNamespaceSelector = "allowed_kubernetes_namespace_selector"
fieldTokenMaxTTL = "token_max_ttl"
fieldTokenDefaultTTL = "token_default_ttl"
fieldServiceAccountName = "service_account_name"
fieldKubernetesRoleName = "kubernetes_role_name"
fieldKubernetesRoleType = "kubernetes_role_type"
fieldGeneratedRoleRules = "generated_role_rules"
fieldNameTemplate = "name_template"
fieldExtraAnnotations = "extra_annotations"
fieldExtraLabels = "extra_labels"
)

func kubernetesSecretBackendRoleResource() *schema.Resource {
Expand Down Expand Up @@ -63,8 +64,19 @@ func kubernetesSecretBackendRoleResource() *schema.Resource {
Type: schema.TypeString,
},
Description: "The list of Kubernetes namespaces this role can generate " +
"credentials for. If set to '*' all namespaces are allowed.",
Required: true,
"credentials for. If set to '*' all namespaces are allowed. If set with" +
"`allowed_kubernetes_namespace_selector`, the conditions are `OR`ed.",
Optional: true,
},
fieldAllowedKubernetesNamespaceSelector: {
Type: schema.TypeString,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "A label selector for Kubernetes namespaces in which credentials can be" +
"generated. Accepts either a JSON or YAML object. The value should be of type" +
"LabelSelector. If set with `allowed_kubernetes_namespace`, the conditions are `OR`ed.",
Optional: true,
},
fieldTokenMaxTTL: {
Type: schema.TypeInt,
Expand Down Expand Up @@ -143,6 +155,7 @@ func kubernetesSecretBackendRoleCreateUpdate(ctx context.Context, d *schema.Reso
data := make(map[string]interface{})
fields := []string{
fieldAllowedKubernetesNamespaces,
fieldAllowedKubernetesNamespaceSelector,
fieldTokenMaxTTL,
fieldTokenDefaultTTL,
fieldServiceAccountName,
Expand All @@ -154,6 +167,9 @@ func kubernetesSecretBackendRoleCreateUpdate(ctx context.Context, d *schema.Reso
fieldExtraLabels,
}
for _, k := range fields {
if k == fieldAllowedKubernetesNamespaceSelector && !provider.IsAPISupported(meta, provider.VaultVersion112) {
continue
}
if d.HasChange(k) {
data[k] = d.Get(k)
}
Expand Down Expand Up @@ -200,6 +216,7 @@ func kubernetesSecretBackendRoleRead(_ context.Context, d *schema.ResourceData,
fields := []string{
consts.FieldName,
fieldAllowedKubernetesNamespaces,
fieldAllowedKubernetesNamespaceSelector,
fieldTokenMaxTTL,
fieldTokenDefaultTTL,
fieldServiceAccountName,
Expand All @@ -211,6 +228,9 @@ func kubernetesSecretBackendRoleRead(_ context.Context, d *schema.ResourceData,
fieldExtraLabels,
}
for _, k := range fields {
if k == fieldAllowedKubernetesNamespaceSelector && !provider.IsAPISupported(meta, provider.VaultVersion112) {
continue
}
if err := d.Set(k, resp.Data[k]); err != nil {
return diag.Errorf("error setting state key %q on Kubernetes backend role, err=%s",
k, err)
Expand Down
35 changes: 35 additions & 0 deletions vault/resource_kubernetes_secret_backend_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,26 @@ func TestAccKubernetesSecretBackendRole(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, fieldExtraAnnotations+".%", "0"),
),
},
{
SkipFunc: func() (bool, error) {
meta := testProvider.Meta().(*provider.ProviderMeta)
return !meta.IsAPISupported(provider.VaultVersion112), nil
},
Config: testKubernetesSecretBackendRole_UpdateConfig3(backend, name),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, consts.FieldBackend, backend),
resource.TestCheckResourceAttr(resourceName, consts.FieldName, name),
resource.TestCheckResourceAttr(resourceName, fieldAllowedKubernetesNamespaceSelector, "{\"matchLabels\":{\"team\":\"hades\"}}"),
resource.TestCheckResourceAttr(resourceName, fieldGeneratedRoleRules, ""),
resource.TestCheckResourceAttr(resourceName, fieldServiceAccountName, ""),
resource.TestCheckResourceAttr(resourceName, fieldKubernetesRoleType, "Role"),
resource.TestCheckResourceAttr(resourceName, fieldKubernetesRoleName, "existing_role"),
resource.TestCheckResourceAttr(resourceName, fieldTokenMaxTTL, "0"),
resource.TestCheckResourceAttr(resourceName, fieldTokenDefaultTTL, "0"),
resource.TestCheckResourceAttr(resourceName, fieldExtraLabels+".%", "0"),
resource.TestCheckResourceAttr(resourceName, fieldExtraAnnotations+".%", "0"),
),
},
{
ResourceName: resourceName,
ImportState: true,
Expand Down Expand Up @@ -169,3 +189,18 @@ resource "vault_kubernetes_secret_backend_role" "test" {
}
`, backend, name)
}

func testKubernetesSecretBackendRole_UpdateConfig3(backend, name string) string {
return fmt.Sprintf(`
resource "vault_kubernetes_secret_backend" "backend" {
path = "%s"
}
resource "vault_kubernetes_secret_backend_role" "test" {
backend = vault_kubernetes_secret_backend.backend.path
name = "%s"
allowed_kubernetes_namespace_selector = "{\"matchLabels\":{\"team\":\"hades\"}}"
kubernetes_role_name = "existing_role"
}
`, backend, name)
}
10 changes: 8 additions & 2 deletions website/docs/r/kubernetes_secret_backend_role.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,14 @@ The following arguments are supported:
* `backend` - (Required) The path of the Kubernetes Secrets Engine backend mount to create
the role in.

* `allowed_kubernetes_namespaces` - (Required) The list of Kubernetes namespaces this role
can generate credentials for. If set to `*` all namespaces are allowed.
* `allowed_kubernetes_namespaces` - (Optional) The list of Kubernetes namespaces this role
can generate credentials for. If set to `*` all namespaces are allowed. If set with
`allowed_kubernetes_namespace_selector`, the conditions are `OR`ed.

* `allowed_kubernetes_namespace_selector` - (Optional) A label selector for Kubernetes namespaces
in which credentials can be generated. Accepts either a JSON or YAML object. The value should be
of type [LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#labelselector-v1-meta).
If set with `allowed_kubernetes_namespace`, the conditions are `OR`ed.

* `token_max_ttl` - (Optional) The maximum TTL for generated Kubernetes tokens in seconds.

Expand Down

0 comments on commit 31776fa

Please sign in to comment.