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

"linkerd inject --manual" changes types of label values (string becomes float64) #3983

Closed
KIVagant opened this issue Jan 28, 2020 · 19 comments
Closed

Comments

@KIVagant
Copy link
Contributor

KIVagant commented Jan 28, 2020

Bug Report

What is the issue?

After linkerd inject --manual is applied, all Deployment labels lose double quotes around label values which causes problems with unobvious types.

How can it be reproduced?

  1. Create the deployment:
# tmp-2.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: "1493e89"
    commit: "1493e89"
  name: "1493e89"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: "1493e89"
  template:
    metadata:
      labels:
        app: "1493e89"
        commit: "1493e89"
      name: "1493e89"
    spec:
      containers:
        - image: nginx
          name: "1493e89"
  1. Apply it using kubectl apply -f tmp-2.yaml and make sure it works. New pods will start, for example:
NAME                                       READY   STATUS    RESTARTS   AGE
1493e89-7946985fdc-7zx2w                   1/1     Running   0          2m31s
  1. Inject Linkerd Proxy linkerd inject --manual tmp-2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: 1493e89
    commit: 1493e89
  name: 1493e89
spec:
  replicas: 1
  selector:
    matchLabels:
      app: 1493e89
  strategy: {}
  template:
    metadata:
      annotations:
        linkerd.io/created-by: linkerd/cli edge-19.9.3 # actually, there's edge-20.1.2 on server side which behaves the same
        linkerd.io/identity-mode: default
        linkerd.io/proxy-version: edge-20.1.2
      creationTimestamp: null
      labels:
        app: 1493e89
        commit: 1493e89
        linkerd.io/control-plane-ns: linkerd
        linkerd.io/proxy-deployment: 1493e89
      name: 1493e89
    spec:
      containers:
      - image: nginx
        name: 1493e89
        resources: {}
...

As you can see here, all labels (and not only labels) lost double quotes around values. Now try to apply it:

linkerd inject --manual tmp-2.yaml | kubectl apply -f -

Logs, error output, etc

deployment "1493e89" injected

