Skip to content

Commit

Permalink
Merge pull request #39328 from hashicorp/b-assume-role-empty-string
Browse files Browse the repository at this point in the history
provider: Allow empty string in `assume_role.role_arn`
  • Loading branch information
gdavison authored Sep 16, 2024
2 parents dc25114 + 811afb5 commit 2d12e5f
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .changelog/39328.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
provider: Allows `assume_role.role_arn` to be an empty string when there is a single `assume_role` entry.
```
26 changes: 21 additions & 5 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,11 +518,27 @@ func configure(ctx context.Context, provider *schema.Provider, d *schema.Resourc
if v, ok := d.GetOk("assume_role"); ok {
path := cty.GetAttrPath("assume_role")
v := v.([]any)
if len(v) == 1 && v[0] == nil {
diags = append(diags,
errs.NewAttributeRequiredWillBeError(path.IndexInt(0), "role_arn"),
)
} else if len(v) > 0 {
if len(v) == 1 {
if v[0] == nil {
diags = append(diags,
errs.NewAttributeRequiredWillBeError(path.IndexInt(0), "role_arn"),
)
} else {
l := v[0].(map[string]any)
if s, ok := l["role_arn"]; !ok || s == "" {
diags = append(diags,
errs.NewAttributeRequiredWillBeError(path.IndexInt(0), "role_arn"),
)
} else {
ar, dg := expandAssumeRoles(ctx, path, v)
diags = append(diags, dg...)
if dg.HasError() {
return nil, diags
}
config.AssumeRole = ar
}
}
} else if len(v) > 1 {
ar, dg := expandAssumeRoles(ctx, path, v)
diags = append(diags, dg...)
if dg.HasError() {
Expand Down
108 changes: 108 additions & 0 deletions internal/provider/provider_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,36 @@ func TestProviderConfig_AssumeRole(t *testing.T) { //nolint:paralleltest
},
},

// For historical reasons, this is valid
"config null string": {
Config: map[string]any{
"assume_role": []any{
map[string]any{
"role_arn": nil,
},
},
},
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials,
ExpectedDiags: diag.Diagnostics{
errs.NewAttributeRequiredWillBeError(cty.GetAttrPath("assume_role").IndexInt(0), "role_arn"),
},
},

// For historical reasons, this is valid
"config empty string": {
Config: map[string]any{
"assume_role": []any{
map[string]any{
"role_arn": "",
},
},
},
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials,
ExpectedDiags: diag.Diagnostics{
errs.NewAttributeRequiredWillBeError(cty.GetAttrPath("assume_role").IndexInt(0), "role_arn"),
},
},

"config multiple first empty": {
Config: map[string]any{
"assume_role": []any{
Expand All @@ -455,6 +485,42 @@ func TestProviderConfig_AssumeRole(t *testing.T) { //nolint:paralleltest
},
},

"config multiple first null string": {
Config: map[string]any{
"assume_role": []any{
map[string]any{
"role_arn": nil,
},
map[string]any{
"role_arn": servicemocks.MockStsAssumeRoleArn2,
"session_name": servicemocks.MockStsAssumeRoleSessionName2,
},
},
},
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials,
ExpectedDiags: diag.Diagnostics{
errs.NewAttributeRequiredError(cty.GetAttrPath("assume_role").IndexInt(0), "role_arn"),
},
},

"config multiple first empty string": {
Config: map[string]any{
"assume_role": []any{
map[string]any{
"role_arn": nil,
},
map[string]any{
"role_arn": servicemocks.MockStsAssumeRoleArn2,
"session_name": servicemocks.MockStsAssumeRoleSessionName2,
},
},
},
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials,
ExpectedDiags: diag.Diagnostics{
errs.NewAttributeRequiredError(cty.GetAttrPath("assume_role").IndexInt(0), "role_arn"),
},
},

"config multiple last empty": {
Config: map[string]any{
"assume_role": []any{
Expand All @@ -473,6 +539,48 @@ func TestProviderConfig_AssumeRole(t *testing.T) { //nolint:paralleltest
servicemocks.MockStsAssumeRoleValidEndpoint,
},
},

"config multiple last null string": {
Config: map[string]any{
"assume_role": []any{
map[string]any{
"role_arn": servicemocks.MockStsAssumeRoleArn,
"session_name": servicemocks.MockStsAssumeRoleSessionName,
},
map[string]any{
"role_arn": nil,
},
},
},
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials,
ExpectedDiags: diag.Diagnostics{
errs.NewAttributeRequiredError(cty.GetAttrPath("assume_role").IndexInt(1), "role_arn"),
},
MockStsEndpoints: []*servicemocks.MockEndpoint{
servicemocks.MockStsAssumeRoleValidEndpoint,
},
},

"config multiple last empty string": {
Config: map[string]any{
"assume_role": []any{
map[string]any{
"role_arn": servicemocks.MockStsAssumeRoleArn,
"session_name": servicemocks.MockStsAssumeRoleSessionName,
},
map[string]any{
"role_arn": "",
},
},
},
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials,
ExpectedDiags: diag.Diagnostics{
errs.NewAttributeRequiredError(cty.GetAttrPath("assume_role").IndexInt(1), "role_arn"),
},
MockStsEndpoints: []*servicemocks.MockEndpoint{
servicemocks.MockStsAssumeRoleValidEndpoint,
},
},
}

for name, tc := range testCases { //nolint:paralleltest
Expand Down

0 comments on commit 2d12e5f

Please sign in to comment.