Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ FEATURES:

* Add support for `group_by` and `secondary_rate` on resource `vault_quota_rate_limit`. Requires Vault Enterprise 1.20.0+ ([#2476](https://github.com/hashicorp/terraform-provider-vault/pull/2476))
* Add support for Transit CMAC endpoint ([#2488](https://github.com/hashicorp/terraform-provider-vault/pull/2488))
* Add support `tls_ca` and `tls_certificate_key` for mongodb connections [#2482](https://github.com/hashicorp/terraform-provider-vault/pull/2482)

* Add new resource `vault_scep_auth_backend_role` to manage roles in a SCEP auth backend. [#2479](https://github.com/hashicorp/terraform-provider-vault/pull/2479).
* Add new datasource and resource `vault_pki_secret_backend_config_scep` for PKI SCEP configuration. [#2487](https://github.com/hashicorp/terraform-provider-vault/pull/2487).
Expand Down
66 changes: 58 additions & 8 deletions vault/resource_database_secret_backend_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,12 +486,10 @@ func getDatabaseSchema(typ schema.ValueType) schemaMap {
ConflictsWith: util.CalculateConflictsWith(dbEngineInfluxDB.Name(), dbEngineTypes),
},
dbEngineMongoDB.name: {
Type: typ,
Optional: true,
Description: "Connection parameters for the mongodb-database-plugin plugin.",
Elem: connectionStringResource(&connectionStringConfig{
includeUserPass: true,
}),
Type: typ,
Optional: true,
Description: "Connection parameters for the mongodb-database-plugin plugin.",
Elem: mongodbConnectionStringResource(),
MaxItems: 1,
ConflictsWith: util.CalculateConflictsWith(dbEngineMongoDB.Name(), dbEngineTypes),
},
Expand Down Expand Up @@ -942,6 +940,23 @@ func snowflakeConnectionStringResource() *schema.Resource {

r.Schema[consts.FieldPassword].Deprecated = "Snowflake is ending support for single-factor password authentication " +
"by November 2025. Refer to the documentation for more information on migrating to key-pair authentication."
return r
}

func mongodbConnectionStringResource() *schema.Resource {
r := connectionStringResource(&connectionStringConfig{
includeUserPass: true,
})
r.Schema["tls_certificate_key"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "x509 certificate for connecting to the database. This must be a PEM encoded version of the private key and the certificate combined.",
}
r.Schema["tls_ca"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "x509 CA file for validating the certificate presented by the MongoDB server. Must be PEM encoded.",
}

return r
}
Expand Down Expand Up @@ -1017,7 +1032,7 @@ func getDatabaseAPIDataForEngine(engine *dbEngine, idx int, d *schema.ResourceDa
case dbEngineHana:
setDatabaseConnectionDataWithDisableEscaping(d, prefix, data)
case dbEngineMongoDB:
setDatabaseConnectionDataWithUserPass(d, prefix, data)
setMongoDBDatabaseConnectionData(d, prefix, data)
case dbEngineMongoDBAtlas:
setMongoDBAtlasDatabaseConnectionData(d, prefix, data)
case dbEngineMSSQL:
Expand Down Expand Up @@ -1281,6 +1296,31 @@ func getMySQLConnectionDetailsFromResponse(d *schema.ResourceData, prefix string
return result
}

func getMongoDBConnectionDetailsFromResponse(d *schema.ResourceData, prefix string, resp *api.Secret) map[string]interface{} {
result := getConnectionDetailsFromResponseWithUserPass(d, prefix, resp)
details := resp.Data["connection_details"]
data, ok := details.(map[string]interface{})
if !ok {
return nil
}
if v, ok := d.GetOk(prefix + "tls_certificate_key"); ok {
result["tls_certificate_key"] = v.(string)
} else {
if v, ok := data["tls_certificate_key"]; ok {
result["tls_certificate_key"] = v.(string)
}
}
if v, ok := d.GetOk(prefix + "tls_ca"); ok {
result["tls_ca"] = v.(string)
} else {
if v, ok := data["tls_ca"]; ok {
result["tls_ca"] = v.(string)
}
}

return result
}

func getRedisConnectionDetailsFromResponse(d *schema.ResourceData, prefix string, resp *api.Secret) map[string]interface{} {
details := resp.Data["connection_details"]
data, ok := details.(map[string]interface{})
Expand Down Expand Up @@ -1624,6 +1664,16 @@ func setMySQLDatabaseConnectionData(d *schema.ResourceData, prefix string, data
}
}

func setMongoDBDatabaseConnectionData(d *schema.ResourceData, prefix string, data map[string]interface{}) {
setDatabaseConnectionDataWithUserPass(d, prefix, data)
if v, ok := d.GetOk(prefix + "tls_certificate_key"); ok {
data["tls_certificate_key"] = v.(string)
}
if v, ok := d.GetOk(prefix + "tls_ca"); ok {
data["tls_ca"] = v.(string)
}
}

func setPostgresDatabaseConnectionData(d *schema.ResourceData, prefix string, data map[string]interface{}, meta interface{}) {
setDatabaseConnectionDataWithDisableEscaping(d, prefix, data)
setCloudDatabaseConnectionData(d, prefix, data, meta)
Expand Down Expand Up @@ -2138,7 +2188,7 @@ func getDBConnectionConfig(d *schema.ResourceData, engine *dbEngine, idx int,
case dbEngineHana:
result = getConnectionDetailsFromResponseWithDisableEscaping(d, prefix, resp)
case dbEngineMongoDB:
result = getConnectionDetailsFromResponseWithUserPass(d, prefix, resp)
result = getMongoDBConnectionDetailsFromResponse(d, prefix, resp)
case dbEngineMongoDBAtlas:
result = getConnectionDetailsMongoDBAtlas(d, prefix, resp)
case dbEngineMSSQL:
Expand Down
55 changes: 55 additions & 0 deletions vault/resource_database_secret_backend_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,38 @@ func TestAccDatabaseSecretBackendConnection_mongodb(t *testing.T) {
})
}

func TestAccDatabaseSecretBackendConnection_mongodb_tls(t *testing.T) {
MaybeSkipDBTests(t, dbEngineMongoDB)

// TODO: make these fatal once we auto provision the required test infrastructure.
values := testutil.SkipTestEnvUnset(t, "MONGODB_CA", "MONGODB_URL")
tlsCa, connURL := values[0], values[1]

backend := acctest.RandomWithPrefix("tf-test-db")
pluginName := dbEngineMongoDB.DefaultPluginName()
name := acctest.RandomWithPrefix("db")
resource.Test(t, resource.TestCase{
ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(context.Background(), t),
PreCheck: func() { testutil.TestAccPreCheck(t) },
CheckDestroy: testAccDatabaseSecretBackendConnectionCheckDestroy,
Steps: []resource.TestStep{
{
Config: testAccDatabaseSecretBackendConnectionConfig_mongodb_tls(name, backend, connURL, tlsCa),
Check: testComposeCheckFuncCommonDatabaseSecretBackend(name, backend, pluginName,
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "allowed_roles.#", "2"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "allowed_roles.0", "dev"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "allowed_roles.1", "prod"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "root_rotation_statements.#", "1"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "root_rotation_statements.0", "FOOBAR"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "verify_connection", "true"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "mongodb.0.connection_url", connURL),
resource.TestCheckResourceAttr("vault_database_secret_backend_connection.test", "mongodb.0.tls_ca", tlsCa+"\n"),
),
},
},
})
}

func TestAccDatabaseSecretBackendConnection_mssql(t *testing.T) {
MaybeSkipDBTests(t, dbEngineMSSQL)

Expand Down Expand Up @@ -1701,6 +1733,29 @@ resource "vault_database_secret_backend_connection" "test" {
`, path, name, connURL)
}

func testAccDatabaseSecretBackendConnectionConfig_mongodb_tls(name, path, connURL, tlsCa 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 = ["dev", "prod"]
root_rotation_statements = ["FOOBAR"]

mongodb {
connection_url = "%s"
tls_ca = <<EOT
%s
EOT
}
}
`, path, name, connURL, tlsCa)
}

func testAccDatabaseSecretBackendConnectionConfig_mssql(name, path, pluginName string, parsedURL *url.URL, containedDB bool) string {
var config string
password, _ := parsedURL.User.Password()
Expand Down