From ffcd2371ce835713c2c961a7baac39a5f3804832 Mon Sep 17 00:00:00 2001 From: Shibly Meeran Date: Tue, 16 Jul 2024 15:33:51 +0530 Subject: [PATCH] adding some optimisation on secret key initialization --- docs/KUBERNETES.md | 5 +++ internal/cli/commands/cmdvault/access.go | 4 +-- internal/cli/commands/cmdvault/deref.go | 2 +- internal/cli/commands/cmdvault/get.go | 2 +- internal/cli/commands/cmdvault/shell.go | 2 +- internal/core/vaults/access.go | 2 +- internal/k8s/api/v1/slv_webhook.go | 7 +++- .../k8s/internal/controller/slv_controller.go | 6 +++- internal/k8s/job/job.go | 7 ++-- internal/k8s/job/reconciler.go | 2 +- internal/k8s/operator/operator.go | 2 +- internal/k8s/utils/key.go | 34 +++++++++---------- slv.go | 2 +- 13 files changed, 45 insertions(+), 32 deletions(-) diff --git a/docs/KUBERNETES.md b/docs/KUBERNETES.md index b0aadfc..7f533d5 100644 --- a/docs/KUBERNETES.md +++ b/docs/KUBERNETES.md @@ -33,6 +33,11 @@ SLV supports two ways to reconcile SLV vaults as kuberenetes secrets: 1. [Operator](#operator) 2. [Job](#job) +SLV is compiled as a single binary, meaning the same binary can act as the CLI, K8s Operator, and K8s Job. Set the respective values to the environment variable `SLV_MODE` to make the SLV container act as an operator or job. + +- For Operator Mode set `SLV_MODE=k8s_operator` +- For Job Mode set `SLV_MODE=k8s_job` + ## Operator SLV operator is a kubenetes controller that runs inside a given cluster to write secrets into given namespaces based on changes in SLV resources. diff --git a/internal/cli/commands/cmdvault/access.go b/internal/cli/commands/cmdvault/access.go index 22df173..a82cbd5 100644 --- a/internal/cli/commands/cmdvault/access.go +++ b/internal/cli/commands/cmdvault/access.go @@ -64,7 +64,7 @@ func vaultAccessAddCommand() *cobra.Command { } vault, err := getVault(vaultFile) if err == nil { - err = vault.Unlock(*envSecretKey) + err = vault.Unlock(envSecretKey) if err == nil { for _, publicKey := range publicKeys { if _, err = vault.Share(publicKey); err != nil { @@ -113,7 +113,7 @@ func vaultAccessRemoveCommand() *cobra.Command { if err == nil { var envSecretKey *crypto.SecretKey if envSecretKey, err = secretkey.Get(); err == nil { - err = vault.Unlock(*envSecretKey) + err = vault.Unlock(envSecretKey) } if err == nil { if err = vault.Revoke(publicKeys, pq); err == nil { diff --git a/internal/cli/commands/cmdvault/deref.go b/internal/cli/commands/cmdvault/deref.go index 4c4c563..e2d88b3 100644 --- a/internal/cli/commands/cmdvault/deref.go +++ b/internal/cli/commands/cmdvault/deref.go @@ -34,7 +34,7 @@ func vaultDerefCommand() *cobra.Command { if err != nil { utils.ExitOnError(err) } - err = vault.Unlock(*envSecretKey) + err = vault.Unlock(envSecretKey) if err != nil { utils.ExitOnError(err) } diff --git a/internal/cli/commands/cmdvault/get.go b/internal/cli/commands/cmdvault/get.go index 5794853..d56c934 100644 --- a/internal/cli/commands/cmdvault/get.go +++ b/internal/cli/commands/cmdvault/get.go @@ -31,7 +31,7 @@ func vaultGetCommand() *cobra.Command { if err != nil { utils.ExitOnError(err) } - err = vault.Unlock(*envSecretKey) + err = vault.Unlock(envSecretKey) if err != nil { utils.ExitOnError(err) } diff --git a/internal/cli/commands/cmdvault/shell.go b/internal/cli/commands/cmdvault/shell.go index 65d611a..34f6e49 100644 --- a/internal/cli/commands/cmdvault/shell.go +++ b/internal/cli/commands/cmdvault/shell.go @@ -41,7 +41,7 @@ func vaultShellCommand() *cobra.Command { if err != nil { utils.ExitOnError(err) } - err = vault.Unlock(*envSecretKey) + err = vault.Unlock(envSecretKey) if err != nil { utils.ExitOnError(err) } diff --git a/internal/core/vaults/access.go b/internal/core/vaults/access.go index 95e113b..887760a 100644 --- a/internal/core/vaults/access.go +++ b/internal/core/vaults/access.go @@ -119,7 +119,7 @@ func (vlt *Vault) ListAccessors() ([]crypto.PublicKey, error) { return accessors, nil } -func (vlt *Vault) Unlock(secretKey crypto.SecretKey) error { +func (vlt *Vault) Unlock(secretKey *crypto.SecretKey) error { if !vlt.IsLocked() { return nil } diff --git a/internal/k8s/api/v1/slv_webhook.go b/internal/k8s/api/v1/slv_webhook.go index 60f9577..7fa8d8b 100644 --- a/internal/k8s/api/v1/slv_webhook.go +++ b/internal/k8s/api/v1/slv_webhook.go @@ -53,7 +53,12 @@ var _ webhook.Validator = &SLV{} func (r *SLV) validateSLV() error { vault := r.Spec.Vault - if err := vault.Unlock(*utils.SecretKey()); err != nil { + secretKey, err := utils.SecretKey() + if err != nil { + slvlog.Error(err, "failed to get secret key", "name", r.Name) + return err + } + if err := vault.Unlock(secretKey); err != nil { slvlog.Error(err, "failed to unlock vault", "name", r.Name) return err } diff --git a/internal/k8s/internal/controller/slv_controller.go b/internal/k8s/internal/controller/slv_controller.go index f921eca..3d379c3 100644 --- a/internal/k8s/internal/controller/slv_controller.go +++ b/internal/k8s/internal/controller/slv_controller.go @@ -114,7 +114,11 @@ func (r *SLVReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R } vault := slvObj.Spec.Vault - if err := vault.Unlock(*utils.SecretKey()); err != nil { + secretKey, err := utils.SecretKey() + if err != nil { + return r.returnError(ctx, &slvObj, &logger, err, "Failed to get secret key") + } + if err := vault.Unlock(secretKey); err != nil { return r.returnError(ctx, &slvObj, &logger, err, "Failed to unlock vault") } slvSecretMap, err := vault.GetAllSecrets() diff --git a/internal/k8s/job/job.go b/internal/k8s/job/job.go index 4d35503..67ea0e4 100644 --- a/internal/k8s/job/job.go +++ b/internal/k8s/job/job.go @@ -6,8 +6,9 @@ import ( ) func Run() { - if err := utils.InitSecretKey(); err != nil { - panic(err.Error()) + secretKey, err := utils.SecretKey() + if err != nil { + panic(err) } config, err := utils.GetKubeClientConfig() @@ -25,7 +26,7 @@ func Run() { panic(err) } - if err = slvsToSecrets(clientset, utils.SecretKey(), slvObjs); err != nil { + if err = slvsToSecrets(clientset, secretKey, slvObjs); err != nil { panic(err) } } diff --git a/internal/k8s/job/reconciler.go b/internal/k8s/job/reconciler.go index 92f6870..9c0582e 100644 --- a/internal/k8s/job/reconciler.go +++ b/internal/k8s/job/reconciler.go @@ -62,7 +62,7 @@ func listSLVs(cfg *rest.Config) ([]slvv1.SLV, error) { } func toSecret(clientset *kubernetes.Clientset, secretKey *crypto.SecretKey, slvObj slvv1.SLV) error { - if err := slvObj.Spec.Unlock(*secretKey); err != nil { + if err := slvObj.Spec.Unlock(secretKey); err != nil { return err } slvSecretMap, err := slvObj.Spec.GetAllSecrets() diff --git a/internal/k8s/operator/operator.go b/internal/k8s/operator/operator.go index f793ce3..b8cc9c3 100644 --- a/internal/k8s/operator/operator.go +++ b/internal/k8s/operator/operator.go @@ -80,7 +80,7 @@ func Run() { setupLog.Info("initializing SLV operator...") setupLog.Info(config.VersionInfo()) - if err := utils.InitSecretKey(); err != nil { + if _, err := utils.SecretKey(); err != nil { setupLog.Error(err, "unable to initialize SLV Environment Secret Key") os.Exit(1) } diff --git a/internal/k8s/utils/key.go b/internal/k8s/utils/key.go index 86d2aaf..9300c52 100644 --- a/internal/k8s/utils/key.go +++ b/internal/k8s/utils/key.go @@ -10,21 +10,26 @@ import ( "oss.amagi.com/slv/internal/core/secretkey" ) -var sKey *crypto.SecretKey +var ( + sKey *crypto.SecretKey + sKeyInitialized bool +) -func InitSecretKey() (err error) { - if sKey == nil { - sKey, _ = secretkey.Get() +func SecretKey() (secretKey *crypto.SecretKey, err error) { + if sKey == nil && !sKeyInitialized { + sKeyInitialized = true + sk, _ := secretkey.Get() if clientset, _ := getKubeClientSet(); clientset != nil { - if sKey == nil { - if sKey, err = getSecretKeyFromCluster(clientset); err != nil && isEnvGenEnabled() { - sKey, err = crypto.NewSecretKey(environments.EnvironmentKey) + if sk == nil { + if sk, err = getSecretKeyFromCluster(clientset); err != nil && isEnvGenEnabled() { + sk, err = crypto.NewSecretKey(environments.EnvironmentKey) } } - if err == nil && sKey != nil { + if err == nil && sk != nil { + sKey = sk var pkEC, pkPQ *crypto.PublicKey - if pkEC, err = sKey.PublicKey(false); err == nil { - if pkPQ, err = sKey.PublicKey(true); err == nil { + if pkEC, err = sk.PublicKey(false); err == nil { + if pkPQ, err = sk.PublicKey(true); err == nil { var publicKeyEC, publicKeyPQ string if publicKeyEC, err = pkEC.String(); err == nil { if publicKeyPQ, err = pkPQ.String(); err == nil { @@ -39,14 +44,7 @@ func InitSecretKey() (err error) { sKey = nil } } - return err -} - -func SecretKey() *crypto.SecretKey { - if err := InitSecretKey(); err != nil { - panic(err.Error()) - } - return sKey + return sKey, err } func GetPublicKeyFromK8s(namespace string, pq bool) (string, error) { diff --git a/slv.go b/slv.go index 679ef37..4a5fc99 100644 --- a/slv.go +++ b/slv.go @@ -14,7 +14,7 @@ func getVaultUnlocked(vaultFile string) (*vaults.Vault, error) { if err != nil { return nil, err } - if err = vault.Unlock(*secretKey); err != nil { + if err = vault.Unlock(secretKey); err != nil { return nil, err } return vault, nil