diff --git a/.secrets.baseline b/.secrets.baseline index c17a30a0c8..50b357c433 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.mod|go.sum|.*.map|^.secrets.baseline$", "lines": null }, - "generated_at": "2024-02-12T15:12:54Z", + "generated_at": "2024-02-14T08:29:34Z", "plugins_used": [ { "name": "ArtifactoryDetector" @@ -846,7 +846,7 @@ "hashed_secret": "c8b6f5ef11b9223ac35a5663975a466ebe7ebba9", "is_secret": false, "is_verified": false, - "line_number": 1835, + "line_number": 1834, "type": "Secret Keyword", "verified_result": null }, @@ -854,7 +854,7 @@ "hashed_secret": "8abf4899c01104241510ba87685ad4de76b0c437", "is_secret": false, "is_verified": false, - "line_number": 1841, + "line_number": 1840, "type": "Secret Keyword", "verified_result": null } @@ -3406,7 +3406,7 @@ "hashed_secret": "3046d9f6cfaaeea6eed9bb7a4ab010fe49b0cfd4", "is_secret": false, "is_verified": false, - "line_number": 157, + "line_number": 186, "type": "Secret Keyword", "verified_result": null }, @@ -3414,7 +3414,7 @@ "hashed_secret": "b732fb611fd46a38e8667f9972e0cde777fbe37f", "is_secret": false, "is_verified": false, - "line_number": 273, + "line_number": 314, "type": "Secret Keyword", "verified_result": null } @@ -3740,7 +3740,7 @@ "hashed_secret": "b732fb611fd46a38e8667f9972e0cde777fbe37f", "is_secret": false, "is_verified": false, - "line_number": 354, + "line_number": 390, "type": "Secret Keyword", "verified_result": null } @@ -3750,7 +3750,7 @@ "hashed_secret": "6d12fda3835a9f315af351d7df4ff82dbcfdb2e6", "is_secret": false, "is_verified": false, - "line_number": 22, + "line_number": 23, "type": "Secret Keyword", "verified_result": null }, @@ -3758,7 +3758,7 @@ "hashed_secret": "347cd9c53ff77d41a7b22aa56c7b4efaf54658e3", "is_secret": false, "is_verified": false, - "line_number": 111, + "line_number": 127, "type": "Secret Keyword", "verified_result": null } @@ -3798,7 +3798,7 @@ "hashed_secret": "f855f5027fd8fdb2df3f6a6f1cf858fffcbedb0c", "is_secret": false, "is_verified": false, - "line_number": 96613, + "line_number": 96618, "type": "Secret Keyword", "verified_result": null }, @@ -3806,7 +3806,7 @@ "hashed_secret": "5fb0fa884132a8724a8d7cba55853737e442adbd", "is_secret": false, "is_verified": false, - "line_number": 119402, + "line_number": 119412, "type": "Secret Keyword", "verified_result": null }, @@ -3814,7 +3814,7 @@ "hashed_secret": "1e5c2f367f02e47a8c160cda1cd9d91decbac441", "is_secret": false, "is_verified": false, - "line_number": 151610, + "line_number": 151620, "type": "Secret Keyword", "verified_result": null } @@ -4906,7 +4906,7 @@ "hashed_secret": "e3efaa78f2f6ca38f70ded91b232d8dac947315d", "is_secret": false, "is_verified": false, - "line_number": 31, + "line_number": 37, "type": "Secret Keyword", "verified_result": null }, @@ -4914,7 +4914,7 @@ "hashed_secret": "d47dcacc720a39e236679ac3e311a0d58bb6519e", "is_secret": false, "is_verified": false, - "line_number": 121, + "line_number": 134, "type": "Secret Keyword", "verified_result": null }, @@ -4922,7 +4922,7 @@ "hashed_secret": "e66e7d67fdf3c596c435fc7828b13205e4950a0f", "is_secret": false, "is_verified": false, - "line_number": 123, + "line_number": 136, "type": "Secret Keyword", "verified_result": null } diff --git a/go.mod b/go.mod index 2ad4fb9230..1ecc0e70ab 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/IBM/push-notifications-go-sdk v0.0.0-20210310100607-5790b96c47f5 github.com/IBM/scc-go-sdk/v5 v5.1.4 github.com/IBM/schematics-go-sdk v0.2.3 - github.com/IBM/secrets-manager-go-sdk/v2 v2.0.2 + github.com/IBM/secrets-manager-go-sdk/v2 v2.0.3 github.com/IBM/vpc-beta-go-sdk v0.6.0 github.com/IBM/vpc-go-sdk v0.48.0 github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 diff --git a/go.sum b/go.sum index ec313213ee..ca0439e0b0 100644 --- a/go.sum +++ b/go.sum @@ -176,6 +176,8 @@ github.com/IBM/schematics-go-sdk v0.2.3 h1:lgTt0Sbudii3cuSk1YSQgrtiZAXDbBABAoVj3 github.com/IBM/schematics-go-sdk v0.2.3/go.mod h1:Tw2OSAPdpC69AxcwoyqcYYaGTTW6YpERF9uNEU+BFRQ= github.com/IBM/secrets-manager-go-sdk/v2 v2.0.2 h1:+Svh1OmoFxMBnZQSOUtp2UUzrOGFsSQlE5TFL/ptJco= github.com/IBM/secrets-manager-go-sdk/v2 v2.0.2/go.mod h1:WII+LS4VkQYykmq65NWSuPb5xGNvsqkcK1aCWZoU2x4= +github.com/IBM/secrets-manager-go-sdk/v2 v2.0.3 h1:28x9ksuRllUbDHmbwk15snNZgaEDc+BtY5Ey8oMqKn8= +github.com/IBM/secrets-manager-go-sdk/v2 v2.0.3/go.mod h1:5gq8D8uWOIbqOm1uztay6lpOysgJaxxEsaVZLWGWb40= github.com/IBM/vpc-beta-go-sdk v0.6.0 h1:wfM3AcW3zOM3xsRtZ+EA6+sESlGUjQ6Yf4n5QQyz4uc= github.com/IBM/vpc-beta-go-sdk v0.6.0/go.mod h1:fzHDAQIqH/5yJmYsKodKHLcqxMDT+yfH6vZjdiw8CQA= github.com/IBM/vpc-go-sdk v0.47.0 h1:2Qcjd4zQQRYjz+y4ZMDP6+aWGifyXCZ9uMmlpW7p9To= diff --git a/ibm/service/secretsmanager/data_source_ibm_sm_service_credentials_secret.go b/ibm/service/secretsmanager/data_source_ibm_sm_service_credentials_secret.go index bc5c17a8c9..c9f1158134 100644 --- a/ibm/service/secretsmanager/data_source_ibm_sm_service_credentials_secret.go +++ b/ibm/service/secretsmanager/data_source_ibm_sm_service_credentials_secret.go @@ -415,7 +415,7 @@ func dataSourceIbmSmServiceCredentialsSecretRotationPolicyToMap(model *secretsma return modelMap, nil } -func dataSourceIbmSmServiceCredentialsSecretSourceServiceToMap(sourceService *secretsmanagerv2.ServiceCredentialsSecretSourceService) (map[string]interface{}, error) { +func dataSourceIbmSmServiceCredentialsSecretSourceServiceToMap(sourceService *secretsmanagerv2.ServiceCredentialsSecretSourceServiceRO) (map[string]interface{}, error) { mainModelMap := make(map[string]interface{}) if sourceService.Instance != nil { instanceMap := make(map[string]interface{}) diff --git a/ibm/service/secretsmanager/data_source_ibm_sm_service_credentials_secret_metadata.go b/ibm/service/secretsmanager/data_source_ibm_sm_service_credentials_secret_metadata.go index 141e0f9e6d..9b28662a5a 100644 --- a/ibm/service/secretsmanager/data_source_ibm_sm_service_credentials_secret_metadata.go +++ b/ibm/service/secretsmanager/data_source_ibm_sm_service_credentials_secret_metadata.go @@ -403,7 +403,7 @@ func dataSourceIbmSmServiceCredentialsSecretMetadataRotationPolicyToMap(model *s return modelMap, nil } -func dataSourceIbmSmServiceCredentialsSecretMetadataSourceServiceToMap(sourceService *secretsmanagerv2.ServiceCredentialsSecretSourceService) (map[string]interface{}, error) { +func dataSourceIbmSmServiceCredentialsSecretMetadataSourceServiceToMap(sourceService *secretsmanagerv2.ServiceCredentialsSecretSourceServiceRO) (map[string]interface{}, error) { mainModelMap := make(map[string]interface{}) if sourceService.Instance != nil { instanceMap := make(map[string]interface{}) diff --git a/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret.go b/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret.go index a1119f17e0..262b037ad5 100644 --- a/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret.go +++ b/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret.go @@ -115,6 +115,35 @@ func DataSourceIbmSmUsernamePasswordSecret() *schema.Resource { Computed: true, Description: "The number of versions of the secret.", }, + "password_generation_policy": &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Description: "Policy for auto-generated passwords.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "length": &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + Description: "The length of auto-generated passwords.", + }, + "include_digits": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + Description: "Include digits in auto-generated passwords.", + }, + "include_symbols": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + Description: "Include symbols in auto-generated passwords.", + }, + "include_uppercase": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + Description: "Include uppercase letters in auto-generated passwords.", + }, + }, + }, + }, "rotation": &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -257,6 +286,18 @@ func dataSourceIbmSmUsernamePasswordSecretRead(context context.Context, d *schem return diag.FromErr(fmt.Errorf("Error setting rotation %s", err)) } + passwordPolicy := []map[string]interface{}{} + if usernamePasswordSecret.PasswordGenerationPolicy != nil { + modelMap, err := passwordGenerationPolicyToMap(usernamePasswordSecret.PasswordGenerationPolicy) + if err != nil { + return diag.FromErr(err) + } + passwordPolicy = append(passwordPolicy, modelMap) + } + if err = d.Set("password_generation_policy", passwordPolicy); err != nil { + return diag.FromErr(fmt.Errorf("Error setting password_generation_policy %s", err)) + } + if err = d.Set("expiration_date", DateTimeToRFC3339(usernamePasswordSecret.ExpirationDate)); err != nil { return diag.FromErr(fmt.Errorf("Error setting expiration_date: %s", err)) } diff --git a/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_metadata.go b/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_metadata.go index 6eada6eb8b..cc6756f00c 100644 --- a/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_metadata.go +++ b/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_metadata.go @@ -107,6 +107,35 @@ func DataSourceIbmSmUsernamePasswordSecretMetadata() *schema.Resource { Computed: true, Description: "The number of versions of the secret.", }, + "password_generation_policy": &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Description: "Policy for auto-generated passwords.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "length": &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + Description: "The length of auto-generated passwords.", + }, + "include_digits": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + Description: "Include digits in auto-generated passwords.", + }, + "include_symbols": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + Description: "Include symbols in auto-generated passwords.", + }, + "include_uppercase": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + Description: "Include uppercase letters in auto-generated passwords.", + }, + }, + }, + }, "rotation": &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -251,6 +280,18 @@ func dataSourceIbmSmUsernamePasswordSecretMetadataRead(context context.Context, return diag.FromErr(fmt.Errorf("Error setting rotation %s", err)) } + passwordPolicy := []map[string]interface{}{} + if usernamePasswordSecretMetadata.PasswordGenerationPolicy != nil { + modelMap, err := passwordGenerationPolicyToMap(usernamePasswordSecretMetadata.PasswordGenerationPolicy) + if err != nil { + return diag.FromErr(err) + } + passwordPolicy = append(passwordPolicy, modelMap) + } + if err = d.Set("password_generation_policy", passwordPolicy); err != nil { + return diag.FromErr(fmt.Errorf("Error setting password_generation_policy %s", err)) + } + if err = d.Set("expiration_date", DateTimeToRFC3339(usernamePasswordSecretMetadata.ExpirationDate)); err != nil { return diag.FromErr(fmt.Errorf("Error setting expiration_date: %s", err)) } diff --git a/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_metadata_test.go b/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_metadata_test.go index dff01d9be9..2cfc9639df 100644 --- a/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_metadata_test.go +++ b/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_metadata_test.go @@ -30,6 +30,7 @@ func TestAccIbmSmUsernamePasswordSecretMetadataDataSourceBasic(t *testing.T) { resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret_metadata.sm_username_password_secret_metadata", "updated_at"), resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret_metadata.sm_username_password_secret_metadata", "versions_total"), resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret_metadata.sm_username_password_secret_metadata", "rotation.#"), + resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret_metadata.sm_username_password_secret_metadata", "password_generation_policy.#"), ), }, }, diff --git a/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_test.go b/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_test.go index 57c04216e8..0a59be3abd 100644 --- a/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_test.go +++ b/ibm/service/secretsmanager/data_source_ibm_sm_username_password_secret_test.go @@ -30,6 +30,7 @@ func TestAccIbmSmUsernamePasswordSecretDataSourceBasic(t *testing.T) { resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret.sm_username_password_secret", "updated_at"), resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret.sm_username_password_secret", "versions_total"), resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret.sm_username_password_secret", "rotation.#"), + resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret.sm_username_password_secret", "password_generation_policy.#"), resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret.sm_username_password_secret", "username"), resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret.sm_username_password_secret", "password"), resource.TestCheckResourceAttrSet("data.ibm_sm_username_password_secret.sm_username_password_secret_by_name", "name"), diff --git a/ibm/service/secretsmanager/resource_ibm_sm_service_credentials_secret.go b/ibm/service/secretsmanager/resource_ibm_sm_service_credentials_secret.go index 8beb6980d2..a48a3d2636 100644 --- a/ibm/service/secretsmanager/resource_ibm_sm_service_credentials_secret.go +++ b/ibm/service/secretsmanager/resource_ibm_sm_service_credentials_secret.go @@ -698,7 +698,7 @@ func resourceIbmSmServiceCredentialsSecretRotationPolicyToMap(modelIntf secretsm return modelMap, nil } -func resourceIbmSmServiceCredentialsSecretSourceServiceToMap(sourceService *secretsmanagerv2.ServiceCredentialsSecretSourceService) (map[string]interface{}, error) { +func resourceIbmSmServiceCredentialsSecretSourceServiceToMap(sourceService *secretsmanagerv2.ServiceCredentialsSecretSourceServiceRO) (map[string]interface{}, error) { mainModelMap := make(map[string]interface{}) if sourceService.Instance != nil { instanceMap := make(map[string]interface{}) diff --git a/ibm/service/secretsmanager/resource_ibm_sm_username_password_secret.go b/ibm/service/secretsmanager/resource_ibm_sm_username_password_secret.go index 5975f94dac..2a21a8935f 100644 --- a/ibm/service/secretsmanager/resource_ibm_sm_username_password_secret.go +++ b/ibm/service/secretsmanager/resource_ibm_sm_username_password_secret.go @@ -122,10 +122,46 @@ func ResourceIbmSmUsernamePasswordSecret() *schema.Resource { }, "password": &schema.Schema{ Type: schema.TypeString, - Required: true, + Optional: true, + Computed: true, Sensitive: true, Description: "The password that is assigned to the secret.", }, + "password_generation_policy": &schema.Schema{ + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Policy for auto-generated passwords.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "length": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Default: 32, + Description: "The length of auto-generated passwords.", + }, + "include_digits": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Include digits in auto-generated passwords.", + }, + "include_symbols": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Include symbols in auto-generated passwords.", + }, + "include_uppercase": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Include uppercase letters in auto-generated passwords.", + }, + }, + }, + }, "created_by": &schema.Schema{ Type: schema.TypeString, Computed: true, @@ -354,6 +390,14 @@ func resourceIbmSmUsernamePasswordSecretRead(context context.Context, d *schema. return diag.FromErr(fmt.Errorf("Error setting password: %s", err)) } + passwordPolicyMap, err := passwordGenerationPolicyToMap(secret.PasswordGenerationPolicy) + if err != nil { + return diag.FromErr(err) + } + if err = d.Set("password_generation_policy", []map[string]interface{}{passwordPolicyMap}); err != nil { + return diag.FromErr(fmt.Errorf("Error setting password generation policy: %s", err)) + } + // Call get version metadata API to get the current version_custom_metadata getVersionMetdataOptions := &secretsmanagerv2.GetSecretVersionMetadataOptions{} getVersionMetdataOptions.SetSecretID(secretId) @@ -441,6 +485,16 @@ func resourceIbmSmUsernamePasswordSecretUpdate(context context.Context, d *schem } } + if d.HasChange("password_generation_policy") { + passwordPolicyModel, err := mapToPasswordGenerationPolicyPatch(d.Get("password_generation_policy").([]interface{})[0].(map[string]interface{})) + if err != nil { + log.Printf("[DEBUG] UpdateSecretMetadataWithContext failed: Reading password_generation_policy parameter failed: %s", err) + return diag.FromErr(fmt.Errorf("UpdateSecretMetadataWithContext failed: Reading password_generation_policy parameter failed: %s", err)) + } + patchVals.PasswordGenerationPolicy = passwordPolicyModel + hasChange = true + } + if hasChange { updateSecretMetadataOptions.SecretMetadataPatch, _ = patchVals.AsPatch() _, response, err := secretsManagerClient.UpdateSecretMetadataWithContext(context, updateSecretMetadataOptions) @@ -574,6 +628,13 @@ func resourceIbmSmUsernamePasswordSecretMapToSecretPrototype(d *schema.ResourceD } model.Rotation = RotationModel } + if _, ok := d.GetOk("password_generation_policy"); ok { + passwordPolicyModel, err := mapToPasswordGenerationPolicy(d.Get("password_generation_policy").([]interface{})[0].(map[string]interface{})) + if err != nil { + return model, err + } + model.PasswordGenerationPolicy = passwordPolicyModel + } return model, nil } @@ -635,3 +696,58 @@ func rotationAttributesDiffSuppress(key, oldValue, newValue string, d *schema.Re return oldValue == newValue } + +func passwordGenerationPolicyToMap(model *secretsmanagerv2.PasswordGenerationPolicyRO) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + if model.Length != nil { + modelMap["length"] = model.Length + } + if model.IncludeDigits != nil { + modelMap["include_digits"] = model.IncludeDigits + } + if model.IncludeSymbols != nil { + modelMap["include_symbols"] = model.IncludeSymbols + } + if model.IncludeUppercase != nil { + modelMap["include_uppercase"] = model.IncludeUppercase + } + return modelMap, nil +} + +func mapToPasswordGenerationPolicy(modelMap map[string]interface{}) (*secretsmanagerv2.PasswordGenerationPolicy, error) { + model := &secretsmanagerv2.PasswordGenerationPolicy{} + if modelMap["length"].(int) == 0 { + model.Length = nil + } else { + model.Length = core.Int64Ptr(int64(modelMap["length"].(int))) + } + if modelMap["include_digits"] != nil { + model.IncludeDigits = core.BoolPtr(modelMap["include_digits"].(bool)) + } + if modelMap["include_symbols"] != nil { + model.IncludeSymbols = core.BoolPtr(modelMap["include_symbols"].(bool)) + } + if modelMap["include_uppercase"] != nil { + model.IncludeUppercase = core.BoolPtr(modelMap["include_uppercase"].(bool)) + } + return model, nil +} + +func mapToPasswordGenerationPolicyPatch(modelMap map[string]interface{}) (*secretsmanagerv2.PasswordGenerationPolicyPatch, error) { + model := &secretsmanagerv2.PasswordGenerationPolicyPatch{} + if modelMap["length"].(int) == 0 { + model.Length = nil + } else { + model.Length = core.Int64Ptr(int64(modelMap["length"].(int))) + } + if modelMap["include_digits"] != nil { + model.IncludeDigits = core.BoolPtr(modelMap["include_digits"].(bool)) + } + if modelMap["include_symbols"] != nil { + model.IncludeSymbols = core.BoolPtr(modelMap["include_symbols"].(bool)) + } + if modelMap["include_uppercase"] != nil { + model.IncludeUppercase = core.BoolPtr(modelMap["include_uppercase"].(bool)) + } + return model, nil +} diff --git a/ibm/service/secretsmanager/resource_ibm_sm_username_password_secret_test.go b/ibm/service/secretsmanager/resource_ibm_sm_username_password_secret_test.go index e7fbfada20..2a3a9de876 100644 --- a/ibm/service/secretsmanager/resource_ibm_sm_username_password_secret_test.go +++ b/ibm/service/secretsmanager/resource_ibm_sm_username_password_secret_test.go @@ -4,6 +4,7 @@ package secretsmanager_test import ( + "encoding/json" "fmt" "strings" "testing" @@ -22,6 +23,21 @@ var password = "password" var modifiedPassword = "modified_password" var usernamePasswordSecretName = "terraform-test-username-secret" var modifiedUsernamePasswordSecretName = "modified-terraform-test-username-secret" +var passwordGenerationPolicy = `{ + length = 17 + include_digits = false + include_symbols = false + include_uppercase = true + }` +var passwordGenerationPolicyJSON = "{\"length\":17,\"include_digits\":false,\"include_symbols\":false,\"include_uppercase\":true}" + +var modifiedPasswordGenerationPolicy = `{ + length = 26 + include_digits = true + include_symbols = true + include_uppercase = false + }` +var modifiedPasswordGenerationPolicyJSON = "{\"length\":26,\"include_digits\":true,\"include_symbols\":true,\"include_uppercase\":false}" func TestAccIbmSmUsernamePasswordSecretBasic(t *testing.T) { resourceName := "ibm_sm_username_password_secret.sm_username_password_secret_basic" @@ -113,6 +129,7 @@ var usernamePasswordSecretFullConfigFormat = ` custom_metadata = %s secret_group_id = "default" rotation %s + password_generation_policy %s }` func usernamePasswordSecretConfigBasic() string { @@ -122,13 +139,14 @@ func usernamePasswordSecretConfigBasic() string { func usernamePasswordSecretConfigAllArgs() string { return fmt.Sprintf(usernamePasswordSecretFullConfigFormat, acc.SecretsManagerInstanceID, acc.SecretsManagerInstanceRegion, - usernamePasswordSecretName, description, label, username, password, expirationDate, customMetadata, rotationPolicy) + usernamePasswordSecretName, description, label, username, password, expirationDate, customMetadata, rotationPolicy, + passwordGenerationPolicy) } func usernamePasswordSecretConfigUpdated() string { return fmt.Sprintf(usernamePasswordSecretFullConfigFormat, acc.SecretsManagerInstanceID, acc.SecretsManagerInstanceRegion, modifiedUsernamePasswordSecretName, modifiedDescription, modifiedLabel, modifiedUsername, modifiedPassword, - modifiedExpirationDate, modifiedCustomMetadata, modifiedRotationPolicy) + modifiedExpirationDate, modifiedCustomMetadata, modifiedRotationPolicy, modifiedPasswordGenerationPolicy) } func testAccCheckIbmSmUsernamePasswordSecretCreated(n string) resource.TestCheckFunc { @@ -166,6 +184,10 @@ func testAccCheckIbmSmUsernamePasswordSecretCreated(n string) resource.TestCheck if err := verifyAttr(getAutoRotate(secret.Rotation), "true", "auto_rotate"); err != nil { return err } + pwdPolicyJson, _ := json.Marshal(secret.PasswordGenerationPolicy) + if err := verifyAttr(string(pwdPolicyJson), passwordGenerationPolicyJSON, "password_generation_policy"); err != nil { + return err + } if err := verifyAttr(getRotationUnit(secret.Rotation), "day", "rotation unit"); err != nil { return err } @@ -217,6 +239,10 @@ func testAccCheckIbmSmUsernamePasswordSecretUpdated(n string) resource.TestCheck if err := verifyAttr(getRotationInterval(secret.Rotation), "2", "rotation interval after update"); err != nil { return err } + pwdPolicyJson, _ := json.Marshal(secret.PasswordGenerationPolicy) + if err := verifyAttr(string(pwdPolicyJson), modifiedPasswordGenerationPolicyJSON, "password_generation_policy"); err != nil { + return err + } return nil } } diff --git a/website/docs/d/sm_username_password_secret.html.markdown b/website/docs/d/sm_username_password_secret.html.markdown index 64768e067f..a376c69cb5 100644 --- a/website/docs/d/sm_username_password_secret.html.markdown +++ b/website/docs/d/sm_username_password_secret.html.markdown @@ -83,13 +83,20 @@ In addition to all argument references listed, you can access the following attr * `password` - (String) The password that is assigned to the secret. * Constraints: The maximum length is `64` characters. The minimum length is `6` characters. The value must match regular expression `/[A-Za-z0-9+-=.]*/`. +* `password_generation_policy` - (List) Policy for auto-generated passwords. + Nested scheme for **password_generation_policy**: + * `length` - (Integer) The length of auto-generated passwords. + * `include_digits` - (Boolean) Include digits in auto-generated passwords. + * `include_symbols` - (Boolean) Include symbols in auto-generated passwords. + * `include_uppercase` - (Boolean) Include uppercase letters in auto-generated passwords. + * `rotation` - (List) Determines whether Secrets Manager rotates your secrets automatically. Nested scheme for **rotation**: - * `auto_rotate` - (Boolean) Determines whether Secrets Manager rotates your secret automatically.Default is `false`. If `auto_rotate` is set to `true` the service rotates your secret based on the defined interval. - * `interval` - (Integer) The length of the secret rotation time interval. - * Constraints: The minimum value is `1`. - * `unit` - (String) The units for the secret rotation time interval. - * Constraints: Allowable values are: `day`, `month`. + * `auto_rotate` - (Boolean) Determines whether Secrets Manager rotates your secret automatically.Default is `false`. If `auto_rotate` is set to `true` the service rotates your secret based on the defined interval. + * `interval` - (Integer) The length of the secret rotation time interval. + * Constraints: The minimum value is `1`. + * `unit` - (String) The units for the secret rotation time interval. + * Constraints: Allowable values are: `day`, `month`. * `secret_group_id` - (String) A v4 UUID identifier, or `default` secret group. * Constraints: The maximum length is `36` characters. The minimum length is `7` characters. The value must match regular expression `/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|default)$/`. diff --git a/website/docs/d/sm_username_password_secret_metadata.html.markdown b/website/docs/d/sm_username_password_secret_metadata.html.markdown index 781f524f1a..9e26afd431 100644 --- a/website/docs/d/sm_username_password_secret_metadata.html.markdown +++ b/website/docs/d/sm_username_password_secret_metadata.html.markdown @@ -64,6 +64,13 @@ In addition to all argument references listed, you can access the following attr * `next_rotation_date` - (String) The date that the secret is scheduled for automatic rotation.The service automatically creates a new version of the secret on its next rotation date. This field exists only for secrets that have an existing rotation policy. +* `password_generation_policy` - (List) Policy for auto-generated passwords. + Nested scheme for **password_generation_policy**: + * `length` - (Integer) The length of auto-generated passwords. + * `include_digits` - (Boolean) Include digits in auto-generated passwords. + * `include_symbols` - (Boolean) Include symbols in auto-generated passwords. + * `include_uppercase` - (Boolean) Include uppercase letters in auto-generated passwords. + * `rotation` - (List) Determines whether Secrets Manager rotates your secrets automatically. Nested scheme for **rotation**: * `auto_rotate` - (Boolean) Determines whether Secrets Manager rotates your secret automatically.Default is `false`. If `auto_rotate` is set to `true` the service rotates your secret based on the defined interval. diff --git a/website/docs/r/sm_username_password_secret.html.markdown b/website/docs/r/sm_username_password_secret.html.markdown index fdb4605f15..40a776d161 100644 --- a/website/docs/r/sm_username_password_secret.html.markdown +++ b/website/docs/r/sm_username_password_secret.html.markdown @@ -20,6 +20,12 @@ resource "ibm_sm_username_password_secret" "sm_username_password_secret" { description = "Extended description for this secret." expiration_date = "2024-04-12T23:20:50Z" labels = ["my-label"] + password_generation_policy { + length = 32 + include_digits = true + include_symbols = true + include_uppercase = true + } rotation { auto_rotate = true interval = 1 @@ -48,8 +54,15 @@ Review the argument reference that you can specify for your resource. * `expiration_date` - (Optional, String) The date a secret is expired. The date format follows RFC 3339. * `labels` - (Optional, List) Labels that you can use to search for secrets in your instance.Up to 30 labels can be created. * Constraints: The list items must match regular expression `/(.*?)/`. The maximum length is `30` items. The minimum length is `0` items. -* `password` - (Required, Forces new resource, String) The password that is assigned to the secret. - * Constraints: The maximum length is `64` characters. The minimum length is `6` characters. The value must match regular expression `/[A-Za-z0-9+-=.]*/`. +* `password` - (Optional, String) The password that is assigned to the secret. If `password` is omitted, Secrets Manager generates a new random password for your secret. + * Constraints: The maximum length is `64` characters. The minimum length is `6` characters. +* `password_generation_policy` - (List) Policy for auto-generated passwords. + Nested scheme for **password_generation_policy**: + * `length` - (Optional, Integer) The length of auto-generated passwords. Default is 32. + * Constraints: The minimum value is `12`. The maximum value is `256`. + * `include_digits` - (Optional, Boolean) Include digits in auto-generated passwords. Default is true. + * `include_symbols` - (Optional, Boolean) Include symbols in auto-generated passwords. Default is true. + * `include_uppercase` - (Optional, Boolean) Include uppercase letters in auto-generated passwords. Default is true. * `rotation` - (Optional, List) Determines whether Secrets Manager rotates your secrets automatically. Nested scheme for **rotation**: * `auto_rotate` - (Optional, Boolean) Determines whether Secrets Manager rotates your secret automatically.Default is `false`. If `auto_rotate` is set to `true` the service rotates your secret based on the defined interval.