From a659f2c105c25b6bcc140c22974d7476aa18442b Mon Sep 17 00:00:00 2001 From: Willian Mori <81596542+wmrmrx@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:50:26 -0300 Subject: [PATCH 01/11] db/cassandra: Add support for skip_verification config (#2346) * db/cassandra: Add support for skip_verification config * Update CHANGELOG.md * Add missing test * Add skip_verification to getConnectionDetailsCassandra --- CHANGELOG.md | 1 + vault/resource_database_secret_backend_connection.go | 12 ++++++++++++ ...source_database_secret_backend_connection_test.go | 2 ++ website/docs/r/database_secret_backend_connection.md | 3 +++ 4 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 333e48db9..7f8fb072b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ FEATURES: * Update `vault_database_secret_backend_connection` to support inline TLS config for PostgreSQL ([#2339](https://github.com/hashicorp/terraform-provider-vault/pull/2339)) +* Update `vault_database_secret_backend_connection` to support skip_verification config for Cassandra ([#2346](https://github.com/hashicorp/terraform-provider-vault/pull/2346)) ## 4.4.0 (Aug 7, 2024) diff --git a/vault/resource_database_secret_backend_connection.go b/vault/resource_database_secret_backend_connection.go index 48680e0b6..8159b3741 100644 --- a/vault/resource_database_secret_backend_connection.go +++ b/vault/resource_database_secret_backend_connection.go @@ -335,6 +335,12 @@ func getDatabaseSchema(typ schema.ValueType) schemaMap { Default: 5, Description: "The number of seconds to use as a connection timeout.", }, + "skip_verification": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Skip permissions checks when a connection to Cassandra is first created. These checks ensure that Vault is able to create roles, but can be resource intensive in clusters with many roles.", + }, }, }, MaxItems: 1, @@ -1041,6 +1047,9 @@ func setCassandraDatabaseConnectionData(d *schema.ResourceData, prefix string, d if v, ok := d.GetOkExists(prefix + "connect_timeout"); ok { data["connect_timeout"] = v.(int) } + if v, ok := d.GetOkExists(prefix + "skip_verification"); ok { + data["skip_verification"] = v.(bool) + } } func getConnectionDetailsFromResponse(d *schema.ResourceData, prefix string, resp *api.Secret) map[string]interface{} { @@ -2070,6 +2079,9 @@ func getConnectionDetailsCassandra(d *schema.ResourceData, prefix string, resp * } result["connect_timeout"] = timeout } + if v, ok := data["skip_verification"]; ok { + result["skip_verification"] = v.(bool) + } return result, nil } return nil, nil diff --git a/vault/resource_database_secret_backend_connection_test.go b/vault/resource_database_secret_backend_connection_test.go index c487f8aa3..6c9a579e2 100644 --- a/vault/resource_database_secret_backend_connection_test.go +++ b/vault/resource_database_secret_backend_connection_test.go @@ -116,6 +116,7 @@ func TestAccDatabaseSecretBackendConnection_cassandra(t *testing.T) { resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "cassandra.0.pem_json", ""), resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "cassandra.0.protocol_version", "4"), resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "cassandra.0.connect_timeout", "5"), + resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "cassandra.0.skip_verification", "false"), ), }, }, @@ -159,6 +160,7 @@ func TestAccDatabaseSecretBackendConnection_cassandraProtocol(t *testing.T) { resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "cassandra.0.pem_json", ""), resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "cassandra.0.protocol_version", "5"), resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "cassandra.0.connect_timeout", "5"), + resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "cassandra.0.skip_verification", "false"), ), }, }, diff --git a/website/docs/r/database_secret_backend_connection.md b/website/docs/r/database_secret_backend_connection.md index b3d364fec..769f96c6a 100644 --- a/website/docs/r/database_secret_backend_connection.md +++ b/website/docs/r/database_secret_backend_connection.md @@ -124,6 +124,9 @@ Exactly one of the nested blocks of configuration options must be supplied. * `connect_timeout` - (Optional) The number of seconds to use as a connection timeout. +* `skip_verification` - (Optional) Skip permissions checks when a connection to Cassandra is first created. + These checks ensure that Vault is able to create roles, but can be resource intensive in clusters with many roles. + ### Couchbase Configuration Options * `hosts` - (Required) A set of Couchbase URIs to connect to. Must use `couchbases://` scheme if `tls` is `true`. From 3f3edeb25e730dd13e1636d8f9b61a574ebb0baf Mon Sep 17 00:00:00 2001 From: NightOwl998 <64656757+NightOwl998@users.noreply.github.com> Date: Wed, 30 Oct 2024 16:44:13 +0100 Subject: [PATCH 02/11] Enhance secret by adding num_uses and ttl for vault_approle_auth_backend_role_secret_id (#2345) * add num_uses & ttl to secre_id resource * fixed tests * fix up * make fmt and add changelog * fmt --------- Co-authored-by: JM Faircloth --- CHANGELOG.md | 1 + ...rce_approle_auth_backend_role_secret_id.go | 29 +++++++++++++++++++ ...pprole_auth_backend_role_secret_id_test.go | 4 +++ 3 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f8fb072b..67f660572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ FEATURES: * Update `vault_database_secret_backend_connection` to support inline TLS config for PostgreSQL ([#2339](https://github.com/hashicorp/terraform-provider-vault/pull/2339)) * Update `vault_database_secret_backend_connection` to support skip_verification config for Cassandra ([#2346](https://github.com/hashicorp/terraform-provider-vault/pull/2346)) +* Update `vault_approle_auth_backend_role_secret_id` to support `num_uses` and `ttl` fields ([#2345](https://github.com/hashicorp/terraform-provider-vault/pull/2345)) ## 4.4.0 (Aug 7, 2024) diff --git a/vault/resource_approle_auth_backend_role_secret_id.go b/vault/resource_approle_auth_backend_role_secret_id.go index 6afd5b0af..cf465af21 100644 --- a/vault/resource_approle_auth_backend_role_secret_id.go +++ b/vault/resource_approle_auth_backend_role_secret_id.go @@ -72,6 +72,22 @@ func approleAuthBackendRoleSecretIDResource(name string) *schema.Resource { }, }, + consts.FieldTTL: { + Type: schema.TypeInt, + Required: false, + Optional: true, + ForceNew: true, + Description: "The TTL duration of the SecretID.", + }, + + consts.FieldNumUses: { + Type: schema.TypeInt, + Required: false, + Optional: true, + ForceNew: true, + Description: "The number of uses for the secret-id.", + }, + consts.FieldBackend: { Type: schema.TypeString, Optional: true, @@ -162,6 +178,14 @@ func approleAuthBackendRoleSecretIDCreate(ctx context.Context, d *schema.Resourc } else { data["metadata"] = "" } + + if v, ok := d.GetOk(consts.FieldTTL); ok { + data["ttl"] = v + } + + if v, ok := d.GetOk(consts.FieldNumUses); ok { + data["num_uses"] = v + } withWrappedAccessor := d.Get(consts.FieldWithWrappedAccessor).(bool) wrappingTTL, wrapped := d.GetOk(consts.FieldWrappingTTL) @@ -293,12 +317,17 @@ func approleAuthBackendRoleSecretIDRead(ctx context.Context, d *schema.ResourceD return diag.Errorf("error encoding metadata for SecretID %q to JSON: %s", id, err) } + ttl := resp.Data["secret_id_ttl"] + numUses := resp.Data["secret_id_num_uses"] + fields := map[string]interface{}{ consts.FieldBackend: backend, consts.FieldRoleName: role, consts.FieldCIDRList: cidrs, consts.FieldMetadata: string(metadata), consts.FieldAccessor: accessor, + consts.FieldTTL: ttl, + consts.FieldNumUses: numUses, } for k, v := range fields { diff --git a/vault/resource_approle_auth_backend_role_secret_id_test.go b/vault/resource_approle_auth_backend_role_secret_id_test.go index f3a865d7e..6d390bb73 100644 --- a/vault/resource_approle_auth_backend_role_secret_id_test.go +++ b/vault/resource_approle_auth_backend_role_secret_id_test.go @@ -190,6 +190,8 @@ func TestAccAppRoleAuthBackendRoleSecretID_full(t *testing.T) { resource.TestCheckResourceAttrSet(secretIDResource, "accessor"), resource.TestCheckResourceAttr(secretIDResource, "cidr_list.#", "2"), resource.TestCheckResourceAttr(secretIDResource, consts.FieldMetadata, `{"hello":"world"}`), + resource.TestCheckResourceAttr(secretIDResource, "ttl", "700"), + resource.TestCheckResourceAttr(secretIDResource, "num_uses", "2"), ), }, }, @@ -254,6 +256,8 @@ resource "vault_approle_auth_backend_role_secret_id" "secret_id" { role_name = vault_approle_auth_backend_role.role.role_name backend = vault_auth_backend.approle.path cidr_list = ["10.148.0.0/20", "10.150.0.0/20"] + ttl = 700 + num_uses = 2 metadata = < Date: Mon, 4 Nov 2024 11:31:29 -0600 Subject: [PATCH 03/11] auth/kubernetes: add support for use_annotations_as_alias_metadata field (#2226) * auth/kubernetes: add support for use_annotations_as_alias_metadata field * changelog * update data source and docs * add version check to tests --- CHANGELOG.md | 1 + ...a_source_kubernetes_auth_backend_config.go | 13 +++++ ...rce_kubernetes_auth_backend_config_test.go | 13 +++++ ...resource_kubernetes_auth_backend_config.go | 25 +++++++++ ...rce_kubernetes_auth_backend_config_test.go | 54 ++++++++++++------- .../docs/d/kubernetes_auth_backend_config.md | 6 +++ .../docs/r/kubernetes_auth_backend_config.md | 2 + 7 files changed, 96 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67f660572..5a77fae27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ FEATURES: * Update `vault_database_secret_backend_connection` to support inline TLS config for PostgreSQL ([#2339](https://github.com/hashicorp/terraform-provider-vault/pull/2339)) * Update `vault_database_secret_backend_connection` to support skip_verification config for Cassandra ([#2346](https://github.com/hashicorp/terraform-provider-vault/pull/2346)) * Update `vault_approle_auth_backend_role_secret_id` to support `num_uses` and `ttl` fields ([#2345](https://github.com/hashicorp/terraform-provider-vault/pull/2345)) +* Add support for `use_annotations_as_alias_metadata` field for the `vault_kubernetes_auth_backend_config` resource ([#2206](https://github.com/hashicorp/terraform-provider-vault/pull/2206)) ## 4.4.0 (Aug 7, 2024) diff --git a/vault/data_source_kubernetes_auth_backend_config.go b/vault/data_source_kubernetes_auth_backend_config.go index 9f67f34db..0dda9a19f 100644 --- a/vault/data_source_kubernetes_auth_backend_config.go +++ b/vault/data_source_kubernetes_auth_backend_config.go @@ -66,6 +66,12 @@ func kubernetesAuthBackendConfigDataSource() *schema.Resource { Optional: true, Description: "Optional disable defaulting to the local CA cert and service account JWT when running in a Kubernetes pod.", }, + fieldUseAnnotationsAsAliasMetadata: { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: "Use annotations from the client token's associated service account as alias metadata for the Vault entity.", + }, }, } } @@ -105,5 +111,12 @@ func kubernetesAuthBackendConfigDataSourceRead(d *schema.ResourceData, meta inte d.Set(consts.FieldDisableISSValidation, resp.Data[consts.FieldDisableISSValidation]) d.Set(consts.FieldDisableLocalCAJWT, resp.Data[consts.FieldDisableLocalCAJWT]) + if provider.IsAPISupported(meta, provider.VaultVersion116) { + err := d.Set(fieldUseAnnotationsAsAliasMetadata, resp.Data[fieldUseAnnotationsAsAliasMetadata]) + if err != nil { + return err + } + } + return nil } diff --git a/vault/data_source_kubernetes_auth_backend_config_test.go b/vault/data_source_kubernetes_auth_backend_config_test.go index 216e77b5f..d02bba9e5 100644 --- a/vault/data_source_kubernetes_auth_backend_config_test.go +++ b/vault/data_source_kubernetes_auth_backend_config_test.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-provider-vault/internal/consts" + "github.com/hashicorp/terraform-provider-vault/internal/provider" "github.com/hashicorp/terraform-provider-vault/testutil" ) @@ -62,6 +63,7 @@ func TestAccKubernetesAuthBackendConfigDataSource_full(t *testing.T) { issuer := "kubernetes/serviceaccount" disableIssValidation := true disableLocalCaJwt := true + useAnnotationsAsAliasMetadata := true resource.Test(t, resource.TestCase{ PreCheck: func() { testutil.TestAccPreCheck(t) }, @@ -115,6 +117,17 @@ func TestAccKubernetesAuthBackendConfigDataSource_full(t *testing.T) { consts.FieldDisableLocalCAJWT, strconv.FormatBool(disableLocalCaJwt)), ), }, + { + SkipFunc: func() (bool, error) { + meta := testProvider.Meta().(*provider.ProviderMeta) + return !meta.IsAPISupported(provider.VaultVersion116), nil + }, + Config: testAccKubernetesAuthBackendConfig_useAnnotations(backend, jwt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", + fieldUseAnnotationsAsAliasMetadata, strconv.FormatBool(useAnnotationsAsAliasMetadata)), + ), + }, }, }) } diff --git a/vault/resource_kubernetes_auth_backend_config.go b/vault/resource_kubernetes_auth_backend_config.go index 624a6c881..04f0b07c1 100644 --- a/vault/resource_kubernetes_auth_backend_config.go +++ b/vault/resource_kubernetes_auth_backend_config.go @@ -18,6 +18,8 @@ import ( "github.com/hashicorp/terraform-provider-vault/internal/provider" ) +const fieldUseAnnotationsAsAliasMetadata = "use_annotations_as_alias_metadata" + var ( kubernetesAuthBackendConfigFromPathRegex = regexp.MustCompile("^auth/(.+)/config$") // overrideKubernetesFieldsMap maps resource IDs to a slice of strings containing @@ -82,6 +84,12 @@ func kubernetesAuthBackendConfigResource() *schema.Resource { Optional: true, Description: "Optional disable defaulting to the local CA cert and service account JWT when running in a Kubernetes pod.", }, + fieldUseAnnotationsAsAliasMetadata: { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: "Use annotations from the client token's associated service account as alias metadata for the Vault entity.", + }, } return &schema.Resource{ Create: kubernetesAuthBackendConfigCreate, @@ -177,6 +185,13 @@ func kubernetesAuthBackendConfigCreate(d *schema.ResourceData, meta interface{}) if v, ok := d.GetOk(consts.FieldDisableLocalCAJWT); ok { data[consts.FieldDisableLocalCAJWT] = v } + + if provider.IsAPISupported(meta, provider.VaultVersion116) { + if v := d.Get(fieldUseAnnotationsAsAliasMetadata); v != nil { + data[fieldUseAnnotationsAsAliasMetadata] = v + } + } + _, err := client.Logical().Write(path, data) if err != nil { return fmt.Errorf("error writing Kubernetes auth backend config %q: %s", path, err) @@ -243,9 +258,13 @@ func kubernetesAuthBackendConfigRead(d *schema.ResourceData, meta interface{}) e consts.FieldDisableISSValidation, consts.FieldDisableLocalCAJWT, consts.FieldPEMKeys, + fieldUseAnnotationsAsAliasMetadata, } for _, k := range params { + if k == fieldUseAnnotationsAsAliasMetadata && !provider.IsAPISupported(meta, provider.VaultVersion116) { + continue + } v := resp.Data[k] if err := d.Set(k, v); err != nil { return err @@ -302,6 +321,12 @@ func kubernetesAuthBackendConfigUpdate(d *schema.ResourceData, meta interface{}) setData(consts.FieldDisableLocalCAJWT, v) } + if provider.IsAPISupported(meta, provider.VaultVersion116) { + if v := d.Get(fieldUseAnnotationsAsAliasMetadata); v != nil { + data[fieldUseAnnotationsAsAliasMetadata] = v + } + } + _, err := client.Logical().Write(path, data) if err != nil { return fmt.Errorf("error updating Kubernetes auth backend config %q: %s", path, err) diff --git a/vault/resource_kubernetes_auth_backend_config_test.go b/vault/resource_kubernetes_auth_backend_config_test.go index 309cc0654..46585f2bd 100644 --- a/vault/resource_kubernetes_auth_backend_config_test.go +++ b/vault/resource_kubernetes_auth_backend_config_test.go @@ -227,6 +227,7 @@ func TestAccKubernetesAuthBackendConfig_full(t *testing.T) { backend := acctest.RandomWithPrefix("kubernetes") jwt := kubernetesJWT issuer := "api" + testResource := "vault_kubernetes_auth_backend_config.config" resource.Test(t, resource.TestCase{ PreCheck: func() { testutil.TestAccPreCheck(t) }, @@ -237,24 +238,25 @@ func TestAccKubernetesAuthBackendConfig_full(t *testing.T) { Config: testAccKubernetesAuthBackendConfigConfig_full(backend, kubernetesCAcert, jwt, issuer, true, true, false), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", - "backend", backend), - resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", - consts.FieldKubernetesHost, "http://example.com:443"), - resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", - consts.FieldKubernetesCACert, kubernetesCAcert), - resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", - "token_reviewer_jwt", jwt), - resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", - "pem_keys.#", "1"), - resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", - "pem_keys.0", kubernetesPEMfile), - resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", - consts.FieldIssuer, "api"), - resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", - consts.FieldDisableISSValidation, strconv.FormatBool(true)), - resource.TestCheckResourceAttr("vault_kubernetes_auth_backend_config.config", - consts.FieldDisableLocalCAJWT, strconv.FormatBool(true)), + resource.TestCheckResourceAttr(testResource, "backend", backend), + resource.TestCheckResourceAttr(testResource, consts.FieldKubernetesHost, "http://example.com:443"), + resource.TestCheckResourceAttr(testResource, consts.FieldKubernetesCACert, kubernetesCAcert), + resource.TestCheckResourceAttr(testResource, "token_reviewer_jwt", jwt), + resource.TestCheckResourceAttr(testResource, "pem_keys.#", "1"), + resource.TestCheckResourceAttr(testResource, "pem_keys.0", kubernetesPEMfile), + resource.TestCheckResourceAttr(testResource, consts.FieldIssuer, "api"), + resource.TestCheckResourceAttr(testResource, consts.FieldDisableISSValidation, strconv.FormatBool(true)), + resource.TestCheckResourceAttr(testResource, consts.FieldDisableLocalCAJWT, strconv.FormatBool(true)), + ), + }, + { + SkipFunc: func() (bool, error) { + meta := testProvider.Meta().(*provider.ProviderMeta) + return !meta.IsAPISupported(provider.VaultVersion116), nil + }, + Config: testAccKubernetesAuthBackendConfig_useAnnotations(backend, jwt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(testResource, fieldUseAnnotationsAsAliasMetadata, strconv.FormatBool(true)), ), }, }, @@ -428,6 +430,22 @@ resource "vault_kubernetes_auth_backend_config" "config" { return config + "}" } +func testAccKubernetesAuthBackendConfig_useAnnotations(backend, jwt string) string { + return fmt.Sprintf(` +resource "vault_auth_backend" "kubernetes" { + type = "kubernetes" + path = "%s" +} + +resource "vault_kubernetes_auth_backend_config" "config" { + backend = vault_auth_backend.kubernetes.path + kubernetes_host = "http://example.com:443" + token_reviewer_jwt = %q + use_annotations_as_alias_metadata = true +} +`, backend, jwt) +} + func testAccKubernetesAuthBackendConfigConfig_full(backend, caCert, jwt, issuer string, disableIssValidation, disableLocalCaJwt, omitCA bool, ) string { diff --git a/website/docs/d/kubernetes_auth_backend_config.md b/website/docs/d/kubernetes_auth_backend_config.md index 1e3761b1e..698614b9d 100644 --- a/website/docs/d/kubernetes_auth_backend_config.md +++ b/website/docs/d/kubernetes_auth_backend_config.md @@ -47,3 +47,9 @@ In addition to the above arguments, the following attributes are exported: * `pem_keys` - Optional list of PEM-formatted public keys or certificates used to verify the signatures of Kubernetes service account JWTs. If a certificate is given, its public key will be extracted. Not every installation of Kubernetes exposes these keys. * `issuer` - Optional JWT issuer. If no issuer is specified, `kubernetes.io/serviceaccount` will be used as the default issuer. + +* `disable_iss_validation` - (Optional) Disable JWT issuer validation. Allows to skip ISS validation. Requires Vault `v1.5.4+` or Vault auth kubernetes plugin `v0.7.1+` + +* `disable_local_ca_jwt` - (Optional) Disable defaulting to the local CA cert and service account JWT when running in a Kubernetes pod. Requires Vault `v1.5.4+` or Vault auth kubernetes plugin `v0.7.1+` + +* `use_annotations_as_alias_metadata` - (Optional) Use annotations from the client token's associated service account as alias metadata for the Vault entity. Requires Vault `v1.16+` or Vault auth kubernetes plugin `v0.18.0+` diff --git a/website/docs/r/kubernetes_auth_backend_config.md b/website/docs/r/kubernetes_auth_backend_config.md index 4b8c84fa2..590a7505c 100644 --- a/website/docs/r/kubernetes_auth_backend_config.md +++ b/website/docs/r/kubernetes_auth_backend_config.md @@ -52,6 +52,8 @@ The following arguments are supported: * `disable_local_ca_jwt` - (Optional) Disable defaulting to the local CA cert and service account JWT when running in a Kubernetes pod. Requires Vault `v1.5.4+` or Vault auth kubernetes plugin `v0.7.1+` +* `use_annotations_as_alias_metadata` - (Optional) Use annotations from the client token's associated service account as alias metadata for the Vault entity. Requires Vault `v1.16+` or Vault auth kubernetes plugin `v0.18.0+` + ## Attributes Reference From 1351ad164efa1a240094e72c50be839a59ca0c07 Mon Sep 17 00:00:00 2001 From: John-Michael Faircloth Date: Thu, 7 Nov 2024 11:10:06 -0600 Subject: [PATCH 04/11] docs: fix custom ui message_base64 (#2356) --- website/docs/r/config_ui_custom_messages.html.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/website/docs/r/config_ui_custom_messages.html.md b/website/docs/r/config_ui_custom_messages.html.md index 85dd0a1d7..f44648f37 100644 --- a/website/docs/r/config_ui_custom_messages.html.md +++ b/website/docs/r/config_ui_custom_messages.html.md @@ -14,12 +14,12 @@ Manages a UI custom message in Vault. Custom messages are displayed in the Vault ```hcl resource "vault_config_ui_custom_message" "maintenance" { - title = "Upcoming maintenance" - message = base64encode("Vault will be offline for planned maintenance on February 1st, 2024 from 05:00Z to 08:00Z") - type = "banner" - authenticated = true - start_time = "2024-01-01T00:00:00.000Z" - end_time = "2024-02-01T05:00:00.000Z" + title = "Upcoming maintenance" + message_base64 = base64encode("Vault will be offline for planned maintenance on February 1st, 2024 from 05:00Z to 08:00Z") + type = "banner" + authenticated = true + start_time = "2024-01-01T00:00:00.000Z" + end_time = "2024-02-01T05:00:00.000Z" } ``` @@ -34,7 +34,7 @@ The following arguments are supported: * `title` - (Required) The title of the custom message to create. -* `message` - (Required) The base64-encoded content of the custom message. +* `message_base64` - (Required) The base64-encoded content of the custom message. * `start_time` - (Required) The time when the custom message begins to be active. This value can be set to a future time, but cannot occur on or after the `end_time` value. From d8d1353ce7dbefb81e03fa670a491f5c2b6b8877 Mon Sep 17 00:00:00 2001 From: John-Michael Faircloth Date: Thu, 7 Nov 2024 12:20:46 -0600 Subject: [PATCH 05/11] secret/ssh: add support for allow_empty_principals on roles (#2354) * secret/ssh: add support for allow_empty_principals on roles * changelog * ignore import field * remove comment --- CHANGELOG.md | 1 + vault/resource_ssh_secret_backend_role.go | 16 +++++- .../resource_ssh_secret_backend_role_test.go | 52 +++++-------------- 3 files changed, 27 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a77fae27..6dd77f0d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ FEATURES: * Update `vault_database_secret_backend_connection` to support skip_verification config for Cassandra ([#2346](https://github.com/hashicorp/terraform-provider-vault/pull/2346)) * Update `vault_approle_auth_backend_role_secret_id` to support `num_uses` and `ttl` fields ([#2345](https://github.com/hashicorp/terraform-provider-vault/pull/2345)) * Add support for `use_annotations_as_alias_metadata` field for the `vault_kubernetes_auth_backend_config` resource ([#2206](https://github.com/hashicorp/terraform-provider-vault/pull/2206)) +* Add support for `allow_empty_principals` field for the `vault_ssh_secret_backend_role` resource ([#2354](https://github.com/hashicorp/terraform-provider-vault/pull/2354)) ## 4.4.0 (Aug 7, 2024) diff --git a/vault/resource_ssh_secret_backend_role.go b/vault/resource_ssh_secret_backend_role.go index b3ee38aa5..d739b39d5 100644 --- a/vault/resource_ssh_secret_backend_role.go +++ b/vault/resource_ssh_secret_backend_role.go @@ -183,6 +183,11 @@ func sshSecretBackendRoleResource() *schema.Resource { Optional: true, Computed: true, }, + "allow_empty_principals": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, } return &schema.Resource{ @@ -261,6 +266,9 @@ func sshSecretBackendRoleWrite(d *schema.ResourceData, meta interface{}) error { data["allowed_domains_template"] = d.Get("allowed_domains_template") } + if provider.IsAPISupported(meta, provider.VaultVersion117) { + data["allow_empty_principals"] = d.Get("allow_empty_principals").(bool) + } if v, ok := d.GetOk("key_id_format"); ok { data["key_id_format"] = v.(string) @@ -359,9 +367,13 @@ func sshSecretBackendRoleRead(d *schema.ResourceData, meta interface{}) error { if provider.IsAPISupported(meta, provider.VaultVersion112) { fields = append(fields, []string{"default_user_template", "allowed_domains_template"}...) } + if provider.IsAPISupported(meta, provider.VaultVersion117) { + fields = append(fields, []string{"allow_empty_principals"}...) + } - // cidr_list cannot be read from the API - // potential for drift here + // cannot be read from the API, potential for drift here: + // - cidr_list + // - allow_empty_principals for _, k := range fields { if err := d.Set(k, role.Data[k]); err != nil { return err diff --git a/vault/resource_ssh_secret_backend_role_test.go b/vault/resource_ssh_secret_backend_role_test.go index c82e6e6db..30bdbe795 100644 --- a/vault/resource_ssh_secret_backend_role_test.go +++ b/vault/resource_ssh_secret_backend_role_test.go @@ -50,6 +50,7 @@ func TestAccSSHSecretBackendRole(t *testing.T) { // 30s is the default value vault uese. // https://developer.hashicorp.com/vault/api-docs/secret/ssh#not_before_duration resource.TestCheckResourceAttr(resourceName, "not_before_duration", "30"), + resource.TestCheckResourceAttr(resourceName, "allowed_domains_template", "false"), ) updateCheckFuncs := append(commonCheckFuncs, @@ -73,6 +74,7 @@ func TestAccSSHSecretBackendRole(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "ttl", "43200"), // 50m (3000 seconds) resource.TestCheckResourceAttr(resourceName, "not_before_duration", "3000"), + resource.TestCheckResourceAttr(resourceName, "allowed_domains_template", "true"), ) getCheckFuncs := func(isUpdate bool) resource.TestCheckFunc { @@ -84,19 +86,6 @@ func TestAccSSHSecretBackendRole(t *testing.T) { checks = append(checks, initialCheckFuncs...) } - meta := testProvider.Meta().(*provider.ProviderMeta) - isVaultVersion112 := meta.IsAPISupported(provider.VaultVersion112) - if isVaultVersion112 { - if isUpdate { - checks = append(checks, - resource.TestCheckResourceAttr(resourceName, "allowed_domains_template", "true"), - ) - } else { - checks = append(checks, - resource.TestCheckResourceAttr(resourceName, "allowed_domains_template", "false"), - ) - } - } return resource.ComposeAggregateTestCheckFunc(checks...)(state) } } @@ -129,35 +118,17 @@ func TestAccSSHSecretBackendRole(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "allowed_user_key_config.1.lengths.0", "256"), ), }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, + testutil.GetImportTestStep(resourceName, false, nil, "allow_empty_principals"), } } - t.Run("vault-1.11-and-below", func(t *testing.T) { - resource.Test(t, resource.TestCase{ - ProviderFactories: providerFactories, - PreCheck: func() { - testutil.TestAccPreCheck(t) - SkipIfAPIVersionGTE(t, testProvider.Meta(), provider.VaultVersion112) - }, - CheckDestroy: testAccSSHSecretBackendRoleCheckDestroy, - Steps: getSteps(""), - }) - }) - t.Run("vault-1.12-and-up", func(t *testing.T) { - resource.Test(t, resource.TestCase{ - ProviderFactories: providerFactories, - PreCheck: func() { - testutil.TestAccPreCheck(t) - SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion112) - }, - CheckDestroy: testAccSSHSecretBackendRoleCheckDestroy, - Steps: getSteps("allowed_domains_template = true"), - }) + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + PreCheck: func() { + testutil.TestAccPreCheck(t) + }, + CheckDestroy: testAccSSHSecretBackendRoleCheckDestroy, + Steps: getSteps(""), }) } @@ -205,7 +176,7 @@ func TestAccSSHSecretBackendRole_template(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "default_user_template", "true"), ), }, - testutil.GetImportTestStep(resourceName, false, nil), + testutil.GetImportTestStep(resourceName, false, nil, "allow_empty_principals"), }, }) } @@ -289,6 +260,7 @@ resource "vault_ssh_secret_backend_role" "test_role" { allow_user_key_ids = true allowed_critical_options = "foo,bar" allowed_domains = "example.com,foo.com" + allowed_domains_template = true allowed_extensions = "ext1,ext2" default_extensions = { "ext1" = "" } default_critical_options = { "opt1" = "" } From e720115744e2ca423022a6b817a4cec6fccf5bf0 Mon Sep 17 00:00:00 2001 From: vinay-gopalan <86625824+vinay-gopalan@users.noreply.github.com> Date: Mon, 11 Nov 2024 09:53:46 -0800 Subject: [PATCH 06/11] Add new fields to Postgres to enable Rootless Configuration for Static Roles (#2341) --- .github/workflows/build.yml | 8 +- CHANGELOG.md | 1 + go.mod | 16 ++- go.sum | 38 ++++-- internal/consts/consts.go | 1 + testutil/postgresqlhelper.go | 127 ++++++++++++++++++ ...urce_database_secret_backend_connection.go | 18 +++ ...database_secret_backend_connection_test.go | 44 ++++++ ...rce_database_secret_backend_static_role.go | 13 ++ ...atabase_secret_backend_static_role_test.go | 88 ++++++++++++ .../r/database_secret_backend_connection.md | 4 + .../r/database_secret_backend_static_role.md | 4 + 12 files changed, 344 insertions(+), 18 deletions(-) create mode 100644 testutil/postgresqlhelper.go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d3557557a..2b974510d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,11 +63,11 @@ jobs: fail-fast: false matrix: image: - - "vault-enterprise:1.13.13-ent" - "vault-enterprise:1.14.13-ent" - - "vault-enterprise:1.15.12-ent" - - "vault-enterprise:1.16.6-ent" - - "vault-enterprise:1.17.2-ent" + - "vault-enterprise:1.15.16-ent" + - "vault-enterprise:1.16.11-ent" + - "vault-enterprise:1.17.7-ent" + - "vault-enterprise:1.18.0-ent" - "vault:latest" services: vault: diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dd77f0d6..1caa10a5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ FEATURES: * Update `vault_approle_auth_backend_role_secret_id` to support `num_uses` and `ttl` fields ([#2345](https://github.com/hashicorp/terraform-provider-vault/pull/2345)) * Add support for `use_annotations_as_alias_metadata` field for the `vault_kubernetes_auth_backend_config` resource ([#2206](https://github.com/hashicorp/terraform-provider-vault/pull/2206)) * Add support for `allow_empty_principals` field for the `vault_ssh_secret_backend_role` resource ([#2354](https://github.com/hashicorp/terraform-provider-vault/pull/2354)) +* Add support for Rootless Configuration for Static Roles to Postgres DB ([#2341](https://github.com/hashicorp/terraform-provider-vault/pull/2341)) ## 4.4.0 (Aug 7, 2024) diff --git a/go.mod b/go.mod index 5b2ed697d..c597ffc1d 100644 --- a/go.mod +++ b/go.mod @@ -31,11 +31,12 @@ require ( github.com/hashicorp/vault-plugin-auth-oci v0.15.1 github.com/hashicorp/vault/api v1.14.0 github.com/hashicorp/vault/sdk v0.13.0 + github.com/jackc/pgx/v4 v4.18.3 github.com/jcmturner/gokrb5/v8 v8.4.4 github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/mapstructure v1.5.0 github.com/stretchr/testify v1.9.0 - golang.org/x/crypto v0.24.0 + golang.org/x/crypto v0.27.0 golang.org/x/net v0.26.0 golang.org/x/oauth2 v0.18.0 google.golang.org/api v0.163.0 @@ -114,6 +115,13 @@ require ( github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgconn v1.14.3 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.3.3 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgtype v1.14.0 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/gofork v1.7.6 // indirect @@ -161,9 +169,9 @@ require ( go.uber.org/atomic v1.11.0 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/go.sum b/go.sum index 8b72b7403..6fe0665c7 100644 --- a/go.sum +++ b/go.sum @@ -1203,6 +1203,7 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= @@ -1378,6 +1379,7 @@ github.com/cncf/xds/go v0.0.0-20230428030218-4003588d1b74/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= @@ -1772,6 +1774,7 @@ github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= @@ -2144,6 +2147,7 @@ github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6t github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= @@ -2152,10 +2156,15 @@ github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfG github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= +github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= +github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= @@ -2165,18 +2174,25 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1: github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= +github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw= github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= +github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA= +github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= @@ -2283,6 +2299,7 @@ github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTRe github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= @@ -2641,6 +2658,7 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -2967,8 +2985,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -3185,8 +3203,8 @@ golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -3346,8 +3364,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -3369,8 +3387,8 @@ golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3392,8 +3410,8 @@ golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/internal/consts/consts.go b/internal/consts/consts.go index f9f28e3b4..1fab9e141 100644 --- a/internal/consts/consts.go +++ b/internal/consts/consts.go @@ -437,6 +437,7 @@ const ( FieldTune = "tune" FieldMaxRetries = "max_retries" FieldSessionTags = "session_tags" + FieldSelfManagedPassword = "self_managed_password" /* common environment variables diff --git a/testutil/postgresqlhelper.go b/testutil/postgresqlhelper.go new file mode 100644 index 000000000..6a5312897 --- /dev/null +++ b/testutil/postgresqlhelper.go @@ -0,0 +1,127 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package testutil + +import ( + "context" + "database/sql" + "fmt" + "github.com/hashicorp/vault/sdk/helper/dbtxn" + "github.com/hashicorp/vault/sdk/helper/docker" + "net/url" + "os" + "testing" + + _ "github.com/jackc/pgx/v4/stdlib" +) + +const ( + defaultPGImage = "docker.mirror.hashicorp.services/postgres" + defaultPGVersion = "13.4-buster" + defaultPGPass = "secret" +) + +func defaultRunOpts(t *testing.T) docker.RunOptions { + return docker.RunOptions{ + ContainerName: "postgres", + ImageRepo: defaultPGImage, + ImageTag: defaultPGVersion, + Env: []string{ + "POSTGRES_PASSWORD=" + defaultPGPass, + "POSTGRES_DB=database", + }, + Ports: []string{"5432/tcp"}, + DoNotAutoRemove: false, + OmitLogTimestamps: true, + LogConsumer: func(s string) { + if t.Failed() { + t.Logf("container logs: %s", s) + } + }, + } +} + +func CreateTestPGUser(t *testing.T, connURL string, username, password, query string) { + t.Helper() + t.Logf("[TRACE] Creating test user") + + db, err := sql.Open("pgx", connURL) + defer db.Close() + if err != nil { + t.Fatal(err) + } + + // Start a transaction + ctx := context.Background() + tx, err := db.BeginTx(ctx, nil) + if err != nil { + t.Fatal(err) + } + defer func() { + _ = tx.Rollback() + }() + + m := map[string]string{ + "name": username, + "password": password, + } + if err := dbtxn.ExecuteTxQueryDirect(ctx, tx, m, query); err != nil { + t.Fatal(err) + } + // Commit the transaction + if err := tx.Commit(); err != nil { + t.Fatal(err) + } +} + +func PrepareTestContainerSelfManaged(t *testing.T) (func(), *url.URL) { + return prepareTestContainerSelfManaged(t, defaultRunOpts(t), defaultPGPass, true, false, false) +} + +func prepareTestContainerSelfManaged(t *testing.T, runOpts docker.RunOptions, password string, addSuffix, forceLocalAddr, useFallback bool, +) (func(), *url.URL) { + if os.Getenv("PG_URL") != "" { + return func() {}, nil + } + + runner, err := docker.NewServiceRunner(runOpts) + if err != nil { + t.Fatalf("Could not start docker Postgres: %s", err) + } + + svc, _, err := runner.StartNewService(context.Background(), addSuffix, forceLocalAddr, connectPostgres(password, runOpts.ImageRepo, useFallback)) + if err != nil { + t.Fatalf("Could not start docker Postgres: %s", err) + } + + return svc.Cleanup, svc.Config.URL() +} + +func connectPostgres(password, repo string, useFallback bool) docker.ServiceAdapter { + return func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + hostAddr := fmt.Sprintf("%s:%d", host, port) + if useFallback { + // set the first host to a bad address so we can test the fallback logic + hostAddr = "localhost:55," + hostAddr + } + u := url.URL{ + Scheme: "postgres", + User: url.UserPassword("postgres", password), + Host: hostAddr, + Path: "postgres", + RawQuery: "sslmode=disable", + } + + db, err := sql.Open("pgx", u.String()) + if err != nil { + return nil, err + } + defer db.Close() + + if err = db.Ping(); err != nil { + return nil, err + } + return docker.NewServiceURL(u), nil + } +} diff --git a/vault/resource_database_secret_backend_connection.go b/vault/resource_database_secret_backend_connection.go index 8159b3741..50bf82028 100644 --- a/vault/resource_database_secret_backend_connection.go +++ b/vault/resource_database_secret_backend_connection.go @@ -830,6 +830,13 @@ func postgresConnectionStringResource() *schema.Resource { Description: "The secret key used for the x509 client certificate. Must be PEM encoded.", Sensitive: true, } + + r.Schema["self_managed"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Description: "If set, allows onboarding static roles with a rootless connection configuration.", + } + return r } @@ -1154,6 +1161,11 @@ func getPostgresConnectionDetailsFromResponse(d *schema.ResourceData, prefix str result["private_key"] = d.Get(prefix + "private_key") } + if provider.IsAPISupported(meta, provider.VaultVersion118) && provider.IsEnterpriseSupported(meta) { + if v, ok := data["self_managed"]; ok { + result["self_managed"] = v.(bool) + } + } return result } @@ -1558,6 +1570,12 @@ func setPostgresDatabaseConnectionData(d *schema.ResourceData, prefix string, da data["private_key"] = v.(string) } } + + if provider.IsAPISupported(meta, provider.VaultVersion118) && provider.IsEnterpriseSupported(meta) { + if v, ok := d.GetOk(prefix + "self_managed"); ok { + data["self_managed"] = v.(bool) + } + } } func setRedisDatabaseConnectionData(d *schema.ResourceData, prefix string, data map[string]interface{}) { diff --git a/vault/resource_database_secret_backend_connection_test.go b/vault/resource_database_secret_backend_connection_test.go index 6c9a579e2..69e85fe17 100644 --- a/vault/resource_database_secret_backend_connection_test.go +++ b/vault/resource_database_secret_backend_connection_test.go @@ -865,6 +865,31 @@ func TestAccDatabaseSecretBackendConnection_postgresql_tls(t *testing.T) { }) } +func TestAccDatabaseSecretBackendConnection_postgresql_rootlessConfig(t *testing.T) { + resourceName := "vault_database_secret_backend_connection.test" + backend := acctest.RandomWithPrefix("tf-test-db") + pluginName := dbEnginePostgres.DefaultPluginName() + name := acctest.RandomWithPrefix("db") + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + PreCheck: func() { + testutil.TestEntPreCheck(t) + SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion118) + }, + CheckDestroy: testAccDatabaseSecretBackendConnectionCheckDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDatabaseSecretBackendConnectionConfig_postgresql_rootless(name, backend), + Check: testComposeCheckFuncCommonDatabaseSecretBackend(name, backend, pluginName, + resource.TestCheckResourceAttr(resourceName, "postgresql.0.self_managed", "true"), + ), + }, + testutil.GetImportTestStep(resourceName, false, nil, ""), + }, + }) +} + func TestAccDatabaseSecretBackendConnection_postgresql_cloud(t *testing.T) { // wanted this to be the included with the following test, but the env-var check is different values := testutil.SkipTestEnvUnset(t, "POSTGRES_CLOUD_URL", "POSTGRES_CLOUD_SERVICE_ACCOUNT_JSON") @@ -1770,6 +1795,25 @@ resource "vault_database_secret_backend_connection" "test" { `, path, name, tlsCA, tlsCert, privateKey) } +func testAccDatabaseSecretBackendConnectionConfig_postgresql_rootless(name, path string) string { + return fmt.Sprintf(` +resource "vault_mount" "db" { + path = "%s" + type = "database" +} + +resource "vault_database_secret_backend_connection" "test" { + backend = vault_mount.db.path + name = "%s" + + postgresql { + connection_url = "postgresql://{{username}}:{{password}}@localhost:5432/postgres?sslmode=verify-full" + self_managed = true + } +} +`, path, name) +} + func testAccDatabaseSecretBackendConnectionConfig_postgres_cloud(name, path, connURL, authType, serviceAccountJSON string) string { return fmt.Sprintf(` resource "vault_mount" "db" { diff --git a/vault/resource_database_secret_backend_static_role.go b/vault/resource_database_secret_backend_static_role.go index 7794c59b6..b627351e1 100644 --- a/vault/resource_database_secret_backend_static_role.go +++ b/vault/resource_database_secret_backend_static_role.go @@ -92,6 +92,13 @@ func databaseSecretBackendStaticRoleResource() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, Description: "Database statements to execute to rotate the password for the configured database user.", }, + consts.FieldSelfManagedPassword: { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + Description: "The password corresponding to the username in the database. " + + "Required when using the Rootless Password Rotation workflow for static roles.", + }, }, } } @@ -131,6 +138,12 @@ func databaseSecretBackendStaticRoleWrite(ctx context.Context, d *schema.Resourc data[consts.FieldRotationPeriod] = v } + if provider.IsAPISupported(meta, provider.VaultVersion118) && provider.IsEnterpriseSupported(meta) { + if v, ok := d.GetOk(consts.FieldSelfManagedPassword); ok && v != "" { + data[consts.FieldSelfManagedPassword] = v + } + } + log.Printf("[DEBUG] Creating static role %q on database backend %q", name, backend) _, err := client.Logical().Write(path, data) if err != nil { diff --git a/vault/resource_database_secret_backend_static_role_test.go b/vault/resource_database_secret_backend_static_role_test.go index ac79287c9..1f23d835b 100644 --- a/vault/resource_database_secret_backend_static_role_test.go +++ b/vault/resource_database_secret_backend_static_role_test.go @@ -7,6 +7,7 @@ import ( "context" "database/sql" "fmt" + "github.com/hashicorp/terraform-provider-vault/internal/consts" "os" "testing" @@ -149,6 +150,64 @@ func TestAccDatabaseSecretBackendStaticRole_rotationSchedule(t *testing.T) { }) } +// TestAccDatabaseSecretBackendStaticRole_Rootless tests the +// Rootless Config and Rotation flow for Static Roles. +// This test sets up a PGX container and creates static users +// in the DB to test the workflow. +// Currently only runs locally; Vault CI is unable to talk +// to the PGX Docker container due to network issues. +func TestAccDatabaseSecretBackendStaticRole_Rootless(t *testing.T) { + // TODO enable test to run in CI + testutil.SkipTestEnvUnset(t, "PGX_ROOTLESS_ROTATION") + + backend := acctest.RandomWithPrefix("tf-test-db") + username := acctest.RandomWithPrefix("user") + dbName := acctest.RandomWithPrefix("db") + name := acctest.RandomWithPrefix("staticrole") + resourceName := "vault_database_secret_backend_static_role.test" + + testRoleStaticCreate := ` +CREATE ROLE "{{name}}" WITH + LOGIN + PASSWORD '{{password}}'; +` + + cleanup, pgxURL := testutil.PrepareTestContainerSelfManaged(t) + defer cleanup() + + connURL := fmt.Sprintf("postgresql://{{username}}:{{password}}@%s/postgres?sslmode=disable", pgxURL.Host) + + // create static database user + testutil.CreateTestPGUser(t, pgxURL.String(), username, "testpassword", testRoleStaticCreate) + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + PreCheck: func() { + testutil.TestEntPreCheck(t) + SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion118) + }, + CheckDestroy: testAccDatabaseSecretBackendStaticRoleCheckDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDatabaseSecretBackendStaticRoleConfig_rootlessConfig(name, username, dbName, backend, connURL, "testpassword"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "backend", backend), + resource.TestCheckResourceAttr(resourceName, "username", username), + resource.TestCheckResourceAttr(resourceName, "db_name", dbName), + resource.TestCheckResourceAttr(resourceName, "rotation_period", "3600"), + ), + }, + { + ResourceName: "vault_database_secret_backend_static_role.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{consts.FieldSelfManagedPassword}, + }, + }, + }) +} + func testAccDatabaseSecretBackendStaticRoleCheckDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "vault_database_secret_backend_static_role" { @@ -316,3 +375,32 @@ resource "vault_database_secret_backend_static_role" "test" { } `, path, db, connURL, name, username) } + +func testAccDatabaseSecretBackendStaticRoleConfig_rootlessConfig(name, username, db, path, connURL, smPassword string) string { + return fmt.Sprintf(` +resource "vault_mount" "db" { + path = "%s" + type = "database" +} + +resource "vault_database_secret_backend_connection" "test" { + backend = vault_mount.db.path + name = "%s" + allowed_roles = ["*"] + + postgresql { + connection_url = "%s" + self_managed = true + } +} + +resource "vault_database_secret_backend_static_role" "test" { + backend = vault_mount.db.path + db_name = vault_database_secret_backend_connection.test.name + name = "%s" + username = "%s" + self_managed_password = "%s" + rotation_period = 3600 +} +`, path, db, connURL, name, username, smPassword) +} diff --git a/website/docs/r/database_secret_backend_connection.md b/website/docs/r/database_secret_backend_connection.md index 769f96c6a..fab521f1a 100644 --- a/website/docs/r/database_secret_backend_connection.md +++ b/website/docs/r/database_secret_backend_connection.md @@ -328,6 +328,10 @@ See the [Vault * `password` - (Optional) The root credential password used in the connection URL. +* `self_managed` - (Optional) If set, allows onboarding static roles with a rootless + connection configuration. Mutually exclusive with `username` and `password`. + If set, will force `verify_connection` to be false. Requires Vault 1.18+ Enterprise. + * `tls_ca` - (Optional) The x509 CA file for validating the certificate presented by the PostgreSQL server. Must be PEM encoded. diff --git a/website/docs/r/database_secret_backend_static_role.md b/website/docs/r/database_secret_backend_static_role.md index c1f1bc662..167b9c86b 100644 --- a/website/docs/r/database_secret_backend_static_role.md +++ b/website/docs/r/database_secret_backend_static_role.md @@ -69,6 +69,10 @@ The following arguments are supported: * `username` - (Required) The database username that this static role corresponds to. +* `self_managed_password` - (Optional) The password corresponding to the username in the database. + Required when using the Rootless Password Rotation workflow for static roles. Only enabled for + select DB engines (Postgres). Requires Vault 1.18+ Enterprise. + * `rotation_period` - The amount of time Vault should wait before rotating the password, in seconds. Mutually exclusive with `rotation_schedule`. From c4d3fd9e22a9994b2a3c512e96e6897278752d89 Mon Sep 17 00:00:00 2001 From: John-Michael Faircloth Date: Mon, 11 Nov 2024 13:37:33 -0600 Subject: [PATCH 07/11] docs: add note on ent-only feature (#2360) --- website/docs/r/config_ui_custom_messages.html.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/r/config_ui_custom_messages.html.md b/website/docs/r/config_ui_custom_messages.html.md index f44648f37..789d5bba8 100644 --- a/website/docs/r/config_ui_custom_messages.html.md +++ b/website/docs/r/config_ui_custom_messages.html.md @@ -10,6 +10,8 @@ description: |- Manages a UI custom message in Vault. Custom messages are displayed in the Vault UI either on the login page or immediately after succesfully logging in. +**Note** this feature is available only with Vault Enterprise. + ## Example Usage ```hcl From 67dfd58108ea4e67771f37f72e54c0d2062839ff Mon Sep 17 00:00:00 2001 From: Jon Leemon <4316746+nomeelnoj@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:38:13 -0800 Subject: [PATCH 08/11] fix(ldap): add connection_timeout to vault_ldap_auth_backend (#2358) * fix(ldap): add connection_timeout to vault_ldap_auth_backend Fixes #2357 Signed-off-by: nomeelnoj * chore(changelog): revert automatic whitespace changes Signed-off-by: nomeelnoj * fix(ldap): convert connection_timeout to int Signed-off-by: nomeelnoj * fix(docs): update language to specify number in seconds Signed-off-by: nomeelnoj * fix(changelog): accidentally overwrote previous entry Signed-off-by: nomeelnoj --------- Signed-off-by: nomeelnoj Co-authored-by: nomeelnoj Co-authored-by: John-Michael Faircloth --- CHANGELOG.md | 1 + vault/resource_ldap_auth_backend.go | 15 +++++++++++++++ vault/resource_ldap_auth_backend_test.go | 4 +++- website/docs/r/ldap_auth_backend.html.md | 2 ++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1caa10a5f..0954fcc1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ FEATURES: * Update `vault_approle_auth_backend_role_secret_id` to support `num_uses` and `ttl` fields ([#2345](https://github.com/hashicorp/terraform-provider-vault/pull/2345)) * Add support for `use_annotations_as_alias_metadata` field for the `vault_kubernetes_auth_backend_config` resource ([#2206](https://github.com/hashicorp/terraform-provider-vault/pull/2206)) * Add support for `allow_empty_principals` field for the `vault_ssh_secret_backend_role` resource ([#2354](https://github.com/hashicorp/terraform-provider-vault/pull/2354)) +* Add support for `connection_timeout` field for the `vault_ldap_auth_backend` resource ([#2358](https://github.com/hashicorp/terraform-provider-vault/pull/2358)) * Add support for Rootless Configuration for Static Roles to Postgres DB ([#2341](https://github.com/hashicorp/terraform-provider-vault/pull/2341)) ## 4.4.0 (Aug 7, 2024) diff --git a/vault/resource_ldap_auth_backend.go b/vault/resource_ldap_auth_backend.go index 497e07d5f..67b115c23 100644 --- a/vault/resource_ldap_auth_backend.go +++ b/vault/resource_ldap_auth_backend.go @@ -193,6 +193,11 @@ func ldapAuthBackendResource() *schema.Resource { Computed: true, Sensitive: true, }, + consts.FieldConnectionTimeout: { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, } addTokenFields(fields, &addTokenFieldsConfig{}) @@ -297,6 +302,10 @@ func ldapAuthBackendUpdate(ctx context.Context, d *schema.ResourceData, meta int data[consts.FieldClientTLSKey] = v.(string) } + if v, ok := d.GetOk(consts.FieldConnectionTimeout); ok { + data[consts.FieldConnectionTimeout] = v + } + updateTokenFields(d, data, false) log.Printf("[DEBUG] Writing LDAP config %q", path) @@ -376,6 +385,12 @@ func ldapAuthBackendRead(ctx context.Context, d *schema.ResourceData, meta inter } } + if v, ok := resp.Data[consts.FieldConnectionTimeout]; ok { + if err := d.Set(consts.FieldConnectionTimeout, v); err != nil { + return diag.Errorf("error reading %s for LDAP Auth Backend %q: %q", consts.FieldConnectionTimeout, path, err) + } + } + // `bindpass`, `client_tls_cert` and `client_tls_key` cannot be read out from the API // So... if they drift, they drift. diff --git a/vault/resource_ldap_auth_backend_test.go b/vault/resource_ldap_auth_backend_test.go index 4687deab2..3e602dfe3 100644 --- a/vault/resource_ldap_auth_backend_test.go +++ b/vault/resource_ldap_auth_backend_test.go @@ -230,6 +230,7 @@ func testLDAPAuthBackendCheck_attrs(resourceName string, name string) resource.T "groupdn": "groupdn", "groupattr": "groupattr", "use_token_groups": "use_token_groups", + "connection_timeout": "connection_timeout", } isVaultVersion111 := provider.IsAPISupported(testProvider.Meta(), provider.VaultVersion111) @@ -278,7 +279,8 @@ resource "vault_ldap_auth_backend" "test" { description = "example" userfilter = "({{.UserAttr}}={{.Username}})" username_as_alias = true - use_token_groups = %s + use_token_groups = %s + connection_timeout = 30 } `, path, local, use_token_groups) } diff --git a/website/docs/r/ldap_auth_backend.html.md b/website/docs/r/ldap_auth_backend.html.md index f0e525085..e534096c6 100644 --- a/website/docs/r/ldap_auth_backend.html.md +++ b/website/docs/r/ldap_auth_backend.html.md @@ -88,6 +88,8 @@ The following arguments are supported: * `local` - (Optional) Specifies if the auth method is local only. +* `connection_timeout` - (Optional) Timeout in seconds when connecting to LDAP before attempting to connect to the next server in the URL provided in `url` (integer: 30) + ### Common Token Arguments These arguments are common across several Authentication Token resources since Vault 1.2. From 4cfc26ec107e27fc81cae5828860aae2a9bf6266 Mon Sep 17 00:00:00 2001 From: Lasse Gaardsholt Date: Mon, 11 Nov 2024 20:42:09 +0100 Subject: [PATCH 09/11] Added TTL field (#2318) * added TTL field Signed-off-by: Lasse Gaardsholt * Added `Computed: True` to TTL Signed-off-by: Lasse Gaardsholt * redundant since false is the default Signed-off-by: Lasse Gaardsholt * Added changlog entry Signed-off-by: Lasse Gaardsholt * Tried adding some tests Signed-off-by: Lasse Gaardsholt * is this enough to read it? Signed-off-by: Lasse Gaardsholt --------- Signed-off-by: Lasse Gaardsholt Co-authored-by: John-Michael Faircloth --- CHANGELOG.md | 87 ++++++++++--------- ...esource_gcp_secret_impersonated_account.go | 12 ++- ...ce_gcp_secret_impersonated_account_test.go | 4 + .../r/gcp_secret_impersonated_account.html.md | 3 + 4 files changed, 62 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0954fcc1f..89a6c71e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ FEATURES: * Update `vault_approle_auth_backend_role_secret_id` to support `num_uses` and `ttl` fields ([#2345](https://github.com/hashicorp/terraform-provider-vault/pull/2345)) * Add support for `use_annotations_as_alias_metadata` field for the `vault_kubernetes_auth_backend_config` resource ([#2206](https://github.com/hashicorp/terraform-provider-vault/pull/2206)) * Add support for `allow_empty_principals` field for the `vault_ssh_secret_backend_role` resource ([#2354](https://github.com/hashicorp/terraform-provider-vault/pull/2354)) +* Update `vault_gcp_secret_impersonated_account` to support setting `ttl` ([#2318](https://github.com/hashicorp/terraform-provider-vault/pull/2318)) * Add support for `connection_timeout` field for the `vault_ldap_auth_backend` resource ([#2358](https://github.com/hashicorp/terraform-provider-vault/pull/2358)) * Add support for Rootless Configuration for Static Roles to Postgres DB ([#2341](https://github.com/hashicorp/terraform-provider-vault/pull/2341)) @@ -26,7 +27,7 @@ BUGS: FEATURES: * Add support for `iam_tags` in `vault_aws_secret_backend_role` ([#2231](https://github.com/hashicorp/terraform-provider-vault/pull/2231)). * Add support for `inheritable` on `vault_quota_rate_limit` and `vault_quota_lease_count`. Requires Vault 1.15+.: ([#2133](https://github.com/hashicorp/terraform-provider-vault/pull/2133)). -* Add support for new WIF fields in `vault_gcp_secret_backend`. Requires Vault 1.17+. *Available only for Vault Enterprise* ([#2249](https://github.com/hashicorp/terraform-provider-vault/pull/2249)). +* Add support for new WIF fields in `vault_gcp_secret_backend`. Requires Vault 1.17+. *Available only for Vault Enterprise* ([#2249](https://github.com/hashicorp/terraform-provider-vault/pull/2249)). * Add support for new WIF fields in `vault_azure_secret_backend`. Requires Vault 1.17+. *Available only for Vault Enterprise* ([#2250](https://github.com/hashicorp/terraform-provider-vault/pull/2250)) * Add support for new WIF fields in `vault_aws_auth_backend_client`. Requires Vault 1.17+. *Available only for Vault Enterprise* ([#2243](https://github.com/hashicorp/terraform-provider-vault/pull/2243)). * Add support for new WIF fields in `vault_gcp_auth_backend` ([#2256](https://github.com/hashicorp/terraform-provider-vault/pull/2256)) @@ -295,7 +296,7 @@ BUGS: ## 3.15.2 (May 3, 2023) BUGS: * Revert [#1830](https://github.com/hashicorp/terraform-provider-vault/pull/1830) which introduced a unexpected breaking change in the way authentication is done within a namespace: ([#1840](https://github.com/hashicorp/terraform-provider-vault/pull/1840)) - + ## 3.15.1 (May 3, 2023) BUGS: * Ensure that the auth_login honours the provider's namespace: ([#1830](https://github.com/hashicorp/terraform-provider-vault/pull/1830)) @@ -433,37 +434,37 @@ FEATURES: IMPROVEMENTS: * Fix Import for OIDC Scope resource: ([#1548](https://github.com/hashicorp/terraform-provider-vault/pull/1548)) -* Update entity alias creation to use entity lookup api: +* Update entity alias creation to use entity lookup api: ([#1517](https://github.com/hashicorp/terraform-provider-vault/pull/1517)) ([#1552](https://github.com/hashicorp/terraform-provider-vault/pull/1552)) -* Add support for Consul secrets engine enhancements: +* Add support for Consul secrets engine enhancements: ([#1518](https://github.com/hashicorp/terraform-provider-vault/pull/1518)) -* auth/gcp: adds `custom_endpoint` parameter to backend config: +* auth/gcp: adds `custom_endpoint` parameter to backend config: ([#1482](https://github.com/hashicorp/terraform-provider-vault/pull/1482)) * auth/jwt: adds `user_claim_json_pointer` and `max_age` to roles: ([#1478](https://github.com/hashicorp/terraform-provider-vault/pull/1478)) BUGS: -* Support updating backend descriptions: +* Support updating backend descriptions: ([#1550](https://github.com/hashicorp/terraform-provider-vault/pull/1550)) ([#1543](https://github.com/hashicorp/terraform-provider-vault/pull/1543)) * Properly set the `base64_pem` in Vault for Couchbase: ([#1545](https://github.com/hashicorp/terraform-provider-vault/pull/1545)) * Fix bug where some rabbitmq config changes trigger erroneous mount recreation: ([#1542](https://github.com/hashicorp/terraform-provider-vault/pull/1542)) -* Update `*kv_secrets*` resources to support namespaces: +* Update `*kv_secrets*` resources to support namespaces: ([#1529](https://github.com/hashicorp/terraform-provider-vault/pull/1529)) * Do not validate JSON on OIDC scope template: ([#1547](https://github.com/hashicorp/terraform-provider-vault/pull/1547)) ## 3.7.0 (June 15, 2022) -FEATURES: +FEATURES: * Support setting `namespace` by resource - ([#1305](https://github.com/hashicorp/terraform-provider-vault/pull/1305)) + ([#1305](https://github.com/hashicorp/terraform-provider-vault/pull/1305)) ([#1479](https://github.com/hashicorp/terraform-provider-vault/pull/1479)) * Add dedicated KV (v1/v2) secret engine resources, and data sources, supersedes `vault_generic_secret` ([#1457](https://github.com/hashicorp/terraform-provider-vault/pull/1457)) - + IMPROVEMENTS: * Update vault libs to v1.10.3 ([#1483](https://github.com/hashicorp/terraform-provider-vault/pull/1483)) @@ -477,7 +478,7 @@ IMPROVEMENTS: ([#1084](https://github.com/hashicorp/terraform-provider-vault/pull/1084)) * ci: Test against vault-enterprise 1.10.3-ent: ([#1461](https://github.com/hashicorp/terraform-provider-vault/pull/1461)) - + BUGS: * `resource/auth_backend`: validate `path`, disallowing leading/trailing / ([#1471](https://github.com/hashicorp/terraform-provider-vault/pull/1471)) @@ -485,77 +486,77 @@ BUGS: ([#1469](https://github.com/hashicorp/terraform-provider-vault/pull/1469)) * `resource/cert_auth_backend`: add the correct field name: `allowed_organizational_units` ([#1496](https://github.com/hashicorp/terraform-provider-vault/pull/1496)) - + ## 3.6.0 (May 18, 2022) IMPROVEMENTS: -* `resource/pki_secret_backend_root_cert`: Force new root CA resource creation on out-of-band changes. +* `resource/pki_secret_backend_root_cert`: Force new root CA resource creation on out-of-band changes. ([#1428](https://github.com/hashicorp/terraform-provider-vault/pull/1428)) -* `resource/pki_secret_backend_intermediate_set_signed`: Document complete usage example. +* `resource/pki_secret_backend_intermediate_set_signed`: Document complete usage example. ([#1452](https://github.com/hashicorp/terraform-provider-vault/pull/1452)) -* `resource/pki_secret_backend_config_urls`: Add support for importing PKI config URLs +* `resource/pki_secret_backend_config_urls`: Add support for importing PKI config URLs ([#1451](https://github.com/hashicorp/terraform-provider-vault/pull/1451)) -* `vault/resource_pki_secret_backend*`: Extend revocation support to other resources +* `vault/resource_pki_secret_backend*`: Extend revocation support to other resources ([#1446](https://github.com/hashicorp/terraform-provider-vault/pull/1446)) -* `vault/resource_pki_secret_backend*`: Force new root CA/cert resource creation on out-of-band changes. +* `vault/resource_pki_secret_backend*`: Force new root CA/cert resource creation on out-of-band changes. ([#1432](https://github.com/hashicorp/terraform-provider-vault/pull/1432)) -* `datasource/generic_secret`: Improve documentation. +* `datasource/generic_secret`: Improve documentation. ([#1390](https://github.com/hashicorp/terraform-provider-vault/pull/1390)) -* `resource/ldap_auth_backend`: Support setting `userfilter`. +* `resource/ldap_auth_backend`: Support setting `userfilter`. ([#1378](https://github.com/hashicorp/terraform-provider-vault/pull/1378)) -* `resource/aws_auth_backend_role`: Add `role_id` as a computed field. +* `resource/aws_auth_backend_role`: Add `role_id` as a computed field. ([#1377](https://github.com/hashicorp/terraform-provider-vault/pull/1377)) -* Auth: Handle CIDR prefix being stripped for hosts in `token_bound_cidrs` +* Auth: Handle CIDR prefix being stripped for hosts in `token_bound_cidrs` ([#1346](https://github.com/hashicorp/terraform-provider-vault/pull/1346)) -* Add `allowed_serial_numbers` support +* Add `allowed_serial_numbers` support ([#1119](https://github.com/hashicorp/terraform-provider-vault/pull/1119)) -* `resource/pki_secret_backend_role`: Allow `key_type` to be set to `any`. +* `resource/pki_secret_backend_role`: Allow `key_type` to be set to `any`. ([#791](https://github.com/hashicorp/terraform-provider-vault/pull/791)) -* `resource/aws_secret_backend_role`: Add `user_path` and `permissions_boundary_arn` arguments. +* `resource/aws_secret_backend_role`: Add `user_path` and `permissions_boundary_arn` arguments. ([#781](https://github.com/hashicorp/terraform-provider-vault/pull/781)) BUGS: -* `resource/pki_secret_backend_root_sign_intermediate`: Ensure that the `certificate_bundle`, and `ca_chain` - do not contain duplicate certificates. +* `resource/pki_secret_backend_root_sign_intermediate`: Ensure that the `certificate_bundle`, and `ca_chain` + do not contain duplicate certificates. ([#1428](https://github.com/hashicorp/terraform-provider-vault/pull/1428)) -* `resource/identity_entity_alias`: Serialize create, update, and delete operations in order to prevent alias - mismatches. +* `resource/identity_entity_alias`: Serialize create, update, and delete operations in order to prevent alias + mismatches. ([#1429](https://github.com/hashicorp/terraform-provider-vault/pull/1429)) * `database_secret*`: Ignore mongodb-atlas `private_key` on read from Vault. - mismatches. + mismatches. ([#1438](https://github.com/hashicorp/terraform-provider-vault/issues/1438)) -* `resource/auth_backend`: Remove `ForceNew` behavior when updating `description`. +* `resource/auth_backend`: Remove `ForceNew` behavior when updating `description`. ([#1439](https://github.com/hashicorp/terraform-provider-vault/pull/1439)) -* `resource/identity_group_member_entity_ids`: Properly handle nil `member_entity_ids` in response. - ([#1448](https://github.com/hashicorp/terraform-provider-vault/pull/1448)) -* `resource/pki_secret_backend_role`: Fix TTL handling in PKI role. +* `resource/identity_group_member_entity_ids`: Properly handle nil `member_entity_ids` in response. + ([#1448](https://github.com/hashicorp/terraform-provider-vault/pull/1448)) +* `resource/pki_secret_backend_role`: Fix TTL handling in PKI role. ([#1447](https://github.com/hashicorp/terraform-provider-vault/pull/1447)) -* `resource/pki_secret_backend_role`: `key_usage` value should be computed. +* `resource/pki_secret_backend_role`: `key_usage` value should be computed. ([#1443](https://github.com/hashicorp/terraform-provider-vault/pull/1443)) -* `resource/vault_pki_secret_backend_{cert,sign}`: Properly force a new resource whenever the cert is near expiry. +* `resource/vault_pki_secret_backend_{cert,sign}`: Properly force a new resource whenever the cert is near expiry. ([#1440](https://github.com/hashicorp/terraform-provider-vault/pull/1440)) -* `resource/identity_entity_alias`: Remove read operation on entity alias update. +* `resource/identity_entity_alias`: Remove read operation on entity alias update. ([#1434](https://github.com/hashicorp/terraform-provider-vault/pull/1434)) ## 3.5.0 (April 20, 2022) FEATURES: * Add MFA support: new resources `vault_mfa_okta`, `vault_mfa_totp`, `vault_mfa_pingid` ([#1395](https://github.com/hashicorp/terraform-provider-vault/pull/1395)) -* *New* `resource/database_secrets_mount`: Configures any number of database secrets engines under +* *New* `resource/database_secrets_mount`: Configures any number of database secrets engines under a single, dedicated mount resource ([#1400](https://github.com/terraform-providers/terraform-provider-vault/pull/1400)) IMPROVEMENTS: -* `data/vault_generic_secret`: Add new field `with_lease_start_time` to `vault_generic_secret` datasource +* `data/vault_generic_secret`: Add new field `with_lease_start_time` to `vault_generic_secret` datasource ([#1414](https://github.com/hashicorp/terraform-provider-vault/pull/1414)) * `resource/vault_ssh_secret_backend_role`: support configuring multiple public SSH key lengths in vault-1.10+ ([#1413](https://github.com/terraform-providers/terraform-provider-vault/pull/1413)) -* `resource/database_secret*`: Add support for configuring TLS, and the `username_template` field for the ElasticSearch. +* `resource/database_secret*`: Add support for configuring TLS, and the `username_template` field for the ElasticSearch. * `resource/pki_secret_backend_cert`: Add support for optionally revoking the certificate upon resource destruction. ([#1411](https://github.com/terraform-providers/terraform-provider-vault/pull/1411)) * `provider`: Add support for setting the `tls_server_name` to use as the SNI host when connecting via TLS. ([#1145](https://github.com/terraform-providers/terraform-provider-vault/pull/1145) * `docs`: Add links to Learn Tutorials. ([#1399](https://github.com/terraform-providers/terraform-provider-vault/pull/1399)) - + BUGS: * `resource/identity_group`: Fix issue where the group's `member_entity_ids` were being unset in error on update. ([#1409](https://github.com/terraform-providers/terraform-provider-vault/pull/1409)) @@ -574,7 +575,7 @@ IMPROVEMENTS: ## 3.4.0 (March 24, 2022) FEATURES: * `data/azure_access_credentials` Add `subscription_id` and `tenant_id` fields to used during credential validation ([#1384](https://github.com/terraform-providers/terraform-provider-vault/pull/1384)) -* Add OIDC Provider support: new resources `vault_identity_oidc_scope`, `vault_identity_oidc_assignment`, `vault_identity_oidc_client` +* Add OIDC Provider support: new resources `vault_identity_oidc_scope`, `vault_identity_oidc_assignment`, `vault_identity_oidc_client` , `vault_identity_oidc_provider`, `vault_identity_oidc_public_keys`, `vault_identity_oidc_openid_config` ([#1363](https://github.com/hashicorp/terraform-provider-vault/pull/1363)) BUGS: @@ -608,8 +609,8 @@ BUGS: IMPROVEMENTS: * `resource/token_auth_backend_role`: Add `allowed_policies_glob` and `disallowed_polices_glob` ([#1316](https://github.com/hashicorp/terraform-provider-vault/pull/1316)) * `resource/database_secret_backend_connection`: Add support for configuring the secret engine's `plugin_name` ([#1320](https://github.com/hashicorp/terraform-provider-vault/pull/1320)) -* `resource/pki_secret_backend_root_sign_intermediate`: Update schema for `ca_chain` from string to a list of - `issuing_ca` and `certificate`, add new `certificate_bundle` attribute that provides the concatenation of the +* `resource/pki_secret_backend_root_sign_intermediate`: Update schema for `ca_chain` from string to a list of + `issuing_ca` and `certificate`, add new `certificate_bundle` attribute that provides the concatenation of the intermediate and issuing CA certificates (PEM encoded) ([#1330](https://github.com/hashicorp/terraform-provider-vault/pull/1330)) * `resource/azure_secret_backend`: Add support for setting `use_microsoft_graph_api` ([#1335](https://github.com/hashicorp/terraform-provider-vault/pull/1335)) * `r/d/kubernetes_auth_backend_role`: Add support for setting and getting `alias_name_source` ([#1336](https://github.com/hashicorp/terraform-provider-vault/pull/1336)) diff --git a/vault/resource_gcp_secret_impersonated_account.go b/vault/resource_gcp_secret_impersonated_account.go index 30be896eb..24905d995 100644 --- a/vault/resource_gcp_secret_impersonated_account.go +++ b/vault/resource_gcp_secret_impersonated_account.go @@ -68,6 +68,12 @@ func gcpSecretImpersonatedAccountResource() *schema.Resource { Computed: true, Description: "Project of the GCP Service Account managed by this impersonated account", }, + consts.FieldTTL: { + Type: schema.TypeString, + Optional: true, + Description: "Time to live.", + Computed: true, + }, }, } } @@ -136,7 +142,7 @@ func gcpSecretImpersonatedAccountRead(ctx context.Context, d *schema.ResourceDat return diag.FromErr(err) } - for _, k := range []string{consts.FieldTokenScopes, consts.FieldServiceAccountEmail, consts.FieldServiceAccountProject} { + for _, k := range []string{consts.FieldTokenScopes, consts.FieldServiceAccountEmail, consts.FieldServiceAccountProject, consts.FieldTTL} { v, ok := resp.Data[k] if ok { if err := d.Set(k, v); err != nil { @@ -200,6 +206,10 @@ func gcpSecretImpersonatedAccountUpdateFields(d *schema.ResourceData, data map[s if v, ok := d.GetOk(consts.FieldTokenScopes); ok { data[consts.FieldTokenScopes] = v.(*schema.Set).List() } + + if v, ok := d.GetOk(consts.FieldTTL); ok { + data[consts.FieldTTL] = v.(string) + } } func gcpSecretImpersonatedAccountPath(backend, impersonatedAccount string) string { diff --git a/vault/resource_gcp_secret_impersonated_account_test.go b/vault/resource_gcp_secret_impersonated_account_test.go index e5fbcd556..0aff24bda 100644 --- a/vault/resource_gcp_secret_impersonated_account_test.go +++ b/vault/resource_gcp_secret_impersonated_account_test.go @@ -50,6 +50,7 @@ func TestGCPSecretImpersonatedAccount(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "service_account_project", project), resource.TestCheckResourceAttr(resourceName, "token_scopes.#", "1"), resource.TestCheckResourceAttr(resourceName, "token_scopes.0", "https://www.googleapis.com/auth/cloud-platform"), + resource.TestCheckResourceAttr(resourceName, "ttl", "700"), ), }, { @@ -62,6 +63,7 @@ func TestGCPSecretImpersonatedAccount(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "token_scopes.#", "2"), resource.TestCheckResourceAttr(resourceName, "token_scopes.0", "https://www.googleapis.com/auth/cloud-platform"), resource.TestCheckResourceAttr(resourceName, "token_scopes.1", "https://www.googleapis.com/auth/cloud-platform.read-only"), + resource.TestCheckResourceAttr(resourceName, "ttl", "700"), ), }, testutil.GetImportTestStep(resourceName, false, nil), @@ -96,6 +98,7 @@ resource "vault_gcp_secret_impersonated_account" "test" { impersonated_account = "%s" token_scopes = ["https://www.googleapis.com/auth/cloud-platform"] service_account_email = "%s" + ttl = 700 } `, testGCPSecretImpersonatedAccount_backend(backend, credentials), impersonatedAccount, serviceAccountEmail) } @@ -112,6 +115,7 @@ resource "vault_gcp_secret_impersonated_account" "test" { "https://www.googleapis.com/auth/cloud-platform", ] service_account_email = "%s" + ttl = 700 } `, testGCPSecretImpersonatedAccount_backend(backend, credentials), impersonatedAccount, serviceAccountEmail) } diff --git a/website/docs/r/gcp_secret_impersonated_account.html.md b/website/docs/r/gcp_secret_impersonated_account.html.md index c2b9ebb91..56324809d 100644 --- a/website/docs/r/gcp_secret_impersonated_account.html.md +++ b/website/docs/r/gcp_secret_impersonated_account.html.md @@ -46,6 +46,9 @@ The following arguments are supported: * `token_scopes` - (Required) List of OAuth scopes to assign to access tokens generated under this impersonated account. +* `ttl` - (Optional) Specifies the default TTL for service principals generated using this role. + Accepts time suffixed strings ("1h") or an integer number of seconds. Defaults to the system/engine default TTL time. + ## Attributes Reference In addition to the fields above, the following attributes are also exposed: From 9e0f200a6f0dcc1838b02220bc74ca9fada2dfbd Mon Sep 17 00:00:00 2001 From: Leland Ursu Date: Tue, 12 Nov 2024 09:32:26 -0500 Subject: [PATCH 10/11] Create CODEOWNERS (#2355) * Create CODEOWNERS adding a code owners file for SOC 2 compliance * Update CODEOWNERS to a team with Write permissions * Update CODEOWNERS updated to use the vault eco system team for code reviewers --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 000000000..a765f7ea9 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @hashicorp/vault-ecosystem From 6b9160d840095d7dcb747a78c99320e531494639 Mon Sep 17 00:00:00 2001 From: John-Michael Faircloth Date: Wed, 13 Nov 2024 16:07:10 -0600 Subject: [PATCH 11/11] tests: make postgres rootless tests run in CI (#2362) --- .github/workflows/build.yml | 7 ++ testutil/postgresqlhelper.go | 84 +------------------ ...atabase_secret_backend_static_role_test.go | 21 ++--- 3 files changed, 17 insertions(+), 95 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2b974510d..3de68e304 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -205,7 +205,14 @@ jobs: MYSQL_CONNECTION_PASSWORD: "mysql" MONGODB_URL: "mongodb://root:mongodb@mongo:27017/admin?ssl=false" MSSQL_URL: "sqlserver://sa:${{ secrets.MSSQL_SA_PASSWORD }}@mssql:1433" + # POSTGRES_URL is the standard root conn URL for Vault POSTGRES_URL: "postgres://postgres:secret@postgres:5432/database?sslmode=disable" + # POSTGRES_URL_TEST is used by the TFVP test to connect directly to + # the postgres container. Note: the host is "localhost" because the + # TFVP tests do not run in the same docker network. + POSTGRES_URL_TEST: "postgres://postgres:secret@localhost:5432/database?sslmode=disable" + # POSTGRES_URL_ROOTLESS is used by Vault to connect to the postgres container. + POSTGRES_URL_ROOTLESS: "postgres://{{username}}:{{password}}@postgres:5432/database?sslmode=disable" COUCHBASE_HOST: couchbase COUCHBASE_USERNAME: Administrator COUCHBASE_PASSWORD: password diff --git a/testutil/postgresqlhelper.go b/testutil/postgresqlhelper.go index 6a5312897..84f1a3ccc 100644 --- a/testutil/postgresqlhelper.go +++ b/testutil/postgresqlhelper.go @@ -6,42 +6,13 @@ package testutil import ( "context" "database/sql" - "fmt" - "github.com/hashicorp/vault/sdk/helper/dbtxn" - "github.com/hashicorp/vault/sdk/helper/docker" - "net/url" - "os" "testing" - _ "github.com/jackc/pgx/v4/stdlib" -) + "github.com/hashicorp/vault/sdk/helper/dbtxn" -const ( - defaultPGImage = "docker.mirror.hashicorp.services/postgres" - defaultPGVersion = "13.4-buster" - defaultPGPass = "secret" + _ "github.com/jackc/pgx/v4/stdlib" ) -func defaultRunOpts(t *testing.T) docker.RunOptions { - return docker.RunOptions{ - ContainerName: "postgres", - ImageRepo: defaultPGImage, - ImageTag: defaultPGVersion, - Env: []string{ - "POSTGRES_PASSWORD=" + defaultPGPass, - "POSTGRES_DB=database", - }, - Ports: []string{"5432/tcp"}, - DoNotAutoRemove: false, - OmitLogTimestamps: true, - LogConsumer: func(s string) { - if t.Failed() { - t.Logf("container logs: %s", s) - } - }, - } -} - func CreateTestPGUser(t *testing.T, connURL string, username, password, query string) { t.Helper() t.Logf("[TRACE] Creating test user") @@ -74,54 +45,3 @@ func CreateTestPGUser(t *testing.T, connURL string, username, password, query st t.Fatal(err) } } - -func PrepareTestContainerSelfManaged(t *testing.T) (func(), *url.URL) { - return prepareTestContainerSelfManaged(t, defaultRunOpts(t), defaultPGPass, true, false, false) -} - -func prepareTestContainerSelfManaged(t *testing.T, runOpts docker.RunOptions, password string, addSuffix, forceLocalAddr, useFallback bool, -) (func(), *url.URL) { - if os.Getenv("PG_URL") != "" { - return func() {}, nil - } - - runner, err := docker.NewServiceRunner(runOpts) - if err != nil { - t.Fatalf("Could not start docker Postgres: %s", err) - } - - svc, _, err := runner.StartNewService(context.Background(), addSuffix, forceLocalAddr, connectPostgres(password, runOpts.ImageRepo, useFallback)) - if err != nil { - t.Fatalf("Could not start docker Postgres: %s", err) - } - - return svc.Cleanup, svc.Config.URL() -} - -func connectPostgres(password, repo string, useFallback bool) docker.ServiceAdapter { - return func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { - hostAddr := fmt.Sprintf("%s:%d", host, port) - if useFallback { - // set the first host to a bad address so we can test the fallback logic - hostAddr = "localhost:55," + hostAddr - } - u := url.URL{ - Scheme: "postgres", - User: url.UserPassword("postgres", password), - Host: hostAddr, - Path: "postgres", - RawQuery: "sslmode=disable", - } - - db, err := sql.Open("pgx", u.String()) - if err != nil { - return nil, err - } - defer db.Close() - - if err = db.Ping(); err != nil { - return nil, err - } - return docker.NewServiceURL(u), nil - } -} diff --git a/vault/resource_database_secret_backend_static_role_test.go b/vault/resource_database_secret_backend_static_role_test.go index 1f23d835b..96df17f7b 100644 --- a/vault/resource_database_secret_backend_static_role_test.go +++ b/vault/resource_database_secret_backend_static_role_test.go @@ -7,10 +7,11 @@ import ( "context" "database/sql" "fmt" - "github.com/hashicorp/terraform-provider-vault/internal/consts" "os" "testing" + "github.com/hashicorp/terraform-provider-vault/internal/consts" + _ "github.com/go-sql-driver/mysql" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -152,13 +153,12 @@ func TestAccDatabaseSecretBackendStaticRole_rotationSchedule(t *testing.T) { // TestAccDatabaseSecretBackendStaticRole_Rootless tests the // Rootless Config and Rotation flow for Static Roles. -// This test sets up a PGX container and creates static users -// in the DB to test the workflow. -// Currently only runs locally; Vault CI is unable to talk -// to the PGX Docker container due to network issues. +// To run locally you will need to set the following env vars: +// - POSTGRES_URL_TEST +// - POSTGRES_URL_ROOTLESS func TestAccDatabaseSecretBackendStaticRole_Rootless(t *testing.T) { - // TODO enable test to run in CI - testutil.SkipTestEnvUnset(t, "PGX_ROOTLESS_ROTATION") + connURLTestRoot := testutil.SkipTestEnvUnset(t, "POSTGRES_URL_TEST")[0] + connURL := testutil.SkipTestEnvUnset(t, "POSTGRES_URL_ROOTLESS")[0] backend := acctest.RandomWithPrefix("tf-test-db") username := acctest.RandomWithPrefix("user") @@ -172,13 +172,8 @@ CREATE ROLE "{{name}}" WITH PASSWORD '{{password}}'; ` - cleanup, pgxURL := testutil.PrepareTestContainerSelfManaged(t) - defer cleanup() - - connURL := fmt.Sprintf("postgresql://{{username}}:{{password}}@%s/postgres?sslmode=disable", pgxURL.Host) - // create static database user - testutil.CreateTestPGUser(t, pgxURL.String(), username, "testpassword", testRoleStaticCreate) + testutil.CreateTestPGUser(t, connURLTestRoot, username, "testpassword", testRoleStaticCreate) resource.Test(t, resource.TestCase{ ProviderFactories: providerFactories,