error: error when retrieving current configuration of:
...
Object: &{map["apiVersion":"apps/v1" "kind":"Deployment" ...
:map["app":%!q(float64=+1.493e+92) "commit":%!q(float64=+1.493e+92)] "name":%!q(float64=+1.493e+92)
...
from server for: "STDIN": resource name may not be empty

// or even more unclear error:

for: "./tmp-2.yaml": unrecognized type: string

Environment

  • Kubernetes Version: v1.14.9-eks-c0eccc
  • Cluster Environment: EKS
  • Host OS: Amazon Linux
  • Linkerd version: edge-20.1.2

Possible solution

Add quotes in yaml templates everywhere by default when possible.

Workaround:

Update the commit id in any way, if it is a commit id causing the problem.

@KIVagant KIVagant changed the title "linkerd inject --manual" changes types of label values "linkerd inject --manual" changes types of label values (string becomes float64) Jan 28, 2020
@grampelberg grampelberg added this to To do in Help Wanted via automation Jan 28, 2020
@ihcsim
Copy link
Contributor

ihcsim commented Jan 28, 2020

This might also be problematic for labels that has "true" / "false" values, which when stripped turn into boolean, causing deployment to fail completely (labels only takes string values.)

@adrijshikhar
Copy link

@grampelberg , i would like to work on this.
i have already setup the repo

@grampelberg
Copy link
Contributor

@adrijshikhar awesome! Go for it!

@adrijshikhar
Copy link

What does inject do basically?

@grampelberg
Copy link
Contributor

@adrijshikhar I would recommend going through the getting started tutorials and spending some time in the docs to answer that question =)

@Vineet-Sharma29
Copy link

@adrijshikhar Are you still working on this issue? If not, I would like to work on it.

@adrijshikhar
Copy link

no i am not

@saurav-malani
Copy link

@grampelberg is this assigned to anyone? If not, then please assign this to me, I would like to give this issue a try.

@grampelberg
Copy link
Contributor

@Vineet-Sharma29 are you still working on this?

@Vineet-Sharma29
Copy link

@grampelberg No

@saurav-malani
Copy link

saurav-malani commented Mar 6, 2020

@grampelberg @ihcsim According to me there is somethings wrong with the "transform" function in cli/cmd/inject.go, specifically here: https://github.com/linkerd/linkerd2/blob/master/cli/cmd/inject.go#L193-L208. i.e. when interconversion occurs from yaml to json and then back to yaml.
ie. maybe when yamltojson conversion is done then every string is under double quote (" "), so conversion method fails to keep track of it. So, doule quotes disappears when when jsonToYaml conversion is done. And, hence the values in final injected yaml files do not have double quotes.

@Pothulapati
Copy link
Contributor

As @saurav-malani mentioned, It's not straight forward from what we discussed.
but I do think its an important use-case, I can take this up and see what I can do there.

@ihcsim Do you have some ideas on how to fix this?

@ihcsim
Copy link
Contributor

ihcsim commented Mar 9, 2020

@Pothulapati @saurav-malani Can you help me to extract out that block of code into an unexported function and add some unit test to help identify which library is acting weird? Maybe something like:

func applyPatch(original, patchJSON []byte) ([]byte, error) {
	patch, err := jsonpatch.DecodePatch(patchJSON)
	if err != nil {
		return nil, err
	}

	origJSON, err := yaml.YAMLToJSON(original)
	if err != nil {
		return nil, err
	}

	injectedJSON, err := patch.Apply(original)
	if err != nil {
		return nil, err
	}

	return conf.JSONToYAML(injectedJSON)
}

There is a good example on how to set up your unit test with simple inputs in the json-patch library README. Thanks!

@saurav-malani
Copy link

saurav-malani commented Mar 9, 2020

@ihcsim I commented out this portion and returned injectedJSON instead of injectedYAML. And, the output corresponding to it is exactly same as expected i.e. integers are not under double quotes and rest under double quotes. So, I believe there is nothing wrong till L208 and probably something goes wrong afterwards, specifically here: injectedYAML, err := conf.JSONToYAML(injectedJSON).
PS: complete json output can be viewed here

@ihcsim
Copy link
Contributor

ihcsim commented Mar 11, 2020

Are you able to track down what's going on in conf.JSONToYAML(injectedJSON)? Adding some unit tests might help to flush out the bugs.

@adnxn
Copy link

adnxn commented Apr 6, 2020

@ihcsim: cant seem to repro this using example above with build from latest commit on master. i wonder if it was fixed with a dependency upgrade or something. haven't actually sifted through the PRs.

$ linkerd version
Client version: stable-2.7.0
Server version: stable-2.7.0

$ linkerd inject --manual tmp.yml | k apply -f -

deployment "1493e89" injected

error: unable to decode "STDIN": resource.metadataOnlyObject.ObjectMeta: v1.ObjectMeta.Labels: ReadString: expects " or n, but found 1, error found in #10 byte of ...|":{"app":1.493e+92,"|..., bigger context ...|,"kind":"Deployment","metadata":{"labels":{"app":1.493e+92,"commit":1.493e+92},"name":1.493e+92},"sp|...

$ linkerd inject --manual tmp.yml | grep commit

deployment "1493e89" injected

    commit: 1493e89
        commit: 1493e89
$ ./target/cli/darwin/linkerd version
Client version: git-d6460cf0
Server version: stable-2.7.0

$ ./target/cli/darwin/linkerd inject --manual tmp.yml | k apply -f -

deployment "1493e89" injected

deployment.apps/1493e89 configured

$ ./target/cli/darwin/linkerd inject --manual tmp.yml | grep commit

deployment "1493e89" injected

    commit: "1493e89"
        commit: "1493e89"

@KIVagant
Copy link
Contributor Author

KIVagant commented Jun 1, 2020

Can confirm the issue in stable-2.7.1

@Ashish-Bansal
Copy link

@adnxn You are right. I confirm that issue has been fixed due to dependency upgrade in #4221

Upstream PR - go-yaml/yaml#171

@KIVagant Latest stable release doesn't include that patch.

@kflynn
Copy link
Member

kflynn commented Oct 5, 2023

Three years on (🤦‍♂) I've confirmed that our current Linkerd doesn't do this any more. Many thanks to everyone who helped out here!!

@kflynn kflynn closed this as completed Oct 5, 2023
Help Wanted automation moved this from To do to Done Oct 5, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Help Wanted
  
Done
Development

No branches or pull requests

10 participants