aws-secret-operator
aws-secret-operator copied to clipboard
Failure to map AWS secrets not in key/value format
When an AWS secret is stored as non-JSON plaintext rather than key value pairs, the operator fails to map secret to a Kubernetes secret object.
Desired behavior would be to store the secret blob in a single key value pair in a Kubernetes secret with a key name something like "secretString"
Error message: { "level": "error", "ts": 1549493879.5115652, "logger": "kubebuilder.controller", "caller": "controller/controller.go:209", "msg": "Reconciler error", "Controller": "awssecret-controller", "Request": "default/test-secret", "error": "failed to compute secret for cr: failed to get json secret as map: invalid character 'a' looking for beginning of value", "errorVerbose": "invalid character 'a' looking for beginning of value failed to get json secret as map github.com/mumoshu/aws-secret-operator/pkg/controller/awssecret.(*ReconcileAWSSecret).newSecretForCR /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/pkg/controller/awssecret/awssecret_controller.go:154 github.com/mumoshu/aws-secret-operator/pkg/controller/awssecret.(*ReconcileAWSSecret).Reconcile /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/pkg/controller/awssecret/awssecret_controller.go:107 github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:207 github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func1 /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:157 github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1 /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133 github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:134 github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait.Until /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88 runtime.goexit /usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:1333 failed to compute secret for cr github.com/mumoshu/aws-secret-operator/pkg/controller/awssecret.(*ReconcileAWSSecret).Reconcile /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/pkg/controller/awssecret/awssecret_controller.go:109 github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:207 github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func1 /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:157 github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1 /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133 github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:134 github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait.Until /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88 runtime.goexit /usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:1333", "stacktrace": "github.com/mumoshu/aws-secret-operator/vendor/github.com/go-logr/zapr.(*zapLogger).Error /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/github.com/go-logr/zapr/zapr.go:128 github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:209 github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func1 /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:157 github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1 /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133 github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:134 github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait.Until /Users/kuoka-yusuke/go/src/github.com/mumoshu/aws-secret-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88" }
@jepperson2 can you provide values so that this issue can be reproduced?
@ghostsquad +1 Here. I simply used a JSON map and still got this one.
{"level":"error","ts":1584478355.4803984,"logger":"kubebuilder.controller","caller":"controller/controller.go:209","msg":"Reconciler error","Controller":"awssecret-controller","Request":"event/event.secrets","error":"failed to compute secret for cr: failed to get json secret as map: invalid character '}' looking for beginning of object key string","errorVerbose":"invalid character '}'
I literally compiled and deployed build 0.2.4.
Here's some sample data.
MAP - DOESN'T work
{
"item1": {
"item1a": "item1value"
},
"item2": {
"item2a": "item2value"
}
}
KEY VALUE PAIRS WORKS
{
"item1a": "item1value"
"item2a": "item2value"
}
Now when I update the version id in the secret's manifest (cruds cr file) to the FLAT Key Value pair the secret finally gets created:
{"level":"info","ts":1584480210.0409229,"logger":"controller_awssecret","caller":"awssecret/awssecret_controller.go:115","msg":"Secret does not exist, Creating a new Secret","Request.Namespace":"event","Request.Name":"event.secrets","desired.Namespace":"event","desired.Name":"event.secrets"}
{"level":"info","ts":1584480210.0504978,"logger":"controller_awssecret","caller":"awssecret/awssecret_controller.go:122","msg":"Secret Created successfully, RequeueAfter 5 minutes","Request.Namespace":"event","Request.Name":"event.secrets"}
Notice that the AWS Console's Secret manager NEITHER CAN translate Maps to Key/Value pairs and when you describe the Opaque secret that gets created by the CRDS then you see the itemized values, which include the matching version id
kubectl describe secrets event.secrets -n event
Name: event.secrets
Namespace: event
Labels: app=event.secrets
Annotations: <none>
Type: Opaque
Data
====
item1a: 15 bytes
item2a: 20 bytes
AWSVersionId: 36 bytes
Edit Conclusion: The logic then is making the same call the AWS Console is making or its equivalent to map values to the K8s secret rather than store it in a single string. This is then a FEATURE request, to capture the exception being thrown and instead of parsing the SecretString or the SecretBinary simply parse it as a blob and let us simple mortals deal with it within our own application. You don't have the change the current behavior because is super cool. Just add an exception handler for this case.
@ecout unfortunately AWS Secrets Manager has a least a small expectation that the value for the secret is a standard json map (key/value pairs), or non-json data entirely, since it's UI is setup in such a way that it can neatly present you with subkeys if the secret is a json map.
With that said, you could do something like:
{
"foo.json": "<escaped json string here>"
}
which would be easier to map down as appropriate to kubernetes.