Skip to content

Commit

Permalink
Merge pull request #25704 from kurtmc/feature/data/aws_secretsmanager…
Browse files Browse the repository at this point in the history
…_random_password_done

Implement aws_secretsmanager_random_password data source
  • Loading branch information
ewbankkit authored Jul 7, 2022
2 parents 96b498a + 069feaf commit eab0e21
Show file tree
Hide file tree
Showing 5 changed files with 263 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/25704.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-data-source
aws_secretsmanager_random_password
```
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ func Provider() *schema.Provider {

"aws_sagemaker_prebuilt_ecr_image": sagemaker.DataSourcePrebuiltECRImage(),

"aws_secretsmanager_random_password": secretsmanager.DataSourceRandomPassword(),
"aws_secretsmanager_secret": secretsmanager.DataSourceSecret(),
"aws_secretsmanager_secret_rotation": secretsmanager.DataSourceSecretRotation(),
"aws_secretsmanager_secret_version": secretsmanager.DataSourceSecretVersion(),
Expand Down
117 changes: 117 additions & 0 deletions internal/service/secretsmanager/random_password_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package secretsmanager

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
)

func DataSourceRandomPassword() *schema.Resource {
return &schema.Resource{
Read: dataSourceRandomPasswordRead,

Schema: map[string]*schema.Schema{
"exclude_characters": {
Type: schema.TypeString,
Optional: true,
},
"exclude_lowercase": {
Type: schema.TypeBool,
Optional: true,
},
"exclude_numbers": {
Type: schema.TypeBool,
Optional: true,
},
"exclude_punctuation": {
Type: schema.TypeBool,
Optional: true,
},
"exclude_uppercase": {
Type: schema.TypeBool,
Optional: true,
},
"include_space": {
Type: schema.TypeBool,
Optional: true,
},
"password_length": {
Type: schema.TypeInt,
Optional: true,
Default: 32,
},
"require_each_included_type": {
Type: schema.TypeBool,
Optional: true,
},
"random_password": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
}

func dataSourceRandomPasswordRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).SecretsManagerConn

var excludeCharacters string
if v, ok := d.GetOk("exclude_characters"); ok {
excludeCharacters = v.(string)
}
var excludeLowercase bool
if v, ok := d.GetOk("exclude_lowercase"); ok {
excludeLowercase = v.(bool)
}
var excludeNumbers bool
if v, ok := d.GetOk("exclude_numbers"); ok {
excludeNumbers = v.(bool)
}
var excludePunctuation bool
if v, ok := d.GetOk("exclude_punctuation"); ok {
excludePunctuation = v.(bool)
}
var excludeUppercase bool
if v, ok := d.GetOk("exclude_uppercase"); ok {
excludeUppercase = v.(bool)
}
var includeSpace bool
if v, ok := d.GetOk("exclude_space"); ok {
includeSpace = v.(bool)
}
var passwordLength int64
if v, ok := d.GetOk("password_length"); ok {
passwordLength = int64(v.(int))
}
var requireEachIncludedType bool
if v, ok := d.GetOk("require_each_included_type"); ok {
requireEachIncludedType = v.(bool)
}

input := &secretsmanager.GetRandomPasswordInput{
ExcludeCharacters: aws.String(excludeCharacters),
ExcludeLowercase: aws.Bool(excludeLowercase),
ExcludeNumbers: aws.Bool(excludeNumbers),
ExcludePunctuation: aws.Bool(excludePunctuation),
ExcludeUppercase: aws.Bool(excludeUppercase),
IncludeSpace: aws.Bool(includeSpace),
PasswordLength: aws.Int64(passwordLength),
RequireEachIncludedType: aws.Bool(requireEachIncludedType),
}

log.Printf("[DEBUG] Reading Secrets Manager Get Random Password: %s", input)
output, err := conn.GetRandomPassword(input)
if err != nil {
return fmt.Errorf("error reading Secrets Manager Get Random Password: %w", err)
}

d.SetId(aws.StringValue(output.RandomPassword))
d.Set("random_password", output.RandomPassword)

return nil
}
107 changes: 107 additions & 0 deletions internal/service/secretsmanager/random_password_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package secretsmanager_test

import (
"fmt"
"testing"
"unicode"

"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
)

func TestAccSecretsManagerRandomPasswordDataSource_basic(t *testing.T) {
datasourceName := "data.aws_secretsmanager_random_password.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, secretsmanager.EndpointsID),
ProviderFactories: acctest.ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccRandomPasswordDataSourceConfig_basic(),
Check: resource.ComposeTestCheckFunc(
testAccRandomPasswordDataSource(datasourceName, 40),
),
},
},
})
}

func TestAccSecretsManagerRandomPasswordDataSource_exclude(t *testing.T) {
datasourceName := "data.aws_secretsmanager_random_password.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, secretsmanager.EndpointsID),
ProviderFactories: acctest.ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccRandomPasswordDataSourceConfig_exclude(),
Check: resource.ComposeTestCheckFunc(
func(s *terraform.State) error {
dataSource, ok := s.RootModule().Resources[datasourceName]
if !ok {
return fmt.Errorf("root module has no resource called %s", datasourceName)
}

if len(dataSource.Primary.Attributes["random_password"]) != 40 {
return fmt.Errorf(
"len(%s) != %d",
dataSource.Primary.Attributes["random_password"],
40,
)
}

for _, r := range dataSource.Primary.Attributes["random_password"] {
if !(unicode.IsLower(r) && unicode.IsLetter(r)) {
return fmt.Errorf("expected only lowercase letters")
}
}

return nil
},
),
},
},
})
}

func testAccRandomPasswordDataSource(datasourceName string, expectedLength int) resource.TestCheckFunc {
return func(s *terraform.State) error {
dataSource, ok := s.RootModule().Resources[datasourceName]
if !ok {
return fmt.Errorf("root module has no resource called %s", datasourceName)
}

if len(dataSource.Primary.Attributes["random_password"]) != expectedLength {
return fmt.Errorf(
"len(%s) != %d",
dataSource.Primary.Attributes["random_password"],
expectedLength,
)
}

return nil
}
}

func testAccRandomPasswordDataSourceConfig_basic() string {
return `
data "aws_secretsmanager_random_password" "test" {
password_length = 40
}
`
}

func testAccRandomPasswordDataSourceConfig_exclude() string {
return `
data "aws_secretsmanager_random_password" "test" {
password_length = 40
exclude_numbers = true
exclude_uppercase = true
exclude_punctuation = true
}
`
}
35 changes: 35 additions & 0 deletions website/docs/d/secretsmanager_random_password.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
subcategory: "Secrets Manager"
layout: "aws"
page_title: "AWS: aws_secretsmanager_random_password"
description: |-
Generate a random password
---

# Data Source: aws_secretsmanager_random_password

Generate a random password.

## Example Usage

```terraform
data "aws_secretsmanager_random_password" "test" {
password_length = 50
exclude_numbers = true
}
```

## Argument Reference

* `exclude_characters` - (Optional) A string of the characters that you don't want in the password.
* `exclude_lowercase` - (Optional) Specifies whether to exclude lowercase letters from the password.
* `exclude_numbers` - (Optional) Specifies whether to exclude numbers from the password.
* `exclude_punctuation` - (Optional) Specifies whether to exclude the following punctuation characters from the password: ``! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ .``
* `exclude_uppercase` - (Optional) Specifies whether to exclude uppercase letters from the password.
* `include_space` - (Optional) Specifies whether to include the space character.
* `password_length` - (Optional) The length of the password.
* `require_each_included_type` - (Optional) Specifies whether to include at least one upper and lowercase letter, one number, and one punctuation.

## Attributes Reference

* `random_password` - The random password.

0 comments on commit eab0e21

Please sign in to comment.