Skip to content

Commit

Permalink
Add company variable type = secret tests (#358)
Browse files Browse the repository at this point in the history
* Add company variable `type` = `secret` tests

* fix secret type value issue

* update docs

* terrafmt

* changelog
  • Loading branch information
patrickcping authored Aug 19, 2024
1 parent d53b699 commit 9752057
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .changelog/358.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
`resource/davinci_variable`: Fix "Provider produced inconsistent result after apply" when defining a variable of `type` = `secret`.
```
4 changes: 2 additions & 2 deletions docs/resources/variable.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,12 @@ resource "davinci_variable" "my_awesome_usercontext_variable" {
### Optional

- `description` (String) A string that specifies the description of the variable.
- `empty_value` (Boolean) A boolean that specifies whether the variable's `value` must be kept as an empty string. Conflicts with `value`, `empty_value`.
- `empty_value` (Boolean) A boolean that specifies whether the variable's `value` must be kept as an empty string. Conflicts with `value`.
- `flow_id` (String) A string that specifies the ID of the flow to which the variable is assigned. This field is required when the `context` field is set to `flow`. Must be a valid PingOne resource ID. This field is immutable and will trigger a replace plan if changed.
- `max` (Number) An integer that specifies the maximum value of the variable, if the `type` parameter is set as `number`. Defaults to `2000`.
- `min` (Number) An integer that specifies the minimum value of the variable, if the `type` parameter is set as `number`. Defaults to `0`.
- `mutable` (Boolean) A boolean that specifies whether the variable is mutable. If `true`, the variable can be modified by the flow. If `false`, the variable is read-only and cannot be modified by the flow. Defaults to `true`.
- `value` (String, Sensitive) A string that specifies the default value of the variable, the type will be inferred from the value specified in the `type` parameter. If left blank or omitted, the resource will not track the variable's value in state. If the variable value should be tracked in state as an empty string, use the `empty_value` parameter. Conflicts with `value`, `empty_value`.
- `value` (String, Sensitive) A string that specifies the default value of the variable, the type will be inferred from the value specified in the `type` parameter. If left blank or omitted, the resource will not track the variable's value in state. If the variable value should be tracked in state as an empty string, use the `empty_value` parameter. Note that if the `type` is `secret`, the provider will not be able to remediate the value's configuration drift in the DaVinci service. Conflicts with `empty_value`.

### Read-Only

Expand Down
10 changes: 6 additions & 4 deletions internal/service/davinci/resource_variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,16 @@ func (r *VariableResource) Schema(ctx context.Context, req resource.SchemaReques
).DefaultValue(true)

valueDescription := framework.SchemaAttributeDescriptionFromMarkdown(
"A string that specifies the default value of the variable, the type will be inferred from the value specified in the `type` parameter. If left blank or omitted, the resource will not track the variable's value in state. If the variable value should be tracked in state as an empty string, use the `empty_value` parameter.",
).ConflictsWith([]string{"value", "empty_value"})
"A string that specifies the default value of the variable, the type will be inferred from the value specified in the `type` parameter. If left blank or omitted, the resource will not track the variable's value in state. If the variable value should be tracked in state as an empty string, use the `empty_value` parameter. Note that if the `type` is `secret`, the provider will not be able to remediate the value's configuration drift in the DaVinci service.",
).ConflictsWith([]string{"empty_value"})

valueServiceDescription := framework.SchemaAttributeDescriptionFromMarkdown(
"A string that specifies the value of the variable in the service, the type will be inferred from the value specified in the `type` parameter.",
)

EmptyValueDescription := framework.SchemaAttributeDescriptionFromMarkdown(
"A boolean that specifies whether the variable's `value` must be kept as an empty string.",
).ConflictsWith([]string{"value", "empty_value"})
).ConflictsWith([]string{"value"})

minDescription := framework.SchemaAttributeDescriptionFromMarkdown(
"An integer that specifies the minimum value of the variable, if the `type` parameter is set as `number`.",
Expand Down Expand Up @@ -728,7 +728,9 @@ func (p *VariableResourceModel) toState(apiObject map[string]davinci.Variable) d
// }

if v := variableObject.Value; v != nil && *v != "" {
p.ValueService = framework.StringToTF(*v)
value := *v
value = regexp.MustCompile(`^\*+$`).ReplaceAllString(value, p.Value.ValueString())
p.ValueService = framework.StringToTF(value)
} else {
p.ValueService = types.StringNull()
}
Expand Down
90 changes: 90 additions & 0 deletions internal/service/davinci/resource_variable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ func testAccResourceVariable_Full_CompanyContext(t *testing.T, withBootstrapConf

name := resourceName

var variableID, environmentID string

fullStep := resource.TestStep{
Config: testAccResourceVariable_CompanyContext_Full_Hcl(resourceName, name, withBootstrapConfig),
Check: resource.ComposeTestCheckFunc(
Expand Down Expand Up @@ -120,6 +122,45 @@ func testAccResourceVariable_Full_CompanyContext(t *testing.T, withBootstrapConf
),
}

secretDynamicStep := resource.TestStep{
Config: testAccResourceVariable_CompanyContext_SecretDynamic_Hcl(resourceName, name, withBootstrapConfig),
Check: resource.ComposeTestCheckFunc(
davinci.Variable_GetIDs(resourceFullName, &environmentID, &variableID),
resource.TestMatchResourceAttr(resourceFullName, "id", regexp.MustCompile(`^[a-zA-Z0-9]+##SK##company$`)),
resource.TestMatchResourceAttr(resourceFullName, "environment_id", verify.P1ResourceIDRegexpFullString),
resource.TestCheckResourceAttr(resourceFullName, "name", name),
resource.TestCheckResourceAttr(resourceFullName, "context", "company"),
resource.TestCheckNoResourceAttr(resourceFullName, "description"),
resource.TestCheckNoResourceAttr(resourceFullName, "value"),
resource.TestCheckNoResourceAttr(resourceFullName, "empty_value"),
resource.TestCheckResourceAttr(resourceFullName, "type", "secret"),
resource.TestCheckResourceAttr(resourceFullName, "min", "0"),
resource.TestCheckResourceAttr(resourceFullName, "max", "2000"),
resource.TestCheckResourceAttr(resourceFullName, "mutable", "true"),
),
}

