From 6b5e0f1164755978857e0f6fc24740ef1617fc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Bergn=C3=A9hr?= Date: Tue, 24 Sep 2024 10:16:33 +0200 Subject: [PATCH] Treat object parameters as objects in templating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change makes it possible to access a parameter in templating, not only to the top-level, i.e. the parameter itself, but also -- if the parameter is of type "object" -- to access properties of the object value. For example: ```yaml parameters: - name: foo type: object default: a: 1 b: 2 install: mymixin: some_property: ${ bundle.parameters.foo.a } ``` In this case, the `.a` was not possible before as `foo` was merely a JSON string at the point of template resolution. Signed-off-by: Leo Bergnéhr --- CONTRIBUTORS.md | 1 + pkg/runtime/runtime_manifest.go | 28 ++++++++++++++++++++++------ pkg/runtime/runtime_manifest_test.go | 11 +++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 90d298dbe..302964960 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -101,5 +101,6 @@ and we will add you. **All** contributors belong here. 💯 - [guangwu guo](https://github.com/testwill) - [Eric Herrmann](https://github.com/egherrmann) - [Alex Dejanu](https://github.com/dejanu) +- [Leo Bergnéhr](https://github.com/lbergnehr) diff --git a/pkg/runtime/runtime_manifest.go b/pkg/runtime/runtime_manifest.go index 9cc084b1f..653a98280 100644 --- a/pkg/runtime/runtime_manifest.go +++ b/pkg/runtime/runtime_manifest.go @@ -6,6 +6,7 @@ import ( "compress/gzip" "context" "encoding/base64" + "encoding/json" "fmt" "io" "os" @@ -131,15 +132,27 @@ func (m *RuntimeManifest) loadDependencyDefinitions() error { return nil } -func (m *RuntimeManifest) resolveParameter(pd manifest.ParameterDefinition) string { +func (m *RuntimeManifest) resolveParameter(pd manifest.ParameterDefinition) (interface{}, error) { + getValue := func(envVar string) (interface{}, error) { + value := m.config.Getenv(envVar) + if pd.Type == "object" { + var obj map[string]interface{} + if err := json.Unmarshal([]byte(value), &obj); err != nil { + return nil, err + } + return obj, nil + } + return value, nil + } + if pd.Destination.EnvironmentVariable != "" { - return m.config.Getenv(pd.Destination.EnvironmentVariable) + return getValue(pd.Destination.EnvironmentVariable) } if pd.Destination.Path != "" { - return pd.Destination.Path + return pd.Destination.Path, nil } envVar := manifest.ParamToEnvVar(pd.Name) - return m.config.Getenv(envVar) + return getValue(envVar) } func (m *RuntimeManifest) resolveCredential(cd manifest.CredentialDefinition) (string, error) { @@ -271,9 +284,12 @@ func (m *RuntimeManifest) buildSourceData() (map[string]interface{}, error) { } pe := param.Name - val := m.resolveParameter(param) + val, err := m.resolveParameter(param) + if err != nil { + return nil, err + } if param.Sensitive { - m.setSensitiveValue(val) + m.setSensitiveValue(val.(string)) } params[pe] = val } diff --git a/pkg/runtime/runtime_manifest_test.go b/pkg/runtime/runtime_manifest_test.go index d56ad0dcf..0ffeb018b 100644 --- a/pkg/runtime/runtime_manifest_test.go +++ b/pkg/runtime/runtime_manifest_test.go @@ -34,17 +34,21 @@ func TestResolveMapParam(t *testing.T) { ctx := context.Background() testConfig := config.NewTestConfig(t) testConfig.Setenv("PERSON", "Ralpha") + testConfig.Setenv("CONTACT", "{ \"name\": \"Breta\" }") mContent := `schemaVersion: 1.0.0-alpha.2 parameters: - name: person - name: place applyTo: [install] +- name: contact + type: object install: - mymixin: Parameters: Thing: ${ bundle.parameters.person } + Object: ${ bundle.parameters.contact.name } ` rm := runtimeManifestFromStepYaml(t, testConfig, mContent) s := rm.Install[0] @@ -62,6 +66,13 @@ install: assert.Equal(t, "Ralpha", val) assert.NotContains(t, "place", pms, "parameters that don't apply to the current action should not be resolved") + // New assertions for the contact parameter + require.IsType(t, "string", pms["Object"], "Data.mymixin.Parameters.Object has incorrect type") + contactName := pms["Object"].(string) + require.IsType(t, "string", contactName, "Data.mymixin.Parameters.Object.name has incorrect type") + + assert.Equal(t, "Breta", contactName) + err = rm.Initialize(ctx) require.NoError(t, err) }