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

api group missing from label transformer config for core resources #3414

Closed
snuggie12 opened this issue Jan 1, 2021 · 15 comments
Closed

api group missing from label transformer config for core resources #3414

snuggie12 opened this issue Jan 1, 2021 · 15 comments

Comments

@snuggie12
Copy link

snuggie12 commented Jan 1, 2021

Describe the bug
If you use the commonLabels transformer and a CRD shares the same kind and version, but not the same group the labels are still applied and a given path might not exist.

The big offender is knative. It too uses Service for kind and conflicts with the core resource of the same name since it does not have spec/selector.

Is it possible to add the group here?? I'm not sure if that would be "core" or an empty string (or if the code needs modified to handle an empty string?)

Files that can reproduce the issue

# hello.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: hello-world
  namespace: default
spec:
  template:
    spec:
      containers:
        - image: docker.io/hello-world
# kustomization.yaml
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

commonLabels:
  foo: bar

resources:
  - hello.yaml

Expected output

Actual output

Kustomize version
v3.8.4 but master doesn't have the group specified and I looked in the release notes so I presume it's still not working.

Platform
MacOS and Linux

Additional context

@Shell32-Natsu
Copy link
Contributor

group being omitted is the same with using empty string. core group is also possible to be omitted in the input resources. Use LabelTransformer to specify your own field specs.

@seh
Copy link
Contributor

seh commented Jan 5, 2021

I think @snuggie12 wanted to prevent these labels from being applied to Knative's Service objects. How would LabelTransformer help with that?

@Shell32-Natsu
Copy link
Contributor

He can explicitly specify group in the field specs.

@seh
Copy link
Contributor

seh commented Jan 5, 2021

Would he have to duplicate all the field specs known to the default LabelTransformer, but with the group populated as "core?"

@Shell32-Natsu
Copy link
Contributor

Unfortunately yes. The problem is the zero value of the group (empty string "") is used to match any group. kustomize doesn't have a mechanism to exclude resources from transformation.

@seh
Copy link
Contributor

seh commented Jan 5, 2021

I was struggling with that lack today, when wishing for negative assertions in Go's regular expression package. For the "target" field in a "patches" entry, I wanted to visit all resources of a particular kind except those whose name matches a certain pattern. I can't express that, so instead I have to try to craft a regular expression that matches all the other names except those I want to omit.

I recognize that using label and annotation selectors would be a better way, but it so happens that the target objects in question are neither labeled nor annotated with anything helpful as of now.

@snuggie12
Copy link
Author

@Shell32-Natsu do you mind elaborating on your solution? If I specify "core" or "" (it's not clear which your suggesting) it will merge with what is in code?

Also, if adding something like "core" fixes this then why close? Why not specify the core resources more explicitly?

I guess if you could provide exact yaml that'd be great.

@snuggie12
Copy link
Author

@Shell32-Natsu Can you let me know if I did this correct? This did not work with various combinations and tried multiple versions of kustomize including latest with kyaml enabled and disabled. It does confirm that merging occurs with builtinpluginconsts as when I try core neither svc nor ksvc match a group called core and neither get the selector.

kustomization.yaml

---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

commonLabels:
  foo: bar

configurations:
  - common-labels-fields.kcfg.yaml

resources:
  - ksvc.yaml
  - svc.yaml

common-labels-fields.kcfg.yaml

---
commonLabels:
  - path: spec/selector
    kind: Service
    version: v1
    create: true
#   group: serving.knative.dev # This plus create: false means neither get selector
#   group: core                # neither gets a selector
#   group: null                # both get selector
#   group: ''                  # both get selector similar to null
#   group: ""                  # both get selector similar to null
#   group: ~                   # both get selector similar to null
#
#
### Also tried creating serving.knative.dev with false and a second one for core.
### I think pretty much any time you see "both get selector" above will produce an error saying "conflicting fieldspecs"
#  - path: spec/selector
#    group: ''
#    kind: Service
#    version: v1
#    create: true

ksvc.yaml (the knative service)

---
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: argocd-bot-kn
spec:
  template:
    spec:
      containers:
        - name: argocd-bot
          envFrom:
            - configMapRef:
                name: argocd-bot-config
            - secretRef:
                name: argocd-bot-config
          image: app:latest

svc.yaml (regular k8s Service)

---
apiVersion: v1
kind: Service
metadata:
  name: foo-svc
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP

@snuggie12
Copy link
Author

Best I can tell core will not work unless you modify this line to say group = "core" and modify all the builtins to say group: core:

@Shell32-Natsu
Copy link
Contributor

This is a correct way. BTW, you can also use LabelTransformer as an external plugin with full control of the fieldSpecs. fieldSpecs in the configurations file will be merged with builtin configs while an external plugin config will not.

@snuggie12
Copy link
Author

@Shell32-Natsu Can both be used at once? If I call LabelTransformer with my special config and commonLabels will commonLabels still try to apply to the knative service?

@Shell32-Natsu
Copy link
Contributor

@snuggie12 Good question. I suppose they can be used at once but I haven't confirmed it in practice.

@a5r0n
Copy link

a5r0n commented Jul 13, 2021

i cant use kustomize with knative..

In the meantime I guess this behavior should be noted in the documentation here?

@dan-j
Copy link

dan-j commented Oct 11, 2021

Best I can tell core will not work unless you modify this line to say group = "core" and modify all the builtins to say group: core:

I'd say this is something worth considering, knative is a hugely popular framework and this bug is stopping everyone from using kustomize.

Any thoughts on reopening?

@mukundjalan
Copy link

To get rid of this issue in knative, I added following patch between my overlays and base.

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
  - ../base

# This patch is required to remove the label selectors generated by kustomize for core
# "Service" object which are not supported by the knative "Service" object specification.
# More info available here: https://github.com/kubernetes-sigs/kustomize/issues/3414
patches:
  - patch: |-
      - op: remove
        path: /spec/selector
    target:
      group: serving.knative.dev
      version: v1
      kind: Service

The above file/directory references "base" directory as base and is referenced in my overlays as base, creating a 3-level kustomize chain. This works because the knative service objects in base are applied the label transformer first and then fed to child which removes the spec.selector field from them and then pass it to overlays. Kind of hacky but works well. The same patch can be added in overlay's kustomize files but I added a new level to avoid repetition of same patch in each overlay.

P.S.: In my case the Service objects are all created in base and hence this works. If your service object is created in overlay, you might have to create a layer beneath overlays as putting the patch in same level as that of service object does not work because the LabelTransformer is applied after the PatchTransformer causing the patch to fail altogether.

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

6 participants