kubernetes-sigs / kustomize

Customization of kubernetes YAML configurations
Apache License 2.0
10.7k stars 2.22k forks source link

NamespaceTransformer seems to interfere with nameReference configuration #5696

Open timothy-spencer opened 1 month ago

timothy-spencer commented 1 month ago

What happened?

I am trying to configure some kuma mesh stuff with kustomize. I need to be able to add prefixes to all the names of things, and thus, I wrote a nameReference config to make sure that the mesh name can be transformed everywhere, including a label that is set in the MeshMetric resource. That works fine.

Then I had to make it so that the MeshMetric resource would live in the kuma namespace instead of the namespace that I had set with namespace: name in kustomization.yaml. I did this by only setting the namespace in that resource, and then using the NamespaceTransformer with unsetOnly: true, and removing namespace: name from kustomization.yaml.

The namespaces now work, but somehow the nameReference does not. The label with the mesh name that is supposed to be renamed does not get renamed.

What did you expect to happen?

I expect nameReference configuration to still work when I add a NamespaceTransformer to kustomization.yaml.

In my example, I expect the kuma.io/mesh label in the MeshMetric resource to be set to foo-test instead of test.

How can we reproduce it (as minimally and precisely as possible)?

# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

#namespace: bar
namePrefix: foo-

resources:
  - resources.yaml

configurations:
  - config.yaml

transformers:
  - |-
    apiVersion: builtin
    kind: NamespaceTransformer
    metadata:
      name: notImportantHere
      namespace: bar
    unsetOnly: true
# resources.yaml
---
apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
  name: test
spec:
  stuff: true

---
apiVersion: kuma.io/v1alpha1
kind: MeshMetric
metadata:
  name: test-metrics
  namespace: kuma
  labels:
    kuma.io/mesh: test
spec:
  moreStuff: true
# config.yaml
nameReference:
- kind: Mesh
  version: v1alpha1
  fieldSpecs:
  - path: metadata/labels/kuma.io\/mesh
    kind: MeshMetric

Expected output

apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
  name: foo-test
  namespace: bar
spec:
  stuff: true
---
apiVersion: kuma.io/v1alpha1
kind: MeshMetric
metadata:
  labels:
    kuma.io/mesh: foo-test
  name: foo-test-metrics
  namespace: kuma
spec:
  moreStuff: true

Actual output

apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
  name: foo-test
  namespace: bar
spec:
  stuff: true
---
apiVersion: kuma.io/v1alpha1
kind: MeshMetric
metadata:
  labels:
    kuma.io/mesh: test
  name: foo-test-metrics
  namespace: kuma
spec:
  moreStuff: true

Kustomize version

v5.3.0

Operating system

MacOS

timothy-spencer commented 1 month ago

BTW, this also seems to happen when I try using a PatchTransformer. I tried doing this:

namespace: bar

transformers:
- |-
  apiVersion: builtin
  kind: PatchTransformer
  metadata:
    name: fix-kuma-namespace
  patch: '[{"op": "replace", "path": "/metadata/namespace", "value": "kuma"}]'
  target:
    group: kuma.io
    version: v1alpha1
    kind: MeshMetric

And if you comment out the transformer, the namespace is wrong, but the label is proper, and if you uncomment the transformer, the label is wrong, and the namespace is correct:

laptop /tmp/t% kustomize build . > output.yaml && diff correct.yaml output.yaml
15c15
<   namespace: kuma
---
>   namespace: bar
laptop /tmp/t% kustomize build . > output.yaml && diff correct.yaml output.yaml
13c13
<     kuma.io/mesh: foo-test
---
>     kuma.io/mesh: test
laptop /tmp/t% 
timothy-spencer commented 1 month ago

If I had to choose, I'd prefer the solution that uses unsetOnly, because then I can set namespaces where I need them to be in the base yaml, and just have the namespaced stuff live in it's namespace. But I thought you might be interested in knowing that just enabling a transformer of multiple types causes nameReference transforms to stop working.

stormqueen1990 commented 1 month ago

@timothy-spencer there is definitely a bug here. I can reproduce the behaviour you're seeing on latest HEAD. I could not, however, reproduce the working behaviour you described without specifying a namespace: bar field in the kustomization.yaml. Could you please clarify the scenario where no transformer configurations are set, but the backreference works as expected?

/triage accepted /lifecycle frozen

timothy-spencer commented 1 month ago

If I understand your request, my first step was to take resources.yaml and config.yaml from above, and use this kustomization.yaml:

# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: bar
namePrefix: foo-

resources:
  - resources.yaml

configurations:
  - config.yaml

This made it so that the namespace got splatted onto all resources, including the ones that I needed to live in the kuma namespace. Thus, my commentingnamespace: bar out as I showed in my original kustomization.yaml, and trying to use the transformer with unsetOnly: true to fix that. But that's when I noticed the metadata/labels/kuma.io\/mesh value reverting back to test instead of foo-test.

Does that answer your question?

stormqueen1990 commented 1 month ago

Does that answer your question?

Hi there, @timothy-spencer!

It does, yes. Thanks for clarifying. I also noticed this strange behaviour during my tests and just wanted to confirm that what I was able to reproduce was in fact the issue you reported.

timothy-spencer commented 1 month ago

Yay! Let me know if there's anything else I can do to help out with this, and thank you for helping this product become even better! :-)