From 91be69a85cd6217134b4a3af395aa3eb60ae46ce Mon Sep 17 00:00:00 2001 From: Eriks Zelenka Date: Mon, 23 Nov 2020 15:24:01 +0000 Subject: [PATCH 1/3] fix: improve logging - remove logrus mixing; dont fail controller for errors, just report - keeps controller healthy, while secrets may be broken --- Makefile | 2 +- chart/helm2/sops-secrets-operator/Chart.yaml | 4 +- chart/helm2/sops-secrets-operator/values.yaml | 2 +- chart/helm3/sops-secrets-operator/Chart.yaml | 4 +- .../tests/operator_test.yaml | 6 +- chart/helm3/sops-secrets-operator/values.yaml | 2 +- controllers/sopssecret_controller.go | 75 +++++++++++++++---- 7 files changed, 69 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 05f6cc7a..52c045a7 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ SHELL := /bin/bash GO := GO15VENDOREXPERIMENT=1 GO111MODULE=on GOPROXY=https://proxy.golang.org go -SOPS_SEC_OPERATOR_VERSION := 0.1.7 +SOPS_SEC_OPERATOR_VERSION := 0.1.8 # https://github.com/kubernetes-sigs/controller-tools/releases CONTROLLER_TOOLS_VERSION := "v0.3.0" diff --git a/chart/helm2/sops-secrets-operator/Chart.yaml b/chart/helm2/sops-secrets-operator/Chart.yaml index 86cc271e..d9735f09 100644 --- a/chart/helm2/sops-secrets-operator/Chart.yaml +++ b/chart/helm2/sops-secrets-operator/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 -version: 0.5.2 -appVersion: 0.1.7 +version: 0.5.3 +appVersion: 0.1.8 description: sops secrets operator name: sops-secrets-operator sources: diff --git a/chart/helm2/sops-secrets-operator/values.yaml b/chart/helm2/sops-secrets-operator/values.yaml index a56a7ca3..32e51b0b 100644 --- a/chart/helm2/sops-secrets-operator/values.yaml +++ b/chart/helm2/sops-secrets-operator/values.yaml @@ -6,7 +6,7 @@ replicaCount: 1 # Deployment replica count - should not be modified image: repository: isindir/sops-secrets-operator # Operator image - tag: 0.1.7 # Operator image tag + tag: 0.1.8 # Operator image tag pullPolicy: Always # Operator image pull policy imagePullSecrets: [] # Secrets to pull image from private docker repository diff --git a/chart/helm3/sops-secrets-operator/Chart.yaml b/chart/helm3/sops-secrets-operator/Chart.yaml index 904c1ae7..b78b9a25 100644 --- a/chart/helm3/sops-secrets-operator/Chart.yaml +++ b/chart/helm3/sops-secrets-operator/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 -version: 0.6.2 -appVersion: 0.1.7 +version: 0.6.3 +appVersion: 0.1.8 type: application description: sops secrets operator name: sops-secrets-operator diff --git a/chart/helm3/sops-secrets-operator/tests/operator_test.yaml b/chart/helm3/sops-secrets-operator/tests/operator_test.yaml index 0611781e..897cdf36 100644 --- a/chart/helm3/sops-secrets-operator/tests/operator_test.yaml +++ b/chart/helm3/sops-secrets-operator/tests/operator_test.yaml @@ -30,8 +30,8 @@ tests: app.kubernetes.io/instance: sops app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: sops-secrets-operator - app.kubernetes.io/version: 0.1.7 - helm.sh/chart: sops-secrets-operator-0.6.2 + app.kubernetes.io/version: 0.1.8 + helm.sh/chart: sops-secrets-operator-0.6.3 # template metadata and spec selector - it: should correctly render template metadata and spec selector @@ -140,7 +140,7 @@ tests: asserts: - equal: path: spec.template.spec.containers[0].image - value: isindir/sops-secrets-operator:0.1.7 + value: isindir/sops-secrets-operator:0.1.8 - equal: path: spec.template.spec.containers[0].imagePullPolicy value: Always diff --git a/chart/helm3/sops-secrets-operator/values.yaml b/chart/helm3/sops-secrets-operator/values.yaml index a56a7ca3..32e51b0b 100644 --- a/chart/helm3/sops-secrets-operator/values.yaml +++ b/chart/helm3/sops-secrets-operator/values.yaml @@ -6,7 +6,7 @@ replicaCount: 1 # Deployment replica count - should not be modified image: repository: isindir/sops-secrets-operator # Operator image - tag: 0.1.7 # Operator image tag + tag: 0.1.8 # Operator image tag pullPolicy: Always # Operator image pull policy imagePullSecrets: [] # Secrets to pull image from private docker repository diff --git a/controllers/sopssecret_controller.go b/controllers/sopssecret_controller.go index f7bba7f0..92a46e03 100644 --- a/controllers/sopssecret_controller.go +++ b/controllers/sopssecret_controller.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" "github.com/go-logr/logr" "github.com/sirupsen/logrus" @@ -71,20 +72,14 @@ func (r *SopsSecretReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) instance, err := decryptSopsSecretInstance(instanceEncrypted, r.Log) if err != nil { - r.Log.Info( - "Decryption error", - "sopssecret", - req.NamespacedName, - "error", - err, - ) //instance.Status.SecretsTotal = len(instance.Spec.SecretsTemplate) instanceEncrypted.Status.Message = "Decryption error" // will not process instance error as we are already in error mode here r.Status().Update(context.Background(), instanceEncrypted) - return reconcile.Result{}, err + // Error conditon, but don't fail controller as it will not help, the actual error is already logged + return reconcile.Result{}, nil } // iterating over secret templates @@ -96,7 +91,14 @@ func (r *SopsSecretReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) instanceEncrypted.Status.Message = "New child secret creation error" r.Status().Update(context.Background(), instanceEncrypted) - return reconcile.Result{}, err + r.Log.Info( + "New child secret creation error", + "sopssecret", + req.NamespacedName, + "error", + err, + ) + return reconcile.Result{}, nil } // Set SopsSecret instance as the owner and controller @@ -108,7 +110,14 @@ func (r *SopsSecretReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) instanceEncrypted.Status.Message = "Setting controller ownership of the child secret error" r.Status().Update(context.Background(), instanceEncrypted) - return reconcile.Result{}, err + r.Log.Info( + "Setting controller ownership of the child secret error", + "sopssecret", + req.NamespacedName, + "error", + err, + ) + return reconcile.Result{}, nil } // Check if this Secret already exists @@ -136,18 +145,28 @@ func (r *SopsSecretReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) instanceEncrypted.Status.Message = "Unknown Error" r.Status().Update(context.Background(), instanceEncrypted) - return reconcile.Result{}, err + r.Log.Info( + "Unknown Error", + "sopssecret", + req.NamespacedName, + "error", + err, + ) + return reconcile.Result{}, nil } if !metav1.IsControlledBy(foundSecret, instance) { instanceEncrypted.Status.Message = "Child secret is not owned by controller error" r.Status().Update(context.Background(), instanceEncrypted) - return reconcile.Result{}, fmt.Errorf( - "secret/%s in %s has a conflict with reconciling request sops secret, potential reasons: target k8s secret already existed or managed secret duplicated in multiple sops secrets", - foundSecret.Name, - foundSecret.Namespace, + r.Log.Info( + "Child secret is not owned by controller or sopssecret Error", + "sopssecret", + req.NamespacedName, + "error", + fmt.Errorf("sopssecret has a conflict with existing kubernetes secret resource, potential reasons: target secret already pre-existed or is managed by multiple sops secrets"), ) + return reconcile.Result{}, nil } origSecret := foundSecret @@ -171,7 +190,14 @@ func (r *SopsSecretReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) instanceEncrypted.Status.Message = "Child secret update error" r.Status().Update(context.Background(), instanceEncrypted) - return reconcile.Result{}, err + r.Log.Info( + "Child secret update error", + "sopssecret", + req.NamespacedName, + "error", + err, + ) + return reconcile.Result{}, nil } r.Log.Info( "Secret successfully refreshed", @@ -186,14 +212,25 @@ func (r *SopsSecretReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) instanceEncrypted.Status.Message = "Healthy" r.Status().Update(context.Background(), instanceEncrypted) + r.Log.Info( + "SopsSecret is Healthy", + "sopssecret", + req.NamespacedName, + ) return ctrl.Result{}, nil } // SetupWithManager - setup with manager func (r *SopsSecretReconciler) SetupWithManager(mgr ctrl.Manager) error { + // Set logging level sopslogging.SetLevel(logrus.InfoLevel) + // Set logrus logs to be discarded + for k := range sopslogging.Loggers { + sopslogging.Loggers[k].Out = ioutil.Discard + } + return ctrl.NewControllerManagedBy(mgr). For(&isindirv1alpha2.SopsSecret{}). Owns(&corev1.Secret{}). @@ -294,6 +331,8 @@ func decryptSopsSecretInstance( if err != nil { reqLogger.Info( "Failed to convert encrypted sops secret to bytes[]", + "sopssecret", + fmt.Sprintf("%s/%s", instanceEncrypted.Namespace, instanceEncrypted.Name), "error", err, ) @@ -304,6 +343,8 @@ func decryptSopsSecretInstance( if err != nil { reqLogger.Info( "Failed to Decrypt encrypted sops secret instance", + "sopssecret", + fmt.Sprintf("%s/%s", instanceEncrypted.Namespace, instanceEncrypted.Name), "error", err, ) @@ -315,6 +356,8 @@ func decryptSopsSecretInstance( if err != nil { reqLogger.Info( "Failed to Unmarshal decrypted sops secret instance", + "sopssecret", + fmt.Sprintf("%s/%s", instanceEncrypted.Namespace, instanceEncrypted.Name), "error", err, ) From fe4fc643f5e0a25e01e652ba0f02c677745c4dcd Mon Sep 17 00:00:00 2001 From: Eriks Zelenka Date: Mon, 23 Nov 2020 15:26:37 +0000 Subject: [PATCH 2/3] Fix --- chart/helm2/sops-secrets-operator/README.md | 2 +- chart/helm3/sops-secrets-operator/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/chart/helm2/sops-secrets-operator/README.md b/chart/helm2/sops-secrets-operator/README.md index 1e8a96a2..a42b85ff 100644 --- a/chart/helm2/sops-secrets-operator/README.md +++ b/chart/helm2/sops-secrets-operator/README.md @@ -83,7 +83,7 @@ The following table lists the configurable parameters of the Sops-secrets-operat | ------------------------ | ----------------------- | -------------- | | `replicaCount` | Deployment replica count - should not be modified | `1` | | `image.repository` | Operator image | `"isindir/sops-secrets-operator"` | -| `image.tag` | Operator image tag | `"0.1.7"` | +| `image.tag` | Operator image tag | `"0.1.8"` | | `image.pullPolicy` | Operator image pull policy | `"Always"` | | `imagePullSecrets` | Secrets to pull image from private docker repository | `[]` | | `nameOverride` | Overrides auto-generated short resource name | `""` | diff --git a/chart/helm3/sops-secrets-operator/README.md b/chart/helm3/sops-secrets-operator/README.md index ef59a30f..77576c04 100644 --- a/chart/helm3/sops-secrets-operator/README.md +++ b/chart/helm3/sops-secrets-operator/README.md @@ -83,7 +83,7 @@ The following table lists the configurable parameters of the Sops-secrets-operat | ------------------------ | ----------------------- | -------------- | | `replicaCount` | Deployment replica count - should not be modified | `1` | | `image.repository` | Operator image | `"isindir/sops-secrets-operator"` | -| `image.tag` | Operator image tag | `"0.1.7"` | +| `image.tag` | Operator image tag | `"0.1.8"` | | `image.pullPolicy` | Operator image pull policy | `"Always"` | | `imagePullSecrets` | Secrets to pull image from private docker repository | `[]` | | `nameOverride` | Overrides auto-generated short resource name | `""` | From 67a9c2df633f56b01c3911e4da3e139e956ce31d Mon Sep 17 00:00:00 2001 From: Eriks Zelenka Date: Mon, 23 Nov 2020 15:27:07 +0000 Subject: [PATCH 3/3] Fix --- docs/index.yaml | 81 ++++++++++++++++++--------- docs/sops-secrets-operator-0.5.3.tgz | Bin 0 -> 5944 bytes docs/sops-secrets-operator-0.6.3.tgz | Bin 0 -> 8407 bytes 3 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 docs/sops-secrets-operator-0.5.3.tgz create mode 100644 docs/sops-secrets-operator-0.6.3.tgz diff --git a/docs/index.yaml b/docs/index.yaml index 3c3a7603..6d171fc1 100644 --- a/docs/index.yaml +++ b/docs/index.yaml @@ -1,9 +1,24 @@ apiVersion: v1 entries: sops-secrets-operator: + - apiVersion: v2 + appVersion: 0.1.8 + created: "2020-11-23T15:26:57.653425Z" + description: sops secrets operator + digest: 6348b1b1b0e8d3df3926e437b2c0f4ad63268d26e2cb54cbecbb564102e6b19c + maintainers: + - email: isindir@users.sf.net + name: isindir + name: sops-secrets-operator + sources: + - https://github.com/isindir/sops-secrets-operator.git + type: application + urls: + - https://isindir.github.io/sops-secrets-operator/sops-secrets-operator-0.6.3.tgz + version: 0.6.3 - apiVersion: v2 appVersion: 0.1.7 - created: "2020-11-21T09:15:50.393105Z" + created: "2020-11-23T15:26:57.65241Z" description: sops secrets operator digest: 710c1c9fa73a2ebf791fda4a608b5e29072d42c0b68c803c7bbeed54a582fd7f maintainers: @@ -18,7 +33,7 @@ entries: version: 0.6.2 - apiVersion: v2 appVersion: 0.1.7 - created: "2020-11-21T09:15:50.392389Z" + created: "2020-11-23T15:26:57.651088Z" description: sops secrets operator digest: f2a606c3837843241bb9d59adc02c38e1cca98753c602b9f758cc61d735ca7cd maintainers: @@ -33,7 +48,7 @@ entries: version: 0.6.1 - apiVersion: v2 appVersion: 0.1.6 - created: "2020-11-21T09:15:50.391414Z" + created: "2020-11-23T15:26:57.649968Z" description: sops secrets operator digest: a2bbf9b39ec5f5b82965037f8f245fb3122adbe31b1c7d336fa1f4cddb228b88 maintainers: @@ -46,9 +61,23 @@ entries: urls: - https://isindir.github.io/sops-secrets-operator/sops-secrets-operator-0.6.0.tgz version: 0.6.0 + - apiVersion: v1 + appVersion: 0.1.8 + created: "2020-11-23T15:26:57.648924Z" + description: sops secrets operator + digest: b89986787f33bb6ed9fb0c658431be8646302e9c1a24537c26269c62249fa071 + maintainers: + - email: isindir@users.sf.net + name: isindir + name: sops-secrets-operator + sources: + - https://github.com/isindir/sops-secrets-operator.git + urls: + - https://isindir.github.io/sops-secrets-operator/sops-secrets-operator-0.5.3.tgz + version: 0.5.3 - apiVersion: v1 appVersion: 0.1.7 - created: "2020-11-21T09:15:50.390292Z" + created: "2020-11-23T15:26:57.64712Z" description: sops secrets operator digest: 9467709cf6fbe8d9d779cedf15fe388af172b609f3ca452ef3d8894f39d999df maintainers: @@ -62,7 +91,7 @@ entries: version: 0.5.2 - apiVersion: v1 appVersion: 0.1.7 - created: "2020-11-21T09:15:50.388687Z" + created: "2020-11-23T15:26:57.645987Z" description: sops secrets operator digest: b54b5d8497564ddc04bd6d8b105eb0a3559e82ae1f6aab2f59ed3e426f119287 maintainers: @@ -76,7 +105,7 @@ entries: version: 0.5.1 - apiVersion: v1 appVersion: 0.1.6 - created: "2020-11-21T09:15:50.387584Z" + created: "2020-11-23T15:26:57.644768Z" description: sops secrets operator digest: 177f1ed214d6e72eda589a6ab155a417c1a4229bfda11e87f24af125a3542ad1 maintainers: @@ -90,7 +119,7 @@ entries: version: 0.5.0 - apiVersion: v2 appVersion: 0.1.5 - created: "2020-11-21T09:15:50.386088Z" + created: "2020-11-23T15:26:57.643127Z" description: sops secrets operator digest: 1535e130357afa883db0b3d30735c817d3b7d412fe5bdfd71534d0c08defa7d1 maintainers: @@ -105,7 +134,7 @@ entries: version: 0.4.8 - apiVersion: v2 appVersion: 0.1.5 - created: "2020-11-21T09:15:50.384808Z" + created: "2020-11-23T15:26:57.642095Z" description: sops secrets operator digest: 19b11dc2d1945f3c436a7d03763b4391d4a382fc13ea515d25422827d859d6d0 maintainers: @@ -120,7 +149,7 @@ entries: version: 0.4.7 - apiVersion: v2 appVersion: 0.1.5 - created: "2020-11-21T09:15:50.383538Z" + created: "2020-11-23T15:26:57.641179Z" description: sops secrets operator digest: c839e5d3374b948d27ad49643411f4891fdec44d179dea06423bb0d6e29d5e32 maintainers: @@ -135,7 +164,7 @@ entries: version: 0.4.6 - apiVersion: v2 appVersion: 0.1.4 - created: "2020-11-21T09:15:50.382516Z" + created: "2020-11-23T15:26:57.64008Z" description: sops secrets operator digest: c71f9f66be32f8b9d3c8d780b09b2455a40fd9755314004efd2bb8d379dafe3c maintainers: @@ -150,7 +179,7 @@ entries: version: 0.4.5 - apiVersion: v2 appVersion: 0.1.3 - created: "2020-11-21T09:15:50.381713Z" + created: "2020-11-23T15:26:57.638901Z" description: sops secrets operator digest: f3f2f89d4ef6018776df0a12a63dd2f9c9519b9d1ac03a9a405e31d0fd902ba0 maintainers: @@ -165,7 +194,7 @@ entries: version: 0.4.4 - apiVersion: v2 appVersion: 0.1.2 - created: "2020-11-21T09:15:50.38098Z" + created: "2020-11-23T15:26:57.638113Z" description: sops secrets operator digest: 1fd5eed318627f5ed0656f4e8ce4a25729568a1626ae313bcbe21050f5f26240 maintainers: @@ -180,7 +209,7 @@ entries: version: 0.4.3 - apiVersion: v2 appVersion: 0.1.2 - created: "2020-11-21T09:15:50.380232Z" + created: "2020-11-23T15:26:57.637266Z" description: sops secrets operator digest: 1f4f9869c75f0922e83ba5d530e101bd4252d5c1c31365800cc9d1425680cf18 maintainers: @@ -195,7 +224,7 @@ entries: version: 0.4.2 - apiVersion: v2 appVersion: 0.1.1 - created: "2020-11-21T09:15:50.379293Z" + created: "2020-11-23T15:26:57.636457Z" description: sops secrets operator digest: 6b054a4e9f261eea3cb84ee2e70b87b24780f1703e2c218ea5f69b7f82d1876f maintainers: @@ -210,7 +239,7 @@ entries: version: 0.4.1 - apiVersion: v2 appVersion: 0.1.0 - created: "2020-11-21T09:15:50.378455Z" + created: "2020-11-23T15:26:57.63546Z" description: sops secrets operator digest: 78b62ab37eac1b45f0a68a9752a3615c5d3f1c960bb4057e665923ce104931cf maintainers: @@ -225,7 +254,7 @@ entries: version: 0.4.0 - apiVersion: v1 appVersion: 0.1.5 - created: "2020-11-21T09:15:50.377195Z" + created: "2020-11-23T15:26:57.633746Z" description: sops secrets operator digest: 41baa3c580cb9d8951c18513a4f04c4dbbfad99de9c62f53de2450c0c7b76725 maintainers: @@ -239,7 +268,7 @@ entries: version: 0.3.7 - apiVersion: v1 appVersion: 0.1.5 - created: "2020-11-21T09:15:50.376043Z" + created: "2020-11-23T15:26:57.632611Z" description: sops secrets operator digest: 1103b1f7bf7af3f400c172227cd5a3659f3a03e5e8158b19ba0b25f7ed45208b maintainers: @@ -253,7 +282,7 @@ entries: version: 0.3.6 - apiVersion: v1 appVersion: 0.1.5 - created: "2020-11-21T09:15:50.375255Z" + created: "2020-11-23T15:26:57.631653Z" description: sops secrets operator digest: 15c72ba7fb09d0e980ec32fd94f56893c439c05c435281a9ab9c8bc94bd20063 maintainers: @@ -267,7 +296,7 @@ entries: version: 0.3.5 - apiVersion: v1 appVersion: 0.1.4 - created: "2020-11-21T09:15:50.374425Z" + created: "2020-11-23T15:26:57.630552Z" description: sops secrets operator digest: 025a6a6381b75286756ef55105ace6e911e5a5818b495ede6356cc8ec572aeac maintainers: @@ -281,7 +310,7 @@ entries: version: 0.3.4 - apiVersion: v1 appVersion: 0.1.3 - created: "2020-11-21T09:15:50.372362Z" + created: "2020-11-23T15:26:57.629265Z" description: sops secrets operator digest: f61b070b640169439cf4ab500047c1e356748a85871f7aeefde46d63d87d453a maintainers: @@ -295,7 +324,7 @@ entries: version: 0.3.3 - apiVersion: v1 appVersion: 0.1.2 - created: "2020-11-21T09:15:50.371153Z" + created: "2020-11-23T15:26:57.62588Z" description: sops secrets operator digest: 2b37dc4e545e8a9540f6b7693079b98bf161ec5a68899defcfc9420bdcbb33e3 maintainers: @@ -309,7 +338,7 @@ entries: version: 0.3.2 - apiVersion: v1 appVersion: 0.1.1 - created: "2020-11-21T09:15:50.369261Z" + created: "2020-11-23T15:26:57.624623Z" description: sops secrets operator digest: 2e2762b8f9d66aab0caacde225955fec8bfd5a4cc10dc6943a1de3809dda4091 maintainers: @@ -323,7 +352,7 @@ entries: version: 0.3.1 - apiVersion: v1 appVersion: 0.1.0 - created: "2020-11-21T09:15:50.367814Z" + created: "2020-11-23T15:26:57.623348Z" description: sops secrets operator digest: ce84f5b64402a582c7689cb842ba03fb10f968c38b57dc9e05f588493128019a maintainers: @@ -337,7 +366,7 @@ entries: version: 0.3.0 - apiVersion: v2 appVersion: 0.0.10 - created: "2020-11-21T09:15:50.366107Z" + created: "2020-11-23T15:26:57.621598Z" description: sops secrets operator digest: 5e4c8bc37ea2c819c55b288c0a5e76ff8c9c02be591bd53776606666af45581c maintainers: @@ -352,7 +381,7 @@ entries: version: 0.2.1 - apiVersion: v1 appVersion: 0.0.10 - created: "2020-11-21T09:15:50.365105Z" + created: "2020-11-23T15:26:57.62064Z" description: sops secrets operator digest: 50b8ebab19008dfc43de1eaee8b0f6287f7a55134585dc6ae88df2520d779f8f maintainers: @@ -364,4 +393,4 @@ entries: urls: - https://isindir.github.io/sops-secrets-operator/sops-secrets-operator-0.1.10.tgz version: 0.1.10 -generated: "2020-11-21T09:15:50.363778Z" +generated: "2020-11-23T15:26:57.619333Z" diff --git a/docs/sops-secrets-operator-0.5.3.tgz b/docs/sops-secrets-operator-0.5.3.tgz new file mode 100644 index 0000000000000000000000000000000000000000..114471a3b38139fd3c472f0872800e18ee086a9d GIT binary patch literal 5944 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⪙!uh+Y+qRxdUliE!y!}LCPW53=GT*U33T2jAW@%)7 zxrx>*zb~bKnqtgmwWvKrRR2@*W*4Eh*fC(U4L<%3+uIi;+uk0+zwB?MxCO48 zzCKn=@t0?nFI%4H`@VO1SY6ga8KaHo@bNV#F_O4k>`u&$K&{Q?6zd&M!nT6TKgXHw a)Ae*cT~F6K*Z&3p0RR8>9l&7#b^ripAgLYz literal 0 HcmV?d00001 diff --git a/docs/sops-secrets-operator-0.6.3.tgz b/docs/sops-secrets-operator-0.6.3.tgz new file mode 100644 index 0000000000000000000000000000000000000000..3308207da81334da1369a0cf82c670ab2ad88bc3 GIT binary patch literal 8407 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