0

I am trying to manipulate a kubernetes yaml file with python's pyyaml. I'm trying to add some annotations, but when I dump them the output is empty.

Add key,val in a Deployment:

file_content = ""
try:
    with open(filename, "r") as f:
        file_content = yaml.safe_load_all(f.read())
except:
    sys.exit(1)

for doc in file_content:
    if doc['kind'] == "Deployment":
        metadata = doc['spec']['template']['metadata']

        if 'annotations' not in metadata.keys():
            metadata['annotations'] = {}
        
        metadata['annotations']['key'] = 'val'

yaml.safe_dump_all(documents=file_content, stream=sys.stdout)

I would like to obtain:

apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  template:
    metadata:
    ...
      annotations:
        'key': 'val'

How can I do that?

Note that in the output there's should be the single quote mark '.

sctx
  • 128
  • 2
  • 11
  • Just a notice. If I remove the `for` loop, `yaml.dump` outputs the original yaml correctly. – sctx Jun 16 '22 at 10:29
  • 1
    If you want to manipulate YAML files with python, you may want to look at `ruamel.yaml` (disclaimer: I am the author). It can preserve comments in your YAML, as well as tags, anchors, merge keys, supports YAML 1.2, (where pyyaml only supports a subset of YAML 1.1). – Anthon Jun 16 '22 at 19:11

1 Answers1

1

I found a solution. It seems that modifying the iterator returned by the yaml.load function results in an empty structure, so empty results.

I copy each element in the operator in a new structure and then apply edits to it.

The following works properly

resources = []

for res in file_content:
    if res['kind'] == "Deployment":

        # manipulate res
    resources.append(res)

yaml.safe_dump_all(documents=resources, stream=sys.stdout)
sctx
  • 128
  • 2
  • 11
  • 1
    Note that you don't need that `res = item.copy()`; you can just `resources.append(item)`. – larsks Jun 16 '22 at 12:02