secretStaticStep := resource.TestStep{
Config: testAccResourceVariable_CompanyContext_SecretStatic_Hcl(resourceName, name, withBootstrapConfig),
Check: resource.ComposeTestCheckFunc(
davinci.Variable_GetIDs(resourceFullName, &environmentID, &variableID),
resource.TestMatchResourceAttr(resourceFullName, "id", regexp.MustCompile(`^[a-zA-Z0-9]+##SK##company$`)),
resource.TestMatchResourceAttr(resourceFullName, "environment_id", verify.P1ResourceIDRegexpFullString),
resource.TestCheckResourceAttr(resourceFullName, "name", name),
resource.TestCheckResourceAttr(resourceFullName, "context", "company"),
resource.TestCheckNoResourceAttr(resourceFullName, "description"),
resource.TestCheckResourceAttr(resourceFullName, "value", "mysecret"),
resource.TestCheckNoResourceAttr(resourceFullName, "empty_value"),
resource.TestCheckResourceAttr(resourceFullName, "type", "secret"),
resource.TestCheckResourceAttr(resourceFullName, "min", "0"),
resource.TestCheckResourceAttr(resourceFullName, "max", "2000"),
resource.TestCheckResourceAttr(resourceFullName, "mutable", "true"),
),
}

variableName := name
mutable := true

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheckClient(t)
Expand Down Expand Up @@ -150,6 +191,26 @@ func testAccResourceVariable_Full_CompanyContext(t *testing.T, withBootstrapConf
return true, nil // skip due to https://github.com/pingidentity/terraform-provider-davinci/issues/253
},
},
{
Config: testAccResourceVariable_CompanyContext_Full_Hcl(resourceName, name, withBootstrapConfig),
Destroy: true,
},
// Test secret
secretDynamicStep,
{
Config: testAccResourceVariable_CompanyContext_SecretDynamic_Hcl(resourceName, name, withBootstrapConfig),
PreConfig: func() {
davinci.Variable_RandomVariableValue_PreConfig(t, environmentID, nil, &dv.VariablePayload{
Name: &variableName,
Context: "company",
Type: "secret",
Mutable: &mutable,
})
},
ExpectNonEmptyPlan: false,
PlanOnly: true,
},
secretStaticStep,
fullStep,
// Test importing the resource
{
Expand Down Expand Up @@ -650,6 +711,35 @@ func testAccResourceVariable_CompanyContext_Minimal_Hcl(resourceName, name strin
return testAccResourceVariable_Minimal_Hcl(resourceName, name, "company", withBootstrapConfig)
}

func testAccResourceVariable_CompanyContext_SecretDynamic_Hcl(resourceName, name string, withBootstrapConfig bool) (hcl string) {
context := "company"
return fmt.Sprintf(`
%[1]s
resource "davinci_variable" "%[2]s" {
environment_id = pingone_environment.%[2]s.id
name = "%[3]s"
context = "%[4]s"
type = "secret"
}
`, acctest.PingoneEnvironmentSsoHcl(resourceName, withBootstrapConfig), resourceName, name, context)
}

func testAccResourceVariable_CompanyContext_SecretStatic_Hcl(resourceName, name string, withBootstrapConfig bool) (hcl string) {
context := "company"
return fmt.Sprintf(`
%[1]s
resource "davinci_variable" "%[2]s" {
environment_id = pingone_environment.%[2]s.id
name = "%[3]s"
context = "%[4]s"
type = "secret"
value = "mysecret"
}
`, acctest.PingoneEnvironmentSsoHcl(resourceName, withBootstrapConfig), resourceName, name, context)
}

func testAccResourceVariable_FlowInstanceContext_Full_Hcl(resourceName, name string, withBootstrapConfig bool) (hcl string) {
return testAccResourceVariable_Full_Hcl(resourceName, name, "flowInstance", withBootstrapConfig)
}
Expand Down

0 comments on commit 9752057

Please sign in to comment.