mortar
mortar copied to clipboard
Unable to add/remove Secret stringData
This may just be a longer way of asking for #92.
Using mortar 0.3.3, starting with a simple deployment with a Secret
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: patchtest
namespace: default
labels:
app: patchtest
spec:
selector:
matchLabels:
app: patchtest
replicas: 1
template:
metadata:
labels:
app: patchtest
spec:
containers:
- name: foo
image: busybox
command:
- cat
tty: true
---
apiVersion: v1
kind: Secret
metadata:
name: patchtest
namespace: default
type: Opaque
stringData:
foo: foo
mortar fire . patchtest
works. Now add another entry to the stringData
map:
stringData:
foo: foo
bar: bar
/__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/k8s-client-0.8.3/lib/k8s/transport.rb:219:in `parse_response': PATCH /api/v1/namespaces/default/secrets/patchtest => HTTP 500 Internal Server Error: jsonpatch add operation does not apply: doc is missing path: /stringData/bar (K8s::Error::InternalError)
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/k8s-client-0.8.3/lib/k8s/transport.rb:242:in `request'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/k8s-client-0.8.3/lib/k8s/resource_client.rb:293:in `json_patch'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/k8s-client-0.8.3/lib/k8s/client.rb:263:in `patch_resource'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/k8s-client-0.8.3/lib/k8s/stack.rb:108:in `block in apply'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/k8s-client-0.8.3/lib/k8s/stack.rb:100:in `map'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/k8s-client-0.8.3/lib/k8s/stack.rb:100:in `apply'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/kontena-mortar-0.3.3/lib/mortar/fire_command.rb:64:in `execute'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/clamp-1.3.0/lib/clamp/command.rb:66:in `run'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/clamp-1.3.0/lib/clamp/subcommand/execution.rb:18:in `execute'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/clamp-1.3.0/lib/clamp/command.rb:66:in `run'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/clamp-1.3.0/lib/clamp/command.rb:140:in `run'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/kontena-mortar-0.3.3/bin/mortar:13:in `<top (required)>'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/bin/mortar:23:in `load'
from /__enclose_io_memfs__/lib/ruby/gems/2.4.0/bin/mortar:23:in `<main>'
Removing a secret that does exist fails similarly:
/__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/k8s-client-0.8.3/lib/k8s/transport.rb:219:in `parse_response': PATCH /api/v1/namespaces/default/secrets/patchtest => HTTP 500 Internal Server Error: jsonpatch remove operation does not apply: doc is missing path: /stringData/foo (K8s::Error::InternalError)
The workaround is to do something like mortar fire --output . patchtest | kubectl apply -f -
, which I think will work fine when no new objects have been added... if there are new ones, they won't get the annotations for the shot, though. To ensure the annotations are in place, run mortar fire . patchtest
immediately afterward.
The workaround is to do something like mortar fire --output . patchtest | kubectl apply -f -, which I think will work fine when no new objects have been added... if there are new ones, they won't get the annotations for the shot, though. To ensure the annotations are in place, run mortar fire . patchtest immediately afterward.
It might be nice if the output from mortar fire --output
could optionally include its annotations and labels so that the pipe to kubectl
could be one step.
Hmm, interesting. Looking from the kube API side secrets are actually patchable:
$ kubectl api-resources --verbs patch | grep secrets
secrets true Secret
The problem is that
stringData:
foo: foo
is never stored on the API as such. What gets stored is only the binary (base64 encoded) data
key.
As a workaround I think you should be able to get this to work if you first fire with
data:
foo: Zm9vCg== # foo in base64
and then later on fire again with
data:
foo: Zm9vCg== # foo in base64
bar: YmFyCg== # bar in base64
Confirmed to work as expected:
apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: default
data:
foo: Zm9vCg==
type: Opaque
$ mortar fire secrets-test/ secrets
shot 'secrets' successfully!
Add another secret key:
apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: default
data:
foo: Zm9vCg==
bar: YmFyCg==
type: Opaque
$ mortar fire secrets-test/ secrets
shot 'secrets' successfully!
$ kubectl describe secrets test-secret
Name: test-secret
Namespace: default
Labels: mortar.kontena.io/shot=secrets
Annotations: mortar.kontena.io/shot-checksum: db2ef5015bfb04228749e5a42bee2495
Type: Opaque
Data
====
bar: 4 bytes
foo: 4 bytes
Thanks, I can definitely work with encoding the secrets before having them consumed by mortar and using data
. Though the full stringData
support would be nice to have.
Though the full stringData support would be nice to have.
That would mean that Mortar, actually the underlying k8s-client gem, would need to understand the specifics of given resource kind. I.e. have typed resources.
Currently much of the power, generic mortar shots (a.k.a. k8s-client stacks), easy way to work with CRDs etc. are possible as the resources are not typed at all on the client side. Unless we find a nice way to be able to work with either typed or untyped resources.
Having typed resources on the client side just makes the maintenance bit painfull as kube api evolves super fast :)