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

Extend SecretsStore to support Vault CSI #625

Merged
merged 5 commits into from Oct 26, 2021
Merged

Conversation

praxist
Copy link
Contributor

@praxist praxist commented Oct 16, 2021

  • SecretsStore reworked to support multiple filewatchers given a directory instead of a secret file
  • Added parsing classes to separate some of the Vault secret format from the SecretsStore, since format is different between the Vault secrets fetcher and Vault CSI
  • More information on vault-csi: https://www.vaultproject.io/docs/platform/k8s/csi
  • Add deprecation notice for Vault-specific functions in SecretsStore

Reddit-only design link: https://docs.google.com/document/d/1nQ8Fhh-WQ4egtIMG_FZzW-dvqAEObsp-onKrQzEn9CA/edit#
This change should be completely transparent for services sticking with secrets fetchers. For those wanting to use vault-csi, they will have to do the following:

  • .ini change to secrets.path = some_directory
  • .ini change to secrets.provider = vault_csi
  • change references of secret paths in code to just the secret name itself.

Note for testing: I moved the existing test suite to its own file and duplicated the tests in the context of SecretsStore using a dir with multiple secrets files vs a single file - I think this provides better coverage though I'm open to collapsing it back down to one file.

SecretsStore reworked to support multiple filewatchers given a directory instead of a secret file
Added parsing classes to separate some of the Vault secret format from the SecretsStore, since format is different between the Vault secrets fetcher and Vault CSI
More information on vault-csi: https://www.vaultproject.io/docs/platform/k8s/csi
Add deprecation notice for Vault-specific functions in SecretsStore
@praxist praxist requested a review from a team as a code owner October 16, 2021 02:05
Copy link
Contributor

@spladug spladug left a comment

Choose a reason for hiding this comment

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

Cool! Thanks for doing this. I think the biggest thing is it'd really be best not to be branching in every function like that but instead use separate classes for each implementation. We'll have to keep an eye on performance and consider our options if checking all those mtimes is too slow. Excited to see the CSI provider replace the secrets fetcher soon!

self.path_type = "dir" if os.path.isdir(path) else "file"
self.parser = parser or VaultFileParser
if self.path_type == "dir":
for root, _, files in os.walk(path):
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there ever going to be subdirectories? or just a flat directory of files? In the latter case it'd be simpler to use os.listdir or Path(...).iterdir().

Do we need to worry about new files being created later on? (i.e. new secrets) If so we'd want to do this directory listing operation more than once.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, there can be subdirectories if the objectName has /s in them. e.g. trying to use secret/blah instead of blah would create an additional directory secret.

Copy link
Contributor Author

@praxist praxist Oct 19, 2021

Choose a reason for hiding this comment

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

second question - new files wouldn't be created unless a change is made to the deploy config to add additional objects.

baseplate/lib/secrets.py Outdated Show resolved Hide resolved
baseplate/lib/secrets.py Outdated Show resolved Hide resolved
baseplate/lib/secrets.py Outdated Show resolved Hide resolved
baseplate/lib/secrets.py Outdated Show resolved Hide resolved
baseplate/lib/secrets.py Outdated Show resolved Hide resolved
baseplate/lib/secrets.py Outdated Show resolved Hide resolved
Copy link
Contributor

@kylelemons kylelemons left a comment

Choose a reason for hiding this comment

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

It looks like spladug has this review, but from my perspective I think it would be useful for the PR / commit to summarize the high-level considerations that need to be made in the transition. Notably, this will need to be mimicked in the Go and TypeScript baseplate libraries, so having a concise description of the changes are that motivate the change would be useful so that the implementation doesn't have to be the canonical documentation of how it works.

@praxist praxist requested a review from spladug October 19, 2021 06:32
@praxist
Copy link
Contributor Author

praxist commented Oct 19, 2021

Split the SecretsStore logic into 2 subclasses representing the file/directory implementations.

@pacejackson pacejackson removed their request for review October 20, 2021 19:03
Copy link
Contributor

@spladug spladug left a comment

Choose a reason for hiding this comment

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

awesome! final stretch. this is looking really good. just a couple final things.

baseplate/lib/secrets.py Outdated Show resolved Hide resolved
baseplate/lib/secrets.py Show resolved Hide resolved
baseplate/lib/secrets.py Outdated Show resolved Hide resolved
baseplate/lib/secrets.py Outdated Show resolved Hide resolved
baseplate/lib/secrets.py Outdated Show resolved Hide resolved
baseplate/lib/secrets.py Outdated Show resolved Hide resolved
@praxist praxist requested a review from spladug October 21, 2021 04:36
Copy link
Contributor

@spladug spladug left a comment

Choose a reason for hiding this comment

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

looks great. thank you!

baseplate/lib/secrets.py Outdated Show resolved Hide resolved
@praxist
Copy link
Contributor Author

praxist commented Oct 25, 2021

@spladug / @kylelemons ready to merge - will squash with the following commit message:

Extend SecretsStore to support Vault CSI

This change adds an additional way to load secrets besides the existing secrets fetcher:
- When vault.provider is set to vault_csi, vault.path will be assumed to be a directory containing individual files representing secrets, rather than a single file containing every secret.
- Vault CSI loads secrets automatically into these files on pod startup, so no additional sidecar is required.
- Secrets are written to files in a different JSON format
- Each secrets file has its own filewatcher representation with per-request caching behavior preserved

Implementation details:
- Add DirectorySecretsStore subclass of SecretsStore supporting multiple filewatchers
- Duplicate SecretsStore unit tests in the context of DirectorySecretsStore
- Modify secrets_store_from_config to return SecretsStore or DirectorySecretsStore based off vault.provider
- Split out vault-specific file parsing logic into functions outside of SecretsStore
- Add deprecation notice for get_vault_url, get_vault_token in SecretsStore

@praxist praxist merged commit b734323 into reddit:develop Oct 26, 2021
@praxist praxist deleted the vault-csi branch October 26, 2021 23:54
curioussavage pushed a commit that referenced this pull request Dec 7, 2021
This change adds an additional way to load secrets besides the existing secrets fetcher:
- When vault.provider is set to vault_csi, vault.path will be assumed to be a directory containing individual files representing secrets, rather than a single file containing every secret.
- Vault CSI loads secrets automatically into these files on pod startup, so no additional sidecar is required.
- Secrets are written to files in a different JSON format
- Each secrets file has its own filewatcher representation with per-request caching behavior preserved

Implementation details:
- Add DirectorySecretsStore subclass of SecretsStore supporting multiple filewatchers
- Duplicate SecretsStore unit tests in the context of DirectorySecretsStore
- Modify secrets_store_from_config to return SecretsStore or DirectorySecretsStore based off vault.provider
- Split out vault-specific file parsing logic into functions outside of SecretsStore
- Add deprecation notice for get_vault_url, get_vault_token in SecretsStore
praxist added a commit to praxist/baseplate that referenced this pull request Dec 13, 2021
parser instance var was previously added in reddit#625
however, the child classes dont call the superclass init so these were never set properly.
spladug pushed a commit that referenced this pull request Dec 13, 2021
parser instance var was previously added in #625
however, the child classes dont call the superclass init so these were never set properly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants