Skip to content
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

Merged
merged 14 commits into from
Jul 18, 2023

Conversation

patrickhuie19
Copy link
Contributor

@patrickhuie19 patrickhuie19 commented Jun 14, 2023

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.

@github-actions
Copy link
Contributor

I see that you haven't updated any README files. Would it make sense to do so?

@patrickhuie19 patrickhuie19 force-pushed the feature/2268-multiple-secrets-files branch 5 times, most recently from fcb4f00 to b16b364 Compare June 14, 2023 17:32
@patrickhuie19 patrickhuie19 marked this pull request as ready for review June 14, 2023 17:51
core/config/v2/types.go Outdated Show resolved Hide resolved
core/config/v2/types.go Outdated Show resolved Hide resolved
@zytek
Copy link
Contributor

zytek commented Jun 14, 2023

Overrides will fail.

why ?
is this similar to config behaviour?

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.

@jmank88
Copy link
Contributor

jmank88 commented Jun 14, 2023

Overrides will fail.

why ? is this similar to config behaviour?

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/config/v2/types.go Outdated Show resolved Hide resolved
Comment on lines 99 to 102
URL: models.NewSecretURL(models.MustParseURL("xxxxx")),
BackupURL: models.NewSecretURL(models.MustParseURL("xxxxx")),
Copy link
Contributor

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.

Copy link
Contributor Author

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:

  1. Merge is successful for all non-overriding operations
  2. Merge fails in presence of any overriding operations
  3. 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.

Copy link
Contributor

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?

Copy link
Contributor Author

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 😆

@patrickhuie19 patrickhuie19 force-pushed the feature/2268-multiple-secrets-files branch from 6912bb4 to 48cdd38 Compare June 21, 2023 00:53
core/config/v2/validate.go Outdated Show resolved Hide resolved
Comment on lines 178 to 183
func MakeTestFile(t *testing.T, contents any, fileName string) string {
d := t.TempDir()
p := filepath.Join(d, fileName)

b, err := toml.Marshal(contents)
Copy link
Contributor

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?

Copy link
Contributor

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.

@patrickhuie19 patrickhuie19 force-pushed the feature/2268-multiple-secrets-files branch from c22bbe5 to f4caebf Compare June 28, 2023 15:20
@patrickhuie19 patrickhuie19 force-pushed the feature/2268-multiple-secrets-files branch from 719daa8 to 3907c49 Compare July 10, 2023 20:52
core/cmd/app_test.go Outdated Show resolved Hide resolved
@@ -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 {
Copy link
Contributor

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.

Suggested change
func MakeTestFile(t *testing.T, contents any, fileName string) string {
func WriteTOMLFile(t *testing.T, contents any, fileName string) string {

Copy link
Contributor Author

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.

@patrickhuie19 patrickhuie19 force-pushed the feature/2268-multiple-secrets-files branch from 7050a83 to 11604ac Compare July 11, 2023 14:03
@patrickhuie19 patrickhuie19 requested a review from a team as a code owner July 11, 2023 21:20
Comment on lines 268 to 271
testtomlutils.WriteTOMLFile(t, chainlink.Secrets{Secrets: toml.Secrets{Threshold: testSecretsFileContentsComplete.Threshold}}, "test_secrets7.toml"),
},
},
wantCfg: withDefaults(t, testConfigFileContents, testSecretsRedactedContentsComplete),
Copy link
Contributor

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:

  1. Why do we still need to marshal redacted values? I thought that reading real values from files would work around that.
  2. If we are stuck with this, then can we at least use the redacted Go values for both parts (both testSecretsRedactedContentsComplete instead of testSecretsFileContentsComplete too)? I think it will be confusing for future readers to see real values being serialized and implicitly converted.

Copy link
Contributor Author

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!

@patrickhuie19 patrickhuie19 force-pushed the feature/2268-multiple-secrets-files branch 2 times, most recently from 4e7dee0 to a432c83 Compare July 17, 2023 16:38
@patrickhuie19 patrickhuie19 force-pushed the feature/2268-multiple-secrets-files branch from a432c83 to b61652a Compare July 17, 2023 17:37
@cl-sonarqube-production
Copy link

SonarQube Quality Gate

Quality Gate failed

Failed condition 79.5% 79.5% Coverage on New Code (is less than 80%)

See analysis details on SonarQube

@patrickhuie19 patrickhuie19 added this pull request to the merge queue Jul 18, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jul 18, 2023
@patrickhuie19 patrickhuie19 added this pull request to the merge queue Jul 18, 2023
Merged via the queue into develop with commit e67f492 Jul 18, 2023
94 of 95 checks passed
@patrickhuie19 patrickhuie19 deleted the feature/2268-multiple-secrets-files branch July 18, 2023 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants