Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to add/remove Secret stringData #99

Open
oeuftete opened this issue Apr 25, 2019 · 6 comments
Open

Unable to add/remove Secret stringData #99

oeuftete opened this issue Apr 25, 2019 · 6 comments

Comments

@oeuftete
Copy link

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.

@oeuftete
Copy link
Author

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.

@jnummelin
Copy link
Contributor

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.

@jnummelin
Copy link
Contributor

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

@jnummelin
Copy link
Contributor

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

@oeuftete
Copy link
Author

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.

@jnummelin
Copy link
Contributor

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants