Skip to content

Commit

Permalink
Update changelog with dual-pass interp [#173134254]
Browse files Browse the repository at this point in the history
  • Loading branch information
anEXPer committed Aug 28, 2020
1 parent 745c370 commit 08f2c22
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 52 deletions.
29 changes: 28 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,34 @@ can be found in [Pivotal Documentation](docs.pivotal.io/platform-automation).
This ensures that commands are not kept in `bash` history.
The environment variable `OM_PASSWORD` will overwrite the password value in `env.yml`.

## 6.1.3
## 6.2.0

### Features
- `interpolate` behavior has been improved
in all commands that perform interpolation.
All interpolation in `om` is now dual-pass;
what would have previously been the final output
is interpolated again.
This allows the use of mapping-variables,
vars that have other vars as their values.
For a detailed example, see the new test for this feature,
found in `interpolate/interpolate_suite_test.go`.
- This is intended to allow the use of vars files
to map from automatically generated vars-names,
such as those created by `staged-config` and `config-template`.
- Also, note that Ops Files are only applied on the first pass,
as they're not idempotent in the way that substituion is.
- Similarly, the --path argument for `om interpolate` is only applied
on the second pass.
- We are aware that other CLI tools that use interpolation behavior
don't do this, and may not wish to -
for example, both `fly` and `bosh` communicate with servers
that also understand the ((double-paren)) var syntax,
and so possibly have cases for passing these things along unresolved.
As far as we know, this is not true of any use of `om`.
- We actually can't think of any case where this would be undesirable,
_even in the other tools we just mentioned_.
If you can, please open an issue!
### Bug Fixes
- `configure-product` will no longer assign a new guid for unnamed collections conatin:
Expand Down
100 changes: 49 additions & 51 deletions interpolate/interpolate_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,57 +163,6 @@ var _ = Describe("Execute", func() {
})
})

When("always", func() {
It("runs the interplation a second time on the output of the first time, without ops files", func() {
// The goal here is to allow vars to be used to map multiple variables from some source
// into different names.
// In our case, the VarsEnv are vars from a secret store,
// While vars-files are mappings between those canonical secret store names,
// And generated variable names in the template that are based on the yaml structure.
// The test setup will attempt to illustrate this situation,
// and test that the same thing could be done using flags as the canonical source.
// We exclude Ops Files because there should be no need for a second pass,
// and they're not guranteed to be idempotent
templateContents := `---
template-keys:
key-1: ((template_keys_key_1))
key-2: ((template_keys_key_2))
other-template-keys:
other-key-1: ((other_template_keys_other_key_1))
other-key-2: ((other_template_keys_other_key_2))
key-to-be-removed-once: some-value
`
varsFileContents := `---
template_keys_key_1: ((shared_value_1))
template_keys_key_2: non-secret-literal-value
other_template_keys_other_key_1: ((shared_value_1))
other_template_keys_other_key_2: ((shared_value_2))
`
nonIdempotentOpsFile := `[{type: remove, path: /key-to-be-removed-once}]`

contents, err := interpolate.Execute(interpolate.Options{
TemplateFile: writeFile(templateContents),
VarsFiles: []string{writeFile(varsFileContents)},
Vars: []string{"shared_value_2=our-second-shared-value"},
VarsEnvs: []string{"PREFIX"},
EnvironFunc: func() []string {
return []string{"PREFIX_shared_value_1=our-first-shared-value"}
},
OpsFiles: []string{writeFile(nonIdempotentOpsFile)},
})
Expect(err).ToNot(HaveOccurred())
fullyInterpolatedYAML := `---
template-keys:
key-1: our-first-shared-value
key-2: non-secret-literal-value
other-template-keys:
other-key-1: our-first-shared-value
other-key-2: our-second-shared-value
`
Expect(contents).To(MatchYAML(fullyInterpolatedYAML))
})
})

When("vars are specified", func() {
It("supports loading individual vars", func() {
contents, err := interpolate.Execute(interpolate.Options{
Expand Down Expand Up @@ -270,6 +219,55 @@ other-template-keys:
})
Expect(err).To(MatchError(ContainSubstring("Expected to find variables: username")))
})

It("runs the interplation a second time on the output of the first time, without ops files", func() {
// The goal here is to allow vars to be used to map multiple variables from some source
// into different names.
// In our case, the VarsEnv are vars from a secret store,
// While vars-files are mappings between those canonical secret store names,
// And generated variable names in the template that are based on the yaml structure.
// The test setup will attempt to illustrate this situation,
// and test that the same thing could be done using flags as the canonical source.
// We exclude Ops Files because there should be no need for a second pass,
// and they're not guranteed to be idempotent
templateContents := `---
template-keys:
key-1: ((template_keys_key_1))
key-2: ((template_keys_key_2))
other-template-keys:
other-key-1: ((other_template_keys_other_key_1))
other-key-2: ((other_template_keys_other_key_2))
key-to-be-removed-once: some-value
`
varsFileContents := `---
template_keys_key_1: ((shared_value_1))
template_keys_key_2: non-secret-literal-value
other_template_keys_other_key_1: ((shared_value_1))
other_template_keys_other_key_2: ((shared_value_2))
`
nonIdempotentOpsFile := `[{type: remove, path: /key-to-be-removed-once}]`

contents, err := interpolate.Execute(interpolate.Options{
TemplateFile: writeFile(templateContents),
VarsFiles: []string{writeFile(varsFileContents)},
Vars: []string{"shared_value_2=our-second-shared-value"},
VarsEnvs: []string{"PREFIX"},
EnvironFunc: func() []string {
return []string{"PREFIX_shared_value_1=our-first-shared-value"}
},
OpsFiles: []string{writeFile(nonIdempotentOpsFile)},
})
Expect(err).ToNot(HaveOccurred())
fullyInterpolatedYAML := `---
template-keys:
key-1: our-first-shared-value
key-2: non-secret-literal-value
other-template-keys:
other-key-1: our-first-shared-value
other-key-2: our-second-shared-value
`
Expect(contents).To(MatchYAML(fullyInterpolatedYAML))
})
})

func writeFile(contents string) string {
Expand Down

0 comments on commit 08f2c22

Please sign in to comment.