Home > Net >  how to add new tag value to a exiting yaml file using python
how to add new tag value to a exiting yaml file using python

Time:02-03

I want to add additional tag value to below yaml contents.

Base Yaml

infra:
  etcd:
    container:
      replica_count: 3
      resource:
        limit_memory: 1000Mi
        limit_cpu: 1000m
        requests_memory: 1000Mi
        requests_cpu: 1000m
    volume:
      storageClaim: 5Gi
      storageCapacity: 5Gi
  kafka:
    container:
      replica_count: 3
      resource:
        limit_memory: 2000Mi
        limit_cpu: 1000m
        requests_memory: 2000Mi
        requests_cpu: 1000m
    volume:
      storageClaim: 10Gi
      storageCapacity: 10Gi        
  zk:
    container:
      replica_count: 3
      resource:
        limit_memory: 500Mi
        limit_cpu: 1000m
        requests_memory: 500Mi
        requests_cpu: 1000m
    volume:
      storageClaim: 10Gi
      storageCapacity: 10Gi

After Update

infra:
  etcd:
    container:
      **image:
        tag: etcd-21.3.4**
      replica_count: 3
      resource:
        limit_memory: 1000Mi
        limit_cpu: 1000m
        requests_memory: 1000Mi
        requests_cpu: 1000m
    volume:
      storageClaim: 5Gi
      storageCapacity: 5Gi
  kafka:
    container:
      **image:
        tag: kafka-21.3.4**
      replica_count: 3
      resource:
        limit_memory: 2000Mi
        limit_cpu: 1000m
        requests_memory: 2000Mi
        requests_cpu: 1000m
    volume:
      storageClaim: 10Gi
      storageCapacity: 10Gi        
  zk:
    container:
      **image:
        tag: zk-21.3.4**
      replica_count: 3
      resource:
        limit_memory: 500Mi
        limit_cpu: 1000m
        requests_memory: 500Mi
        requests_cpu: 1000m
    volume:
      storageClaim: 10Gi
      storageCapacity: 10Gi

I am new to python and yaml handling, Any reference will help. I am able open & close the files but not able to get specific guideline to add/remove/update the new tag & value. even contents.update is removing the data after the first image tag update.

import yaml

# Read the YAML file
with open ('in.yaml', 'r') as read_file:
    contents = yaml.safe_load(read_file)
   
contents['infra']['etcd'] = 'Image' 

# Write the YAML file with sort_keys=False to retain same order
with open('in.yaml', 'w') as write_file:
    yaml.dump(contents, write_file, sort_keys=False)

CodePudding user response:

Your YAML loads into a Python datastructure, where the value for key 'etcd' is a dictionary. If you replace that dictionary by doing:

contents['infra']['etcd'] = 'Image'

you replace the value (i.e. the dictionary) with a single string and you won't get the output that you show.

To get the part between **, you need to update the value for container with a dict`:

import sys
from pathlib import Path
import ruamel.yaml

file_in = Path('input.yaml')

    
yaml = ruamel.yaml.YAML()
data = yaml.load(file_in)
for key in ['etcd', 'kafka', 'zk']:
    data['infra'][key]['container'].insert(0, 'image', dict(tag=f'{key}-21.3.4'))
yaml.dump(data, sys.stdout)

which gives:

infra:
  etcd:
    container:
      image:
        tag: etcd-21.3.4
      replica_count: 3
      resource:
        limit_memory: 1000Mi
        limit_cpu: 1000m
        requests_memory: 1000Mi
        requests_cpu: 1000m
    volume:
      storageClaim: 5Gi
      storageCapacity: 5Gi
  kafka:
    container:
      image:
        tag: kafka-21.3.4
      replica_count: 3
      resource:
        limit_memory: 2000Mi
        limit_cpu: 1000m
        requests_memory: 2000Mi
        requests_cpu: 1000m
    volume:
      storageClaim: 10Gi
      storageCapacity: 10Gi
  zk:
    container:
      image:
        tag: zk-21.3.4
      replica_count: 3
      resource:
        limit_memory: 500Mi
        limit_cpu: 1000m
        requests_memory: 500Mi
        requests_cpu: 1000m
    volume:
      storageClaim: 10Gi
      storageCapacity: 10Gi

I am using my ruamel.yaml package which is an improvement of PyYAML, supporting the newer YAML 1.2 standard (released in 2009). It also allows you to insert (i.e. update at a specific position wrt the list of keys) in the mapping/dict that you loaded from YAML (to get the key image in the first position), and will also preserves any comments, aliases, key orderinng, etc that you might have in your file. (If needed you can also preserve superfluous quotes around scalars, but you don't have any in your input)

  • Related