-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature/2268: added support for merging fields from multiple secrets files #9590
Conversation
I see that you haven't updated any README files. Would it make sense to do so? |
fcb4f00
to
b16b364
Compare
why ? is there any reason to have this behave differently than config.toml merging? just/mostly curious. not sure if I see a pattern for overriding secrets, but this is something we DO use for config - to provide default values, but give ability to override. I'd be +1 on making this consistent with config, but if you have a scenario where this is unsafe I won't fight for it. |
The thinking was that if you override a secret value that means you are leaking extra secrets somewhere they are not necessary, which seems inherently unsafe. |
core/cmd/app_test.go
Outdated
URL: models.NewSecretURL(models.MustParseURL("xxxxx")), | ||
BackupURL: models.NewSecretURL(models.MustParseURL("xxxxx")), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does explicit xxxxx
need to be used here? I'm worried that could mask problems with the printing protection, since it matches w/o conversion and could lead to a false positive. Comparing either the raw TOML strings, or Go types with real values would be cleaner, if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, yea - good point!
IMO, three things should be tested here:
- Merge is successful for all non-overriding operations
- Merge fails in presence of any overriding operations
- Verify merge results in the correct ending value of secrets
The first two test cases are addressed sufficiently through the current changes. The third test case is not. The crux is that when the new merging is performed, New()
, is also functionally coupled with the redaction of the secrets. The redaction logic is defined in core/store/models/secrets.go
. As an aside, I believe it makes sense that tests 1 and 2 are performed in app_test.go
since end to end error and success conditions for use of the node are tested here.
I've split the merging and redaction functionality in the next commit to isolate and unit test the merging functionality in config_general_test.go
. However - given how the secret types are implemented, there is no direct way to compare by types or by toml string. I'd either have to create a new type for testing that is similar to the Secrets type, or implement a new toml string outputter that won't redact the secret values. The latter approach seems like it could be potentially abused. The solution I’ve landed on is comparing the values in opts
before New()
is called and the values behind the Secret
and SecretURL
types in opts after New() is called through the use of a new TestSecrets
type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that I follow. The redaction logic prevents printing/marshaling directly, but the values are still directly available and comparable. If these tests depend on the literal value being xxxxx
, then something seems wrong. If they don't depend on any particular values, then that also seems wrong. I thought we would have real values here in the Go types, and a raw TOML string of redacted types elsewhere. Are we reading in a redacted file somewhere or something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, like you mentioned on a comment below - by design it's not possible to go from the secret types to non-redacted values in the TOML. I'll use raw TOML as you suggested, it should simplify all of the ...workarounds I used for this revision to test that third case 😆
6912bb4
to
48cdd38
Compare
core/utils/files.go
Outdated
func MakeTestFile(t *testing.T, contents any, fileName string) string { | ||
d := t.TempDir() | ||
p := filepath.Join(d, fileName) | ||
|
||
b, err := toml.Marshal(contents) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this is the problem - you can't write secrets like this via the existing types, by design. It will always just print redacted values. Can we use raw TOML here instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use package embed
https://pkg.go.dev/embed to make regular files available to the test.
c22bbe5
to
f4caebf
Compare
719daa8
to
3907c49
Compare
core/utils/files.go
Outdated
@@ -170,3 +175,14 @@ func (s FileSize) String() string { | |||
str, _ := s.MarshalText() | |||
return string(str) | |||
} | |||
|
|||
func MakeTestFile(t *testing.T, contents any, fileName string) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be a general util func? Can we limit it to tests instead? Or even a toml config test package?
I think we should document the expectations with secrets too, so this isn't mistakenly assumed to be able to marshal secret values.
func MakeTestFile(t *testing.T, contents any, fileName string) string { | |
func WriteTOMLFile(t *testing.T, contents any, fileName string) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, good call. Addressed in the next revision, added a comment in the following commit.
7050a83
to
11604ac
Compare
core/cmd/app_test.go
Outdated
testtomlutils.WriteTOMLFile(t, chainlink.Secrets{Secrets: toml.Secrets{Threshold: testSecretsFileContentsComplete.Threshold}}, "test_secrets7.toml"), | ||
}, | ||
}, | ||
wantCfg: withDefaults(t, testConfigFileContents, testSecretsRedactedContentsComplete), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I lost the thread somewhere:
- Why do we still need to marshal redacted values? I thought that reading real values from files would work around that.
- If we are stuck with this, then can we at least use the redacted Go values for both parts (both
testSecretsRedactedContentsComplete
instead oftestSecretsFileContentsComplete
too)? I think it will be confusing for future readers to see real values being serialized and implicitly converted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was sticking with the earlier pattern, but I agree that reading real values from files is a better approach. I've updated in the next revision, thanks!
…eTOMLFile and from general utilities to testtomlutils
…ead of implementing it ourselves
… to use persistent toml test fixtures
4e7dee0
to
a432c83
Compare
…o chainlink package
a432c83
to
b61652a
Compare
https://smartcontract-it.atlassian.net/browse/BCF-2268
Currently multiple secrets files may be provided, but only the fields from the first provided file are processed.
With this change, secrets configuration fields split into multiple secrets files will be merged together. Overrides will fail. For maps and lists, true merging behavior is honored. There is only a map element currently, so if list secrets configuration fields are added in the future it will have to respect this pattern.
Validation is performed on the final merged secrets file. Duplicates within files err out as they do today.