add support for literal type in set block (#1615)

* add support for literal type in set block

* Add changelog
This commit is contained in:
Jaylon McShan 2025-05-19 06:20:15 -06:00 committed by GitHub
parent a37eb37958
commit ff0b0a24a4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 74 additions and 6 deletions

3
.changelog/1615.txt Normal file
View file

@ -0,0 +1,3 @@
```release-note:feature
Add `"literal"` as a supported `type` for the `set` block
```

View file

@ -299,7 +299,7 @@ func (d *HelmTemplate) Schema(ctx context.Context, req datasource.SchemaRequest,
Optional: true,
Computed: true,
Validators: []validator.String{
stringvalidator.OneOf("auto", "string"),
stringvalidator.OneOf("auto", "string", "literal"),
},
},
},
@ -335,7 +335,7 @@ func (d *HelmTemplate) Schema(ctx context.Context, req datasource.SchemaRequest,
"type": schema.StringAttribute{
Optional: true,
Validators: []validator.String{
stringvalidator.OneOf("auto", "string"),
stringvalidator.OneOf("auto", "string", "literal"),
},
},
},
@ -932,6 +932,17 @@ func applySetValue(base map[string]interface{}, set SetValue) diag.Diagnostics {
if err := strvals.ParseIntoString(fmt.Sprintf("%s=%s", name, value), base); err != nil {
diags.AddError("Failed parsing string value", fmt.Sprintf("Key %q with value %s: %s", name, value, err))
}
case "literal":
var literal interface{}
if err := yaml.Unmarshal([]byte(fmt.Sprintf("%s: %s", name, value)), &literal); err != nil {
diags.AddError("Failed parsing literal value", fmt.Sprintf("Key %q with literal value %s: %s", name, value, err))
return diags
}
if m, ok := literal.(map[string]interface{}); ok {
base[name] = m[name]
} else {
base[name] = literal
}
default:
diags.AddError("Unexpected type", fmt.Sprintf("Unexpected type: %s", valueType))
}

View file

@ -536,7 +536,7 @@ func (r *HelmRelease) Schema(ctx context.Context, req resource.SchemaRequest, re
Computed: true,
Default: stringdefault.StaticString(""),
Validators: []validator.String{
stringvalidator.OneOf("auto", "string"),
stringvalidator.OneOf("auto", "string", "literal"),
},
},
},
@ -603,7 +603,7 @@ func (r *HelmRelease) Schema(ctx context.Context, req resource.SchemaRequest, re
"type": schema.StringAttribute{
Optional: true,
Validators: []validator.String{
stringvalidator.OneOf("auto", "string"),
stringvalidator.OneOf("auto", "string", "literal"),
},
},
},
@ -1396,6 +1396,18 @@ func getValue(base map[string]interface{}, set setResourceModel) diag.Diagnostic
diags.AddError("Failed parsing string value", fmt.Sprintf("Failed parsing key %q with value %s: %s", name, value, err))
return diags
}
case "literal":
var literal interface{}
if err := yaml.Unmarshal([]byte(fmt.Sprintf("%s: %s", name, value)), &literal); err != nil {
diags.AddError("Failed parsing literal value", fmt.Sprintf("Key %q with literal value %s: %s", name, value, err))
return diags
}
if m, ok := literal.(map[string]interface{}); ok {
base[name] = m[name]
} else {
base[name] = literal
}
default:
diags.AddError("Unexpected type", fmt.Sprintf("Unexpected type: %s", valueType))
return diags

View file

@ -1822,6 +1822,28 @@ func TestAccResourceRelease_update_set_list_chart(t *testing.T) {
})
}
func TestAccResourceRelease_literalSet(t *testing.T) {
name := randName("literal-set")
namespace := createRandomNamespace(t)
defer deleteNamespace(t, namespace)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: protoV6ProviderFactories(),
Steps: []resource.TestStep{
{
Config: testAccHelmReleaseConfigSetLiteral(testResourceName, namespace, name, "1.2.3"),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("helm_release.test", "metadata.name", name),
resource.TestCheckResourceAttr("helm_release.test", "metadata.namespace", namespace),
resource.TestCheckResourceAttr("helm_release.test", "metadata.revision", "1"),
resource.TestCheckResourceAttr("helm_release.test", "status", release.StatusDeployed.String()),
resource.TestCheckResourceAttr("helm_release.test", "metadata.values", "{\"nested\":{\"a\":true,\"b\":1337}}"),
),
},
},
})
}
func setupOCIRegistry(t *testing.T, usepassword bool) (string, func()) {
dockerPath, err := exec.LookPath("docker")
if err != nil {
@ -2389,3 +2411,23 @@ func testAccHelmReleaseRecomputeMetadataSet(resource, ns, name string) string {
}
`, resource, name, ns, resource)
}
func testAccHelmReleaseConfigSetLiteral(resource, ns, name, version string) string {
return fmt.Sprintf(`
resource "helm_release" "%s" {
name = %q
namespace = %q
description = "Test"
repository = %q
chart = "test-chart"
version = %q
set = [
{
name = "nested"
value = "{ \"a\": true, \"b\": 1337 }"
type = "literal"
}
]
}
`, resource, name, ns, testRepositoryURL, version)
}

View file

@ -51,11 +51,11 @@ The provider also supports repositories that are added to the local machine outs
{{tffile "examples/resources/release/example_7.tf"}}
The `set`, `set_list`, and `set_sensitive` blocks support:
The `set`, and `set_sensitive` blocks support:
* `name` - (Required) full name of the variable to be set.
* `value` - (Required) value of the variable to be set.
* `type` - (Optional) type of the variable to be set. Valid options are `auto` and `string`.
* `type` - (Optional) type of the variable to be set. Valid options are `auto`, `string`, and `literal`.
Since Terraform Utilizes HCL as well as Helm using the Helm Template Language, it's necessary to escape the `{}`, `[]`, `.`, and `,` characters twice in order for it to be parsed. `name` should also be set to the `value path`, and `value` is the desired value that will be set.