1

I have a yaml file with an arbitrary amount of documents, and I'm trying to replace all missing namespaces for namespaceable resources with an arbitrary input one.

Getting the non-namespaceable resources is easy:

kubectl api-resources --namespaced=false --no-headers | awk '{print $NF}' > /tmp/bad_resources.yaml 

The problem is using this list in YQ (mike farah's).

This code works for hardcoded resources:

 NAMESPACE="$NAMESPACE" yq ' select(.kind != "Namespace" and .kind != "CustomResourceDefinition") | .metadata.namespace = (.metadata.namespace // strenv(NAMESPACE)) ' "$INPUT" > "$OUTPUT" 

How can I replace this hardcoded list with the list I generated via kubectl?

I'm kind of going crazy with this, even LLMs utterly fail at this and keep mistaking yq versions and suggesting input arguments that don't exist.

Sample yaml:

 --- kind: Namespace metadata: name: test --- kind: ConfigMap metadata: name: test1 namespace: asd --- kind: ConfigMap metadata: name: test2 

In this example, it should be able to add the namespace to the Configmap test2, but not change test1, nor add it to Namespace, because Namespace is not a namespaceable resource. The output should be the same, except for the added namespace, so the last resource should have a new metadata.namespace field with the input namespace.

The kubectl list of resources looks like this:

Namespace Node PersistentVolume 

Given that I'm generating it with the command I posted above, I can manipulate this, so it could also be a yaml array.

2
  • Please provide a sample YAML file and your expected output. Commented Nov 10 at 9:46
  • @pmf done, added an example Commented Nov 10 at 9:57

1 Answer 1

2

Use load_str to load a text file, / to split by lines, and all_c to check against all items:

NAMESPACE="nsp" goyq ' (load_str("list.txt") / "\n") as $list | select(.kind as $kind | $list | all_c(. != $kind)) .metadata.namespace |= . // strenv(NAMESPACE) ' sample.yaml 
--- kind: Namespace metadata: name: test --- kind: ConfigMap metadata: name: test1 namespace: asd --- kind: ConfigMap metadata: name: test2 namespace: nsp 

using mikefarah/yq v4.32+

(Replacing / "\n" with | split("\n") will make it work with v4.18+)

Sign up to request clarification or add additional context in comments.

7 Comments

You must've missed this part of the question: "how can I replace this hardcoded list with the list I generated via kubectl?"
Then please provide samples (like that "list generated via kubectl") that enables me to reproduce your issue.
I added an example output of the kubectl command to the OP.
Thank you. Now, how do the items Namespace, Node, PersistentVolume come into play with your sample? Please connect all the dots.
those items are a list of kinds that should not have their namespace altered by the script. They need to replace the hardcoded list in select(.kind != "Namespace" and .kind != "CustomResourceDefinition"). I don't know them in advance, because they vary from cluster to cluster.
Now this makes it clear (with select(.kind != "Namespace" and .kind != "CustomResourceDefinition") in your sample, I would've expected a list containing Namespace and CustomResourceDefinition, not Namespace, Node, and PersistentVolume)
It's just an example. CustomResourceDefinition could be there or it could not. The point is that it's a list that I don't know in advance, so I can't hardcode them in the script.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.