forked from flyteorg/flyte
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Vault Secret Manager #patch (flyteorg#343)
* Start adding Vaul Secret manager Signed-off-by: Tim Bauer <[email protected]> * Auto-update enumer Signed-off-by: Tim Bauer <[email protected]> * Make verbose Signed-off-by: Tim Bauer <[email protected]> * Revert to print Signed-off-by: Tim Bauer <[email protected]> * Mark debug statements Signed-off-by: Tim Bauer <[email protected]> * Remove prints, simplify vault Signed-off-by: Tim Bauer <[email protected]> * Test format env var, print more Signed-off-by: Tim Bauer <[email protected]> * Check annotations Signed-off-by: Tim Bauer <[email protected]> * Try to retrieve annotations Signed-off-by: Tim Bauer <[email protected]> * Attempt append annotation Signed-off-by: Tim Bauer <[email protected]> * Test annotation injection Signed-off-by: Tim Bauer <[email protected]> * Pre-populate only Signed-off-by: Tim Bauer <[email protected]> * Utils func for vault secret annotation Signed-off-by: Tim Bauer <[email protected]> * Add shorter id to avoid 63 char limit Signed-off-by: Tim Bauer <[email protected]> * Rm print Signed-off-by: Tim Bauer <[email protected]> * Set vault role from config Signed-off-by: Tim Bauer <[email protected]> * Add tests Signed-off-by: Tim Bauer <[email protected]> * Name coreIdl import Signed-off-by: Tim Bauer <[email protected]> * Rm duplicate import Signed-off-by: Tim Bauer <[email protected]> * Update documentation and naming Signed-off-by: Tim Bauer <[email protected]> * Update pkg/webhook/utils.go Co-authored-by: Haytham Abuelfutuh <[email protected]> Signed-off-by: Tim Bauer <[email protected]> * Update pkg/webhook/vault_secret_manager.go There is a [workaround](https://www.vaultproject.io/docs/platform/k8s/injector/examples#environment-variable-example) which involves mounting a template formatted file that contains `export API_KEY="{{ .Data.data.api_key }}"` and then sourcing this file as an extra step. But unless the user takes this extra sourcing step, this is still file mounting. So I would go with this Error message since the user should be warned that the expected result from requesting Env var will not be achieved with this. Co-authored-by: Haytham Abuelfutuh <[email protected]> Signed-off-by: Tim Bauer <[email protected]> * Update pkg/webhook/vault_secret_manager.go Co-authored-by: Haytham Abuelfutuh <[email protected]> Signed-off-by: Tim Bauer <[email protected]> * Fix naming and indent Signed-off-by: Tim Bauer <[email protected]> * Add handling of different kv version and test Signed-off-by: Tim Bauer <[email protected]> * Remove print Signed-off-by: Tim Bauer <[email protected]> * Add enumer for KV version Signed-off-by: Tim Bauer <[email protected]> * Correct kvversion type Signed-off-by: Tim Bauer <[email protected]> * Rm newlines from vault secret template Signed-off-by: Tim Bauer <[email protected]> * Apply suggestions from code review Co-authored-by: Ketan Umare <[email protected]> Signed-off-by: Tim Bauer <[email protected]> * Add docstring Signed-off-by: Tim Bauer <[email protected]> Co-authored-by: Haytham Abuelfutuh <[email protected]> Co-authored-by: Ketan Umare <[email protected]>
- Loading branch information
1 parent
7b09010
commit 9e83dee
Showing
10 changed files
with
437 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
13 changes: 7 additions & 6 deletions
13
flytepropeller/pkg/webhook/config/secretmanagertype_enumer.go
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package webhook | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
coreIdl "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/core" | ||
"github.com/flyteorg/flyteplugins/go/tasks/pluginmachinery/utils" | ||
"github.com/flyteorg/flytepropeller/pkg/webhook/config" | ||
"github.com/flyteorg/flytestdlib/logger" | ||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
var ( | ||
VaultSecretPathPrefix = []string{string(os.PathSeparator), "etc", "flyte", "secrets"} | ||
) | ||
|
||
// VaultSecretManagerInjector allows injecting of secrets into pods by leveraging an existing deployment of Vault Agent | ||
// Vault Agent functions as an additional webhook that is triggered through annotations and then retrieves and mounts | ||
// the requested secrets from Vault. This injector parses a secret Request into vault annotations, interpreting the secret | ||
// Group as the vault secret path and the secret Key as the key for which to extract a value from a Vault secret. | ||
// It supports adding multiple secrets. (The common annotations will simply be overwritten if added several times) | ||
// Note that you need to configure the Vault role that this injector will try to use and add Vault policies for | ||
// the service account and namespaces that your workflows run under. | ||
// Files will be mounted at /etc/flyte/secrets/<SecretGroup>/<SecretKey> | ||
type VaultSecretManagerInjector struct { | ||
cfg config.VaultSecretManagerConfig | ||
} | ||
|
||
func (i VaultSecretManagerInjector) Type() config.SecretManagerType { | ||
return config.SecretManagerTypeVault | ||
} | ||
|
||
func (i VaultSecretManagerInjector) Inject(ctx context.Context, secret *coreIdl.Secret, p *corev1.Pod) (newP *corev1.Pod, injected bool, err error) { | ||
if len(secret.Group) == 0 || len(secret.Key) == 0 { | ||
return nil, false, fmt.Errorf("Vault Secrets Webhook requires both key and group to be set. "+ | ||
"Secret: [%v]", secret) | ||
} | ||
|
||
switch secret.MountRequirement { | ||
case coreIdl.Secret_ANY: | ||
fallthrough | ||
case coreIdl.Secret_FILE: | ||
// Set environment variable to let the container know where to find the mounted files. | ||
defaultDirEnvVar := corev1.EnvVar{ | ||
Name: SecretPathDefaultDirEnvVar, | ||
Value: filepath.Join(VaultSecretPathPrefix...), | ||
} | ||
|
||
p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, defaultDirEnvVar) | ||
p.Spec.Containers = AppendEnvVars(p.Spec.Containers, defaultDirEnvVar) | ||
|
||
// Sets an empty prefix to let the containers know the file names will match the secret keys as-is. | ||
prefixEnvVar := corev1.EnvVar{ | ||
Name: SecretPathFilePrefixEnvVar, | ||
Value: "", | ||
} | ||
|
||
p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, prefixEnvVar) | ||
p.Spec.Containers = AppendEnvVars(p.Spec.Containers, prefixEnvVar) | ||
|
||
commonVaultAnnotations := map[string]string{ | ||
"vault.hashicorp.com/agent-inject": "true", | ||
"vault.hashicorp.com/secret-volume-path": filepath.Join(VaultSecretPathPrefix...), | ||
"vault.hashicorp.com/role": i.cfg.Role, | ||
"vault.hashicorp.com/agent-pre-populate-only": "true", | ||
} | ||
|
||
secretVaultAnnotations, err := CreateVaultAnnotationsForSecret(secret, i.cfg.KVVersion) | ||
// Creating annotations can break with an unsupported KVVersion | ||
if err != nil { | ||
return p, false, err | ||
} | ||
|
||
p.ObjectMeta.Annotations = utils.UnionMaps(p.ObjectMeta.Annotations, commonVaultAnnotations) | ||
p.ObjectMeta.Annotations = utils.UnionMaps(p.ObjectMeta.Annotations, secretVaultAnnotations) | ||
|
||
case coreIdl.Secret_ENV_VAR: | ||
return p, false, fmt.Errorf("Env_Var is not a supported mount requirement for Vault Secret Manager") | ||
default: | ||
err := fmt.Errorf("unrecognized mount requirement [%v] for secret [%v]", secret.MountRequirement.String(), secret.Key) | ||
logger.Error(ctx, err) | ||
return p, false, err | ||
} | ||
|
||
return p, true, nil | ||
} | ||
|
||
func NewVaultSecretManagerInjector(cfg config.VaultSecretManagerConfig) VaultSecretManagerInjector { | ||
return VaultSecretManagerInjector{ | ||
cfg: cfg, | ||
} | ||
} |
Oops, something went wrong.