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

VAULT-12095 Support multiple config files for Vault Agent #18403

Merged
merged 6 commits into from
Jan 3, 2023

Conversation

VioletHynes
Copy link
Contributor

@VioletHynes VioletHynes commented Dec 15, 2022

This PR adds support for the following:

  • Ability to specify -config=./a-directory/, like Vault
  • Ability to specify multiple -config=a.hcl -config=b.hcl

Merge strategy and file choosing strategy is identical to Vault itself.

I used the same language for the docs that we did here: https://developer.hashicorp.com/vault/tutorials/operations/configure-vault

If you can't review this before the holiday break, don't worry! There's no rush.

// isTemporaryFile returns true or false depending on whether the
// provided file name is a temporary file for the following editors:
// emacs or vim.
func isTemporaryFile(name string) bool {
Copy link
Contributor Author

@VioletHynes VioletHynes Dec 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little weird to me, but we use it for Vault's config parsing so I thought I'd keep it for consistency.

@@ -236,16 +473,6 @@ func LoadConfig(path string) (*Config, error) {
return nil, fmt.Errorf("error parsing 'api_proxy':%w", err)
}

if result.APIProxy != nil && result.Cache != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These checks have been moved to a new check stage after all of the config has been added and merged.

err = parseVault(result, list)
if err != nil {
return nil, fmt.Errorf("error parsing 'vault':%w", err)
}

if result.Vault == nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer set a default Vault config retries, we simply use the default if it's not set.

@@ -61,191 +61,6 @@ func testAgentCommand(tb testing.TB, logger hclog.Logger) (*cli.MockUi, *AgentCo
}
}

/*
func TestAgent_Cache_UnixListener(t *testing.T) {
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'm not sure what this is, so I deleted it as it was commented out. We can always fish it out of git if we need it again, but I don't like having a ~200 line comment block in files like this.

command/agent.go Outdated Show resolved Hide resolved
command/agent.go Outdated Show resolved Hide resolved
result.TemplateConfig = c2.TemplateConfig
}

for _, l := range c.Templates {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a more succinct syntax (...) you could use in place of a for loop if you wanted.

if c.APIProxy.UseAutoAuthTokenRaw != nil {
return fmt.Errorf("use_auto_auth_token defined in both api_proxy and cache config. Please remove this configuration from the cache block")
} else {
c.APIProxy.ForceAutoAuthToken = c.Cache.ForceAutoAuthToken
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer if a Validate method didn't mutate its inputs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unfortunate consequence of supporting the API Proxy config values in Cache, too. It made the most sense to me to keep this logic together as opposed to having two separate blocks e.g.:

// in Validate
	if c.APIProxy != nil && c.Cache != nil {
		if c.Cache.UseAutoAuthTokenRaw != nil {
			if c.APIProxy.UseAutoAuthTokenRaw != nil {
				return fmt.Errorf("use_auto_auth_token defined in both api_proxy and cache config. Please remove this configuration from the cache block")
			}
		}
	}

and

// elsewhere
	if c.APIProxy != nil && c.Cache != nil {
		if c.Cache.UseAutoAuthTokenRaw != nil {
			if c.APIProxy.UseAutoAuthTokenRaw == nil {
				c.APIProxy.ForceAutoAuthToken = c.Cache.ForceAutoAuthToken
			}
		}
	}

I don't really like mutation like this either, but in this case it feels like the lesser of two evils to me, with regards to code cleanliness.


var files []string
err = nil
for err != io.EOF {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine as you have it, though I think it might be a little more readable if you used filepath.WalkDir instead of Readdir here.

As with Vault, the `-config` flag can be used in three different ways:

- Use the flag once to name the path to a single specific configuration file.
- Use the flag multiple times to name multiple configuration files, which will be composed at runtime.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't normally see composed used in this sense, maybe it's a British-ism? I would use merged or combined instead.

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 actually took this wording from one of our existing learn docs: https://developer.hashicorp.com/vault/tutorials/operations/configure-vault

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's proper English either. You can say "this cake is composed of the following ingredients", but I've never seen it used in the form "I composed these ingredients to make a cake". My English grammar isn't so hot but I think it comes down to transitive vs intransitive use. @tjperry07 wdyt?

Copy link
Contributor Author

@VioletHynes VioletHynes Jan 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, it's definitely a grammatical form I recognise and the sentence does make 100% sense to me, so it could be a British English thing maybe? To give another tech (or, maybe more maths) example, it's used in this way regularly when talking about composing functions (e.g. for a composition f . g, f and g are composed).

I don't really have qualms with changing it, but we should probably update it in both places if we do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Composed can be used, but it's reading strange to Americans because we usually use it when talking about art and feelings. She composed the painting beautifully. They composed themselves before walking into the room.

In this case merged, combined, even compiled (if appropriate) is better. Just because we follow US English and all US English quirks. But composed is grammatically correct.

t.Fatal(diff)
}

config, err = LoadConfigFile("./test-fixtures/config-dir-auto-auth-and-listener/config1.hcl")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why these extra checks? They seem redundant after the deep.Equal above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essentially, we are doing two checks:

  1. Check that the config matches if we load the directory
  2. Check that the config matches if we load and merge the two files independently

In essence, we're confirming there is no difference between:
vault agent -config=dir1
and
vault agent -config=dir1/file1.hcl -config=dir1/file2.hcl

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm always dubious of the value of tests that reproduce the code they're testing.

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 think I'd like to keep it as is, to ensure that the behaviour doesn't diverge in the future. Anecdotally, this was quite useful during development. We could factor out the test to two tests that check the multi-file approach in a different test to the dir approach, but we'd lose the validation that the two produce the same resultant config.

@VioletHynes VioletHynes merged commit c2abccc into main Jan 3, 2023
AnPucel pushed a commit that referenced this pull request Jan 14, 2023
* VAULT-12095 Code changes for multi-config

* VAULT-12095 typo

* VAULT-12095 make vault non-nil during update

* VAULT-12095 docs

* VAULT-12095 small refactor

* VAULT-12095 typos
@peteski22 peteski22 deleted the violethynes/VAULT-12095 branch January 30, 2023 11:45
AnPucel pushed a commit that referenced this pull request Feb 3, 2023
* VAULT-12095 Code changes for multi-config

* VAULT-12095 typo

* VAULT-12095 make vault non-nil during update

* VAULT-12095 docs

* VAULT-12095 small refactor

* VAULT-12095 typos
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