From 8fba7b9849b43a8a37096b0ba61536cd930e5c29 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Fri, 3 May 2024 16:55:16 +0900 Subject: [PATCH 01/31] chore: Update Docker image tags and platforms in CI workflow --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 32689d3..8a600e8 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,15 @@ You can change the tag to a specific version if you want like following: $ dokcer pull ghcr.io/h0n9/cloud-secrets-manager:v0.5 ``` +> For `aws-vault` users, the following command allows you to run the container +with the necessary credentials. We acknowledge that the command is a bit +lengthy, but rest assured, we're actively working on a more streamlined +solution, including a potential Homebrew release for Cloud Secrets Manager: + +```bash +$ aws-vault exec -- docker run --rm -it -e AWS_REGION -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN -e AWS_SECURITY_TOKEN ghcr.io/h0n9/cloud-secrets-manager:latest +``` + #### List Secrets ```bash From 8e2f32e6bdc99a6afea4cea32ae8ce216c547529 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 8 May 2024 09:32:56 +0900 Subject: [PATCH 02/31] chore: Update Homebrew installation command in README.md --- README.md | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 8a600e8..0ee8b28 100644 --- a/README.md +++ b/README.md @@ -130,32 +130,25 @@ following explanation. #### Installation -As Cloud Secrets Manager is available as a Docker image, there is no need to -install the CLI tool. Just run the Docker container as follows: +Cloud Secrets Manager can be installed via Homebrew: ```bash -$ dokcer pull ghcr.io/h0n9/cloud-secrets-manager:latest +$ brew install h0n9/devops/cloud-secrets-manager ``` -You can change the tag to a specific version if you want like following: +That's it! You can now use the `cloud-secrets-manager` command. -```bash -$ dokcer pull ghcr.io/h0n9/cloud-secrets-manager:v0.5 -``` - -> For `aws-vault` users, the following command allows you to run the container -with the necessary credentials. We acknowledge that the command is a bit -lengthy, but rest assured, we're actively working on a more streamlined -solution, including a potential Homebrew release for Cloud Secrets Manager: +> For `aws-vault` users, you can use the following command to execute the +`cloud-secrets-manager` command with the specified AWS profile: ```bash -$ aws-vault exec -- docker run --rm -it -e AWS_REGION -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN -e AWS_SECURITY_TOKEN ghcr.io/h0n9/cloud-secrets-manager:latest +$ aws-vault exec -- cloud-secrets-manager ``` #### List Secrets ```bash -$ docker run --rm -it ghcr.io/h0n9/cloud-secrets-manager:latest secrets list --provider aws --limit 3 +$ cloud-secrets-manager secrets list --provider aws --limit 3 dev/hello-world dev/very-precious-secret dev/another-secret @@ -165,7 +158,7 @@ The `--limit` option is available to limit the number of secrets to be listed. #### Edit Secret ```bash -$ docker run --rm -it ghcr.io/h0n9/cloud-secrets-manager:latest secrets edit --provider aws --secret-id dev/very-precious-secret +$ cloud-secrets-manager secrets edit --provider aws --secret-id dev/very-precious-secret ``` A text editor will be opened with the secret value. After editing, save and @@ -176,5 +169,5 @@ If you want to use a specific editor, set the `EDITOR` environment variable. ```bash $ export EDITOR=nano -$ docker run --rm -it ghcr.io/h0n9/cloud-secrets-manager:latest secrets edit --provider aws --secret-id dev/very-precious-secret +$ cloud-secrets-manager secrets edit --provider aws --secret-id dev/very-precious-secret ``` From 851cee37f39e967840df9ee991dab2089ac57854 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 8 May 2024 09:49:53 +0900 Subject: [PATCH 03/31] chore: Update cloud-secrets-manager command in README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0ee8b28..ae7ac36 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ Cloud Secrets Manager can be installed via Homebrew: $ brew install h0n9/devops/cloud-secrets-manager ``` -That's it! You can now use the `cloud-secrets-manager` command. +That's it! You can now use the `cloud-secrets-manager`, or `csm` commands. > For `aws-vault` users, you can use the following command to execute the `cloud-secrets-manager` command with the specified AWS profile: @@ -148,7 +148,7 @@ $ aws-vault exec -- cloud-secrets-manager #### List Secrets ```bash -$ cloud-secrets-manager secrets list --provider aws --limit 3 +$ csm secrets list --provider aws --limit 3 dev/hello-world dev/very-precious-secret dev/another-secret @@ -158,7 +158,7 @@ The `--limit` option is available to limit the number of secrets to be listed. #### Edit Secret ```bash -$ cloud-secrets-manager secrets edit --provider aws --secret-id dev/very-precious-secret +$ csm secrets edit --provider aws --secret-id dev/very-precious-secret ``` A text editor will be opened with the secret value. After editing, save and @@ -169,5 +169,5 @@ If you want to use a specific editor, set the `EDITOR` environment variable. ```bash $ export EDITOR=nano -$ cloud-secrets-manager secrets edit --provider aws --secret-id dev/very-precious-secret +$ csm secrets edit --provider aws --secret-id dev/very-precious-secret ``` From 6380b5439d819810f8d64b1659e10fa23587dd9f Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 8 May 2024 09:50:10 +0900 Subject: [PATCH 04/31] chore: Update cloud-secrets-manager command in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ae7ac36..ff89c5b 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ Cloud Secrets Manager can be installed via Homebrew: $ brew install h0n9/devops/cloud-secrets-manager ``` -That's it! You can now use the `cloud-secrets-manager`, or `csm` commands. +That's it! You can now use the `cloud-secrets-manager` or `csm` commands. > For `aws-vault` users, you can use the following command to execute the `cloud-secrets-manager` command with the specified AWS profile: From 5d3f3145c7d793e29f5f5487b959d755c3b1e04d Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 8 May 2024 09:50:44 +0900 Subject: [PATCH 05/31] chore: Update cloud-secrets-manager command in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ff89c5b..891094d 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ That's it! You can now use the `cloud-secrets-manager` or `csm` commands. `cloud-secrets-manager` command with the specified AWS profile: ```bash -$ aws-vault exec -- cloud-secrets-manager +$ aws-vault exec -- csm ``` #### List Secrets From 222e411d6f45334bdd4157e77dacf46d3dc4c294 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Tue, 4 Jun 2024 12:01:27 +0900 Subject: [PATCH 06/31] Make injector get injected as first init container --- webhook/mutator.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/webhook/mutator.go b/webhook/mutator.go index be49546..8cc8cef 100644 --- a/webhook/mutator.go +++ b/webhook/mutator.go @@ -69,8 +69,8 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, }) - // inject sidecar - pod.Spec.InitContainers = append(pod.Spec.InitContainers, corev1.Container{ + // create init container for injection + initContainer := corev1.Container{ Name: injectorName, Image: mutator.InjectorImage, Args: []string{ @@ -87,7 +87,10 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis MountPath: csm.InjectorVolumeMountPath, }, }, - }) + } + + // append init container to pod's init containers + pod.Spec.InitContainers = append([]corev1.Container{initContainer}, pod.Spec.InitContainers...) // mount volume to every containers for i := range pod.Spec.Containers { From d8832de9c74aa3ea13d47fc5d4843f49924ad284 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Tue, 4 Jun 2024 14:13:06 +0900 Subject: [PATCH 07/31] feat: Mount volume to every init container in mutator.go --- webhook/mutator.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/webhook/mutator.go b/webhook/mutator.go index 8cc8cef..cfab4ec 100644 --- a/webhook/mutator.go +++ b/webhook/mutator.go @@ -69,6 +69,15 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, }) + // mount volume to every init containers + for i := range pod.Spec.InitContainers { + pod.Spec.InitContainers[i].VolumeMounts = append(pod.Spec.InitContainers[i].VolumeMounts, corev1.VolumeMount{ + Name: injectorName, + MountPath: output, + SubPath: filepath.Base(output), + }) + } + // create init container for injection initContainer := corev1.Container{ Name: injectorName, From fd213aeede6bf63014e17271db6c5bad4894a75a Mon Sep 17 00:00:00 2001 From: h0n9 Date: Tue, 4 Jun 2024 14:15:35 +0900 Subject: [PATCH 08/31] Minor updates --- webhook/mutator.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/webhook/mutator.go b/webhook/mutator.go index cfab4ec..dcdb086 100644 --- a/webhook/mutator.go +++ b/webhook/mutator.go @@ -78,6 +78,15 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis }) } + // mount volume to every containers + for i := range pod.Spec.Containers { + pod.Spec.Containers[i].VolumeMounts = append(pod.Spec.Containers[i].VolumeMounts, corev1.VolumeMount{ + Name: injectorName, + MountPath: output, + SubPath: filepath.Base(output), + }) + } + // create init container for injection initContainer := corev1.Container{ Name: injectorName, @@ -101,15 +110,6 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis // append init container to pod's init containers pod.Spec.InitContainers = append([]corev1.Container{initContainer}, pod.Spec.InitContainers...) - // mount volume to every containers - for i := range pod.Spec.Containers { - pod.Spec.Containers[i].VolumeMounts = append(pod.Spec.Containers[i].VolumeMounts, corev1.VolumeMount{ - Name: injectorName, - MountPath: output, - SubPath: filepath.Base(output), - }) - } - // set annotation for injection to true injected := "injected" if secretName != "" { From 223fabeebd7902b4e0937674ac7ab6ff47edb64e Mon Sep 17 00:00:00 2001 From: h0n9 Date: Tue, 4 Jun 2024 14:23:05 +0900 Subject: [PATCH 09/31] Minor updates to enhance readability --- webhook/mutator.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/webhook/mutator.go b/webhook/mutator.go index dcdb086..9034409 100644 --- a/webhook/mutator.go +++ b/webhook/mutator.go @@ -69,12 +69,16 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, }) + // prepare mount path for general use + mountPath := output + subPath := filepath.Base(mountPath) + // mount volume to every init containers for i := range pod.Spec.InitContainers { pod.Spec.InitContainers[i].VolumeMounts = append(pod.Spec.InitContainers[i].VolumeMounts, corev1.VolumeMount{ Name: injectorName, - MountPath: output, - SubPath: filepath.Base(output), + MountPath: mountPath, + SubPath: subPath, }) } @@ -82,8 +86,8 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis for i := range pod.Spec.Containers { pod.Spec.Containers[i].VolumeMounts = append(pod.Spec.Containers[i].VolumeMounts, corev1.VolumeMount{ Name: injectorName, - MountPath: output, - SubPath: filepath.Base(output), + MountPath: mountPath, + SubPath: subPath, }) } @@ -97,7 +101,7 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis fmt.Sprintf("--provider=%s", providerStr), fmt.Sprintf("--secret-id=%s", secretID), fmt.Sprintf("--template=%s", util.EncodeBase64(tmplStr)), - fmt.Sprintf("--output=%s", filepath.Join(csm.InjectorVolumeMountPath, filepath.Base(output))), + fmt.Sprintf("--output=%s", filepath.Join(csm.InjectorVolumeMountPath, subPath)), }, VolumeMounts: []corev1.VolumeMount{ { From 64cd3b0019c6827653d45f6c3c0ae240577e2b50 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 08:44:34 +0900 Subject: [PATCH 10/31] feat: Add base64 decoding for secret values in Save method --- handler/handler.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/handler/handler.go b/handler/handler.go index b9b96d8..817e7e6 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -1,7 +1,9 @@ package handler import ( + "encoding/base64" "encoding/json" + "fmt" "os" "text/template" @@ -34,12 +36,27 @@ func (handler *SecretHandler) Get(secretID string) (map[string]interface{}, erro return m, nil } -func (handler *SecretHandler) Save(secretID, path string) error { +func (handler *SecretHandler) Save(secretID, path string, decodeBase64EncodedSecret bool) error { m, err := handler.Get(secretID) if err != nil { return err } + if decodeBase64EncodedSecret { + for key, value := range m { + switch t := value.(type) { + case string: + decodedValue, err := base64.StdEncoding.DecodeString(value.(string)) + if err != nil { + return err + } + m[key] = decodedValue + default: + return fmt.Errorf("unsupported type: %T", t) + } + } + } + file, err := os.Create(path) if err != nil { return err From 3513c0e4da7f5228f7b98bc04d2b78cf274a0067 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 08:45:57 +0900 Subject: [PATCH 11/31] feat: Add base64 decoding for secret values for injector cmd --- cli/injector/injector.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/cli/injector/injector.go b/cli/injector/injector.go index 8d36d48..b4f3a51 100644 --- a/cli/injector/injector.go +++ b/cli/injector/injector.go @@ -27,10 +27,11 @@ var Cmd = &cobra.Command{ } var ( - providerName string - secretID string - templateBase64 string - output string + providerName string + secretID string + templateBase64 string + output string + decodeBase64EncodedSecret bool ) var runCmd = &cobra.Command{ @@ -92,7 +93,7 @@ var runCmd = &cobra.Command{ logger.Info().Msg("initialized secret handler") - err = secretHandler.Save(secretID, output) + err = secretHandler.Save(secretID, output, decodeBase64EncodedSecret) if err != nil { return err } @@ -128,5 +129,11 @@ func init() { "secret", "output filename", ) + runCmd.Flags().BoolVar( + &decodeBase64EncodedSecret, + "decode-b64-secret", + false, + "decode base64 encoded secret", + ) Cmd.AddCommand(runCmd) } From d593d2b4b7f857b2165250b3e1a9ce5c0b046925 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 08:50:51 +0900 Subject: [PATCH 12/31] feat: Add base64 decoding for secret values in annotation.go --- webhook/annotation.go | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/webhook/annotation.go b/webhook/annotation.go index 4b554a5..3e00dc9 100644 --- a/webhook/annotation.go +++ b/webhook/annotation.go @@ -9,21 +9,23 @@ import ( ) const ( - AnnotationProvider = "provider" - AnnotationSecretID = "secret-id" - AnnotationTemplate = "template" - AnnotationOutput = "output" - AnnotationInjected = "injected" + AnnotationProvider = "provider" + AnnotationSecretID = "secret-id" + AnnotationTemplate = "template" + AnnotationOutput = "output" + AnnotationDecodeB64 = "decode-base64" + AnnotationInjected = "injected" ) type AnnotationSet map[string]Annotations var AnnotationMap = map[string]string{ - fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationProvider): AnnotationProvider, - fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationSecretID): AnnotationSecretID, - fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationTemplate): AnnotationTemplate, - fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationOutput): AnnotationOutput, - fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationInjected): AnnotationInjected, + fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationProvider): AnnotationProvider, + fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationSecretID): AnnotationSecretID, + fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationTemplate): AnnotationTemplate, + fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationOutput): AnnotationOutput, + fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationDecodeB64): AnnotationDecodeB64, + fmt.Sprintf("%s/%s", csm.AnnotationPrefix, AnnotationInjected): AnnotationInjected, } func ParseAnnotationSet(input map[string]string) AnnotationSet { @@ -53,11 +55,12 @@ func ParseAnnotationSet(input map[string]string) AnnotationSet { type Annotations map[string]string var annotationsAvailable = map[string]bool{ - AnnotationProvider: true, - AnnotationSecretID: true, - AnnotationTemplate: true, - AnnotationOutput: true, - AnnotationInjected: true, + AnnotationProvider: true, + AnnotationSecretID: true, + AnnotationTemplate: true, + AnnotationOutput: true, + AnnotationDecodeB64: true, + AnnotationInjected: true, } func ParseAndCheckAnnotations(input Annotations) Annotations { @@ -110,3 +113,11 @@ func (a Annotations) GetTemplate() (string, error) { func (a Annotations) GetOutput() (string, error) { return a.getValue(AnnotationOutput) } + +func (a Annotations) GetDecodeB64() (bool, error) { + value, err := a.getValue(AnnotationDecodeB64) + if err != nil { + return false, err + } + return strconv.ParseBool(value) +} From cee71edd3d4860a2aed21391f907f642fc8f8380 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 08:56:13 +0900 Subject: [PATCH 13/31] feat: Add base64 decoding for secret values in mutator.go --- webhook/mutator.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/webhook/mutator.go b/webhook/mutator.go index 9034409..d728f95 100644 --- a/webhook/mutator.go +++ b/webhook/mutator.go @@ -56,6 +56,10 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis if err != nil { return admission.Errored(http.StatusBadRequest, err) } + decodeB64, err := annotations.GetDecodeB64() + if err != nil { + return admission.Errored(http.StatusBadRequest, err) + } // prepare injector name for general use injectorName := "cloud-secrets-injector" @@ -102,6 +106,7 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis fmt.Sprintf("--secret-id=%s", secretID), fmt.Sprintf("--template=%s", util.EncodeBase64(tmplStr)), fmt.Sprintf("--output=%s", filepath.Join(csm.InjectorVolumeMountPath, subPath)), + fmt.Sprintf("--decode-b64-secret=%t", decodeB64), }, VolumeMounts: []corev1.VolumeMount{ { From d3430ded8c51e6008f5ce5673f88200a46f90d12 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 08:58:30 +0900 Subject: [PATCH 14/31] chore: Enable image push in CI workflow --- .github/workflows/ci.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1b79473..fa68d48 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -13,7 +13,7 @@ env: img-registry: ghcr.io/h0n9 img-repository: cloud-secrets-manager img-tags: ghcr.io/h0n9/cloud-secrets-manager:tmp - img-push: "false" + img-push: "true" img-platforms: linux/amd64 jobs: build-push: @@ -31,11 +31,9 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: "Set env vars (develop)" - if: ${{ github.ref_name == 'develop' }} shell: bash run: | echo "img-tags=${{ env.img-registry }}/${{ env.img-repository }}:dev-${GITHUB_SHA::6}" >> $GITHUB_ENV - echo "img-push=true" >> $GITHUB_ENV - name: "Set env vars (tag)" if: ${{ startsWith(github.ref_name, 'v') }} shell: bash From d0952b5a535bff6ab17fb5aac6076c1c082f3ee6 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 09:01:08 +0900 Subject: [PATCH 15/31] chore: Exclude docs and markdown files from CI workflow paths-ignore --- .github/workflows/ci.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fa68d48..9ad1203 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,6 +9,8 @@ on: - v* paths-ignore: - ".github/**" + - "docs/**" + - "*.md" env: img-registry: ghcr.io/h0n9 img-repository: cloud-secrets-manager From 4e6b839b6e22b5e5908dc3721c928e70ae999b5f Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 09:06:19 +0900 Subject: [PATCH 16/31] chore: Remove unnecessary login step condition in CI workflow --- .github/workflows/ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9ad1203..44dbfcf 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,7 +24,6 @@ jobs: - name: Checkout uses: actions/checkout@v2 - name: Login to GitHub Container Registry - if: ${{ github.ref_name == 'develop' || startsWith(github.ref_name, 'v') }} uses: docker/login-action@v2 with: registry: ${{ env.img-registry }} From b978499b0c9b419697ea295eec078a9b3c314438 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 09:07:26 +0900 Subject: [PATCH 17/31] chore: Update CI workflow to include manual triggering --- .github/workflows/ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 44dbfcf..6d38de9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,5 +1,6 @@ name: ci on: + workflow_dispatch: push: branches: - main From bbe61632939e6e3cff96a6e7e82bad4f12c92818 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 09:11:11 +0900 Subject: [PATCH 18/31] docs: Add explanation for `decode-base64` annotation --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 891094d..3acc257 100644 --- a/README.md +++ b/README.md @@ -82,13 +82,14 @@ of other new charts. The following annotatins are required to inject `cloud-secrets-injector` into pods: -| **Key** | **Required** | **Description** | **Example** | -|----------------------------------------------------|--------------|---------------------------|----------------------------------------------------------| -| `cloud-secrets-manager.h0n9.postie.chat/provider` | true | Cloud Provider Name | `aws` | -| `cloud-secrets-manager.h0n9.postie.chat/secret-id` | true | Secret Name | `very-precious-secret` | -| `cloud-secrets-manager.h0n9.postie.chat/template` | true | Template for secret value | ```{{ range $k, $v := . }}{{ $k }}={{ $v }} {{ end }}``` | -| `cloud-secrets-manager.h0n9.postie.chat/output` | true | File path for output | `/secrets/env` | -| `cloud-secrets-manager.h0n9.postie.chat/injected` | false | Identifier for injection | `false` | +| **Key** | **Required** | **Description** | **Example** | +|--------------------------------------------------------|--------------|------------------------------|----------------------------------------------------------| +| `cloud-secrets-manager.h0n9.postie.chat/provider` | true | Cloud Provider Name | `aws` | +| `cloud-secrets-manager.h0n9.postie.chat/secret-id` | true | Secret Name | `very-precious-secret` | +| `cloud-secrets-manager.h0n9.postie.chat/template` | true | Template for secret value | ```{{ range $k, $v := . }}{{ $k }}={{ $v }} {{ end }}``` | +| `cloud-secrets-manager.h0n9.postie.chat/output` | true | File path for output | `/secrets/env` | +| `cloud-secrets-manager.h0n9.postie.chat/decode-base64` | false | Decode base64-encoded string | `true` or `false` | +| `cloud-secrets-manager.h0n9.postie.chat/injected` | false | Identifier for injection | `false` | #### Annotations for Multiple Secrets Injection From baffbae2d6b3fdad53a69f9b9dac904d84b04b83 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 09:19:26 +0900 Subject: [PATCH 19/31] chore: Remove unused const variales --- cli/cli.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cli/cli.go b/cli/cli.go index 5ffb1dc..147f55d 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -7,12 +7,6 @@ import ( "github.com/spf13/cobra" ) -const ( - DefaultProviderName = "aws" - DefaultTemplateBase64 = "e3sgcmFuZ2UgJGssICR2IDo9IC4gfX1be3sgJGsgfX1dCnt7ICR2IH19Cgp7eyBlbmQgfX0K" - DefaultOutputFilename = "output" -) - var VersionCmd = &cobra.Command{ Use: "version", Short: fmt.Sprintf("print '%s' version information", csm.Name), From c1a47aadd7fcfeb13521cf8c7a474e0105c1fbb0 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 09:22:31 +0900 Subject: [PATCH 20/31] chore: Update injector.go to handle empty output filename and default decode base64 to false --- cli/injector/injector.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/cli/injector/injector.go b/cli/injector/injector.go index b4f3a51..7d8569a 100644 --- a/cli/injector/injector.go +++ b/cli/injector/injector.go @@ -17,8 +17,10 @@ import ( const ( DefaultProviderName = "aws" + DefaultSecretID = "" DefaultTemplateBase64 = "e3sgcmFuZ2UgJGssICR2IDo9IC4gfX1be3sgJGsgfX1dCnt7ICR2IH19Cgp7eyBlbmQgfX0K" - DefaultOutputFilename = "output" + DefaultOutputFilename = "" + DefaultDecodeBase64 = false ) var Cmd = &cobra.Command{ @@ -30,7 +32,7 @@ var ( providerName string secretID string templateBase64 string - output string + outputFilename string decodeBase64EncodedSecret bool ) @@ -46,10 +48,13 @@ var runCmd = &cobra.Command{ logger.Info().Msg("initialized context") - // get envs + // check required flags if secretID == "" { return fmt.Errorf("failed to read 'secret-id' flag") } + if outputFilename == "" { + return fmt.Errorf("failed to read 'output' flag") + } logger.Info().Msg("read environment variables") @@ -93,12 +98,12 @@ var runCmd = &cobra.Command{ logger.Info().Msg("initialized secret handler") - err = secretHandler.Save(secretID, output, decodeBase64EncodedSecret) + err = secretHandler.Save(secretID, outputFilename, decodeBase64EncodedSecret) if err != nil { return err } - logger.Info().Msg(fmt.Sprintf("saved secret id '%s' values to '%s'", secretID, output)) + logger.Info().Msg(fmt.Sprintf("saved secret id '%s' values to '%s'", secretID, outputFilename)) return nil }, @@ -108,7 +113,7 @@ func init() { runCmd.Flags().StringVar( &providerName, "provider", - "aws", + DefaultProviderName, "cloud provider name", ) runCmd.Flags().StringVar( @@ -120,20 +125,20 @@ func init() { runCmd.Flags().StringVar( &templateBase64, "template", - "e3sgcmFuZ2UgJGssICR2IDo9IC4gfX1be3sgJGsgfX1dCnt7ICR2IH19Cgp7eyBlbmQgfX0K", + DefaultTemplateBase64, "base64 encoded template string", ) runCmd.Flags().StringVar( - &output, + &outputFilename, "output", - "secret", + DefaultOutputFilename, "output filename", ) runCmd.Flags().BoolVar( &decodeBase64EncodedSecret, "decode-b64-secret", - false, - "decode base64 encoded secret", + DefaultDecodeBase64, + "decode base64-encoded secret", ) Cmd.AddCommand(runCmd) } From b5da5631907253c2618ad3e616e30048f9775f32 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 09:44:35 +0900 Subject: [PATCH 21/31] chore: Update annotation.go to handle default value for GetDecodeB64 --- webhook/annotation.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webhook/annotation.go b/webhook/annotation.go index 3e00dc9..661ce0f 100644 --- a/webhook/annotation.go +++ b/webhook/annotation.go @@ -117,7 +117,8 @@ func (a Annotations) GetOutput() (string, error) { func (a Annotations) GetDecodeB64() (bool, error) { value, err := a.getValue(AnnotationDecodeB64) if err != nil { - return false, err + // default value and no error + return false, nil } return strconv.ParseBool(value) } From 7f7deab58d094e6b86d4c5316e3c86fb9cdc48a7 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 10:27:36 +0900 Subject: [PATCH 22/31] refactor: Update base64 encoding and decoding functions - Rename `EncodeBase64` to `EncodeBase64StrToStr` - Rename `DecodeBase64` to `DecodeBase64StrToStr` - Add new function `DecodeBase64StrToBytes` - Update usages of the renamed functions in `util.go` --- util/util.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/util/util.go b/util/util.go index ea3ebfd..8f603a2 100644 --- a/util/util.go +++ b/util/util.go @@ -13,18 +13,22 @@ func GetEnv(key, fallback string) string { return fallback } -func EncodeBase64(input string) string { +func EncodeBase64StrToStr(input string) string { return base64.RawStdEncoding.EncodeToString([]byte(input)) } -func DecodeBase64(input string) (string, error) { - output, err := base64.RawStdEncoding.DecodeString(input) +func DecodeBase64StrToStr(input string) (string, error) { + output, err := DecodeBase64StrToBytes(input) if err != nil { return "", err } return string(output), nil } +func DecodeBase64StrToBytes(input string) ([]byte, error) { + return base64.RawStdEncoding.DecodeString(input) +} + func ReadFileToBytes(filename string) ([]byte, error) { data, err := ioutil.ReadFile(filename) if err != nil { From c1139fd8dee72c7305e85a702dd5dae93c5cef51 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 10:29:16 +0900 Subject: [PATCH 23/31] refactor: Update base64 encoding and decoding functions --- cli/injector/injector.go | 2 +- cli/template/decode.go | 2 +- cli/template/encode.go | 2 +- cli/template/test.go | 2 +- webhook/mutator.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cli/injector/injector.go b/cli/injector/injector.go index 7d8569a..2e55928 100644 --- a/cli/injector/injector.go +++ b/cli/injector/injector.go @@ -59,7 +59,7 @@ var runCmd = &cobra.Command{ logger.Info().Msg("read environment variables") // decode base64-encoded template to string - templateStr, err := util.DecodeBase64(templateBase64) + templateStr, err := util.DecodeBase64StrToStr(templateBase64) if err != nil { return err } diff --git a/cli/template/decode.go b/cli/template/decode.go index dc79e60..e542103 100644 --- a/cli/template/decode.go +++ b/cli/template/decode.go @@ -16,7 +16,7 @@ var decodeCmd = &cobra.Command{ if args[0] == "" { return fmt.Errorf("failed to decode empty string") } - template, err := util.DecodeBase64(args[0]) + template, err := util.DecodeBase64StrToStr(args[0]) if err != nil { return err } diff --git a/cli/template/encode.go b/cli/template/encode.go index 15056d7..c54c7cc 100644 --- a/cli/template/encode.go +++ b/cli/template/encode.go @@ -16,7 +16,7 @@ var encodeCmd = &cobra.Command{ if args[0] == "" { return fmt.Errorf("failed to encode empty string") } - fmt.Println(util.EncodeBase64(args[0])) + fmt.Println(util.EncodeBase64StrToStr(args[0])) return nil }, } diff --git a/cli/template/test.go b/cli/template/test.go index 5b7c190..e370786 100644 --- a/cli/template/test.go +++ b/cli/template/test.go @@ -18,7 +18,7 @@ var testCmd = &cobra.Command{ if args[0] == "" { return fmt.Errorf("failed to test empty string") } - templateStr, err := util.DecodeBase64(args[0]) + templateStr, err := util.DecodeBase64StrToStr(args[0]) if err != nil { return err } diff --git a/webhook/mutator.go b/webhook/mutator.go index d728f95..65cc84c 100644 --- a/webhook/mutator.go +++ b/webhook/mutator.go @@ -104,7 +104,7 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis "run", fmt.Sprintf("--provider=%s", providerStr), fmt.Sprintf("--secret-id=%s", secretID), - fmt.Sprintf("--template=%s", util.EncodeBase64(tmplStr)), + fmt.Sprintf("--template=%s", util.EncodeBase64StrToStr(tmplStr)), fmt.Sprintf("--output=%s", filepath.Join(csm.InjectorVolumeMountPath, subPath)), fmt.Sprintf("--decode-b64-secret=%t", decodeB64), }, From c74d4a56eb0dc67f9d28d058c5d057ec834a6104 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 10:39:45 +0900 Subject: [PATCH 24/31] refactor: Update secret saving logic to handle base64 encoded secrets The code changes in this commit update the `Save` method in the `SecretHandler` struct to handle base64 encoded secrets. If the `decodeBase64EncodedSecret` flag is set to true, the secret is decoded from base64 and then saved to the specified file. This allows for more flexibility in handling secrets that are stored in base64 format. --- handler/handler.go | 47 ++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/handler/handler.go b/handler/handler.go index 817e7e6..4709372 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -1,13 +1,13 @@ package handler import ( - "encoding/base64" + "bytes" "encoding/json" - "fmt" "os" "text/template" "github.com/h0n9/cloud-secrets-manager/provider" + "github.com/h0n9/cloud-secrets-manager/util" ) type SecretHandlerFunc func(string) (string, error) @@ -37,31 +37,42 @@ func (handler *SecretHandler) Get(secretID string) (map[string]interface{}, erro } func (handler *SecretHandler) Save(secretID, path string, decodeBase64EncodedSecret bool) error { + // get secret m, err := handler.Get(secretID) if err != nil { return err } - if decodeBase64EncodedSecret { - for key, value := range m { - switch t := value.(type) { - case string: - decodedValue, err := base64.StdEncoding.DecodeString(value.(string)) - if err != nil { - return err - } - m[key] = decodedValue - default: - return fmt.Errorf("unsupported type: %T", t) - } - } - } - + // create file file, err := os.Create(path) if err != nil { return err } defer file.Close() - return handler.template.Execute(file, m) + // if secret is not base64 encoded, write it to file and return + if !decodeBase64EncodedSecret { + return handler.template.Execute(file, m) + } + + var ( + buff bytes.Buffer + decodedSecret []byte + ) + + // execute template + err = handler.template.Execute(&buff, m) + if err != nil { + return err + } + + // decode base64 encoded secret + decodedSecret, err = util.DecodeBase64StrToBytes(buff.String()) + if err != nil { + return err + } + + // write decoded secret to file + _, err = file.Write(decodedSecret) + return err } From 02f350cb317bfe95c939a11c0ef7efe4adb10155 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 11:00:46 +0900 Subject: [PATCH 25/31] refactor: Add base64 decoding function and update util.go The code changes in this commit add a new function `DecodeBase64BytesToBytes` to the `util.go` file. This function decodes a base64 encoded byte slice and returns the decoded bytes. Additionally, the existing `DecodeBase64StrToBytes` function is modified to use the `base64.StdEncoding.Decode` method instead of `base64.RawStdEncoding.DecodeString`. This ensures consistent decoding behavior across the codebase. --- util/util.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/util/util.go b/util/util.go index 8f603a2..1bd79a9 100644 --- a/util/util.go +++ b/util/util.go @@ -29,6 +29,15 @@ func DecodeBase64StrToBytes(input string) ([]byte, error) { return base64.RawStdEncoding.DecodeString(input) } +func DecodeBase64BytesToBytes(input []byte) ([]byte, error) { + output := make([]byte, base64.StdEncoding.DecodedLen(len(input))) + n, err := base64.StdEncoding.Decode(output, input) + if err != nil { + return nil, err + } + return output[:n], nil +} + func ReadFileToBytes(filename string) ([]byte, error) { data, err := ioutil.ReadFile(filename) if err != nil { From ad08a020aeb7bbc9c3cf0cb249f88c639c5c0fdd Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 11:01:15 +0900 Subject: [PATCH 26/31] refactor: Update Save method to handle base64 encoded secrets The Save method in the SecretHandler struct is updated to handle base64 encoded secrets. If the decodeBase64EncodedSecret flag is set to true, the secret is decoded from base64 and then saved to the specified file. This allows for more flexibility in handling secrets that are stored in base64 format. --- handler/handler.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/handler/handler.go b/handler/handler.go index 4709372..02ebe22 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -55,24 +55,24 @@ func (handler *SecretHandler) Save(secretID, path string, decodeBase64EncodedSec return handler.template.Execute(file, m) } - var ( - buff bytes.Buffer - decodedSecret []byte - ) - // execute template + var buff bytes.Buffer err = handler.template.Execute(&buff, m) if err != nil { return err } // decode base64 encoded secret - decodedSecret, err = util.DecodeBase64StrToBytes(buff.String()) + decodedSecret, err := util.DecodeBase64BytesToBytes(buff.Bytes()) if err != nil { return err } // write decoded secret to file _, err = file.Write(decodedSecret) - return err + if err != nil { + return err + } + + return nil } From 66dc0c0e8a065f0c4ef5e18b156334b71471adc7 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 11:19:07 +0900 Subject: [PATCH 27/31] test: Update test codes for annotations --- webhook/annotation_test.go | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/webhook/annotation_test.go b/webhook/annotation_test.go index 2032326..ddd45b9 100644 --- a/webhook/annotation_test.go +++ b/webhook/annotation_test.go @@ -20,6 +20,7 @@ func TestParseAndCheckAnnotations(t *testing.T) { "cloud-secrets-manager.h0n9.postie.chat/output": "/envs", // ✅ "cloud-secrets-manager.h0n9.postie.chat/template": SampleTemplate, // ✅ "cloud-secrets-manager.h0n9.postie.chat/injected": "true", // ✅ + "cloud-secrets-manager.h0n9.postie.chat/decode-base64": "true", // ✅ "cloud-secrets-manager.h0n9.posite.chat/template": SampleTemplate, // ❌: typo "cloud-secrets-manager.h0n9.postie.chat/volume-path": "/envs", // ❌: unsupported "cloud-secrets-manager.h0n9.postie.chat": "h0n9", // ❌: non subpath @@ -27,11 +28,12 @@ func TestParseAndCheckAnnotations(t *testing.T) { } output := ParseAndCheckAnnotations(input) expectedOutput := Annotations{ - "provider": "aws", - "secret-id": "life-is-beautiful", - "template": SampleTemplate, - "output": "/envs", - "injected": "true", + "provider": "aws", + "secret-id": "life-is-beautiful", + "template": SampleTemplate, + "output": "/envs", + "decode-base64": "true", + "injected": "true", } assert.EqualValues(t, expectedOutput, output) } @@ -43,6 +45,7 @@ func TestParseAnnotationSet(t *testing.T) { "cloud-secrets-manager.h0n9.postie.chat/output": "/envs", // ✅ "cloud-secrets-manager.h0n9.postie.chat/template": SampleTemplate, // ✅ "cloud-secrets-manager.h0n9.postie.chat/injected": "true", // ✅ + "cloud-secrets-manager.h0n9.postie.chat/decode-base64": "true", // ✅ "cloud-secrets-manager.h0n9.posite.chat/template": SampleTemplate, // ❌: typo "cloud-secrets-manager.h0n9.postie.chat/volume-path": "/envs", // ❌: unsupported "cloud-secrets-manager.h0n9.postie.chat": "h0n9", // ❌: non subpath @@ -52,22 +55,25 @@ func TestParseAnnotationSet(t *testing.T) { "cloud-secrets-manager.h0n9.postie.chat/output-test": "/secrets/envs", // ✅ "cloud-secrets-manager.h0n9.postie.chat/template-test": SampleTemplate, // ✅ "cloud-secrets-manager.h0n9.postie.chat/injected-test": "false", // ✅ + "cloud-secrets-manager.h0n9.postie.chat/decode-base64-test": "false", // ✅ } output := ParseAnnotationSet(input) expectedOutput := AnnotationSet{ "": Annotations{ - "provider": "aws", - "secret-id": "life-is-beautiful", - "template": SampleTemplate, - "output": "/envs", - "injected": "true", + "provider": "aws", + "secret-id": "life-is-beautiful", + "template": SampleTemplate, + "output": "/envs", + "decode-base64": "true", + "injected": "true", }, "test": Annotations{ - "provider": "gcp", - "secret-id": "life-is-wonderful", - "template": SampleTemplate, - "output": "/secrets/envs", - "injected": "false", + "provider": "gcp", + "secret-id": "life-is-wonderful", + "template": SampleTemplate, + "output": "/secrets/envs", + "decode-base64": "false", + "injected": "false", }, } assert.EqualValues(t, expectedOutput, output) From b67232a5839088aff82f65f5c770ded678a1694f Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 11:20:23 +0900 Subject: [PATCH 28/31] refactor: Fix typo in IsInjected method name The IsInected method in the Annotations struct is renamed to IsInjected to accurately reflect its purpose of checking if a specific annotation is present. This improves code readability and maintainability. --- webhook/annotation.go | 2 +- webhook/annotation_test.go | 12 ++++++------ webhook/mutator.go | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/webhook/annotation.go b/webhook/annotation.go index 661ce0f..f2a9ad7 100644 --- a/webhook/annotation.go +++ b/webhook/annotation.go @@ -78,7 +78,7 @@ func ParseAndCheckAnnotations(input Annotations) Annotations { return output } -func (a Annotations) IsInected() bool { +func (a Annotations) IsInjected() bool { value, exist := a[AnnotationInjected] if !exist { return false diff --git a/webhook/annotation_test.go b/webhook/annotation_test.go index ddd45b9..5e8738d 100644 --- a/webhook/annotation_test.go +++ b/webhook/annotation_test.go @@ -81,15 +81,15 @@ func TestParseAnnotationSet(t *testing.T) { func TestAnnotationsIsInjected(t *testing.T) { annotations := Annotations{} - assert.False(t, annotations.IsInected()) + assert.False(t, annotations.IsInjected()) annotations = Annotations{"injected": "false"} - assert.False(t, annotations.IsInected()) + assert.False(t, annotations.IsInjected()) annotations = Annotations{"injected": "x"} - assert.False(t, annotations.IsInected()) + assert.False(t, annotations.IsInjected()) annotations = Annotations{"injected": "ture"} - assert.False(t, annotations.IsInected()) + assert.False(t, annotations.IsInjected()) annotations = Annotations{"injected": "t"} - assert.True(t, annotations.IsInected()) + assert.True(t, annotations.IsInjected()) annotations = Annotations{"injected": "true"} - assert.True(t, annotations.IsInected()) + assert.True(t, annotations.IsInjected()) } diff --git a/webhook/mutator.go b/webhook/mutator.go index 65cc84c..100ce94 100644 --- a/webhook/mutator.go +++ b/webhook/mutator.go @@ -35,7 +35,7 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis } for secretName, annotations := range annotationSet { - if annotations.IsInected() { + if annotations.IsInjected() { // return admission.Allowed("do nothing as secrets are already injected") continue } From edc088464beeb90034086b41a72407994b5e5a77 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 11:24:43 +0900 Subject: [PATCH 29/31] docs: Update minor thing on description for `decode-base64` --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3acc257..780c1bf 100644 --- a/README.md +++ b/README.md @@ -82,14 +82,14 @@ of other new charts. The following annotatins are required to inject `cloud-secrets-injector` into pods: -| **Key** | **Required** | **Description** | **Example** | -|--------------------------------------------------------|--------------|------------------------------|----------------------------------------------------------| -| `cloud-secrets-manager.h0n9.postie.chat/provider` | true | Cloud Provider Name | `aws` | -| `cloud-secrets-manager.h0n9.postie.chat/secret-id` | true | Secret Name | `very-precious-secret` | -| `cloud-secrets-manager.h0n9.postie.chat/template` | true | Template for secret value | ```{{ range $k, $v := . }}{{ $k }}={{ $v }} {{ end }}``` | -| `cloud-secrets-manager.h0n9.postie.chat/output` | true | File path for output | `/secrets/env` | -| `cloud-secrets-manager.h0n9.postie.chat/decode-base64` | false | Decode base64-encoded string | `true` or `false` | -| `cloud-secrets-manager.h0n9.postie.chat/injected` | false | Identifier for injection | `false` | +| **Key** | **Required** | **Description** | **Example** | +|--------------------------------------------------------|--------------|------------------------------------|----------------------------------------------------------| +| `cloud-secrets-manager.h0n9.postie.chat/provider` | true | Cloud Provider Name | `aws` | +| `cloud-secrets-manager.h0n9.postie.chat/secret-id` | true | Secret Name | `very-precious-secret` | +| `cloud-secrets-manager.h0n9.postie.chat/template` | true | Template for secret value | ```{{ range $k, $v := . }}{{ $k }}={{ $v }} {{ end }}``` | +| `cloud-secrets-manager.h0n9.postie.chat/output` | true | File path for output | `/secrets/env` | +| `cloud-secrets-manager.h0n9.postie.chat/decode-base64` | false | Decode base64-encoded secret value | `true` or `false` | +| `cloud-secrets-manager.h0n9.postie.chat/injected` | false | Identifier for injection | `false` | #### Annotations for Multiple Secrets Injection From 66b45cd704e57c047cbf37150a1ad033f9bc97e8 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Wed, 5 Jun 2024 11:34:09 +0900 Subject: [PATCH 30/31] docs: Add annotation for decoding base64-decoded secret value --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 780c1bf..180ef42 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,29 @@ cloud-secrets-manager.h0n9.postie.chat/template-config-secrets: | Just add `` at the end of each annotation key, like `cloud-secrets-manager.h0n9.postie.chat/provider-`. That's it! +#### Annotation for Decoding Base64-encoded Secret Value + +From the version `v0.6`, you can decode base64-encoded secret values by setting +the `cloud-secrets-manager.h0n9.postie.chat/decode-base64` annotation to `true`. + +```yaml +cloud-secrets-manager.h0n9.postie.chat/provider-cert: aws +cloud-secrets-manager.h0n9.postie.chat/secret-id-cert: very-precious-secret +cloud-secrets-manager.h0n9.postie.chat/output-cert: /secrets/precious.cer +cloud-secrets-manager.h0n9.postie.chat/template-cert: | + {{ .base64-encoded-precious-cert }} +cloud-secrets-manager.h0n9.postie.chat/decode-base64-cert: "true" +cloud-secrets-manager.h0n9.postie.chat/provider-key: aws +cloud-secrets-manager.h0n9.postie.chat/secret-id-key: very-precious-secret +cloud-secrets-manager.h0n9.postie.chat/output-key: /secrets/precious.key +cloud-secrets-manager.h0n9.postie.chat/template-key: | + {{ .base64-encoded-precious-key }} +cloud-secrets-manager.h0n9.postie.chat/decode-base64-key: "true" +``` + +This feature is useful when you want to inject a base64-encoded secret value as +a file into a pod. + ### Providers Supported providers require the annotations mentioned above in common. However, From 3052f0930a54c2a83512462bee43641c947ec259 Mon Sep 17 00:00:00 2001 From: h0n9 Date: Mon, 10 Jun 2024 08:32:39 +0900 Subject: [PATCH 31/31] chore: Update version to v0.6 in manager.go --- manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager.go b/manager.go index fa1b24b..a6678ac 100644 --- a/manager.go +++ b/manager.go @@ -2,7 +2,7 @@ package manager const ( Name = "cloud-secrets-manager" - Version = "v0.5" + Version = "v0.6" AnnotationPrefix = "cloud-secrets-manager.h0n9.postie.chat" InjectorVolumeMountPath = "/tmp/cloud-secrets-injector/secrets" )