Search code examples
pythonyamlpyyamlrundeck

Editing existent YAML and duplicating entries through PyYAML


I have a YAML with the following structure:

- description: 'DUMMY_JOB'
  sequence:
    commands:
      - description: Metadata
        script: ASDF
      - description: Login
        jobref:
        args: ASDF
        group: ''
        name: ASDF
        nodeStep: 'true'
      - description: Deployment
        jobref:
        args: ASDF
        group: ''
        name: ASDF
        nodeStep: 'true'
      - description: Logout
        jobref:
        group: ''
        name: ASDF
        nodeStep: 'true'
    keepgoing: false
    strategy: node-first
  uuid: 'UNIQUE_ID'

This YAML is used as a job description inside Rundeck, what I have to do is basically duplicate the commands edit the data (the olds commands) and the new ones to reflect new parameters.

I'm loading it through PyYaml with:

jobStream   = open("example.yaml", 'r')
jobMap      = yaml.safe_load(jobStream)

And accessing it with:

jobMap[0]['sequence']['commands']

Brings back the data I need. However if I simply duplicate it through a merge like:

commandsA = jobMap[0]['sequence']['commands']
commandsB = jobMap[0]['sequence']['commands']
jobMap[0]['sequence']['commands'] = commandsA + commandsB

If I try do yaml.dump(jobMap) it won't have the commands duplicated but the IDs show up:

- *id001
- *id002
- *id003
- *id004

Solution

  • The elements from the list commandsA and from commandsB are dictionaries, if you copy those you'll get multiple reference in your structure to the same items, leading to anchors (&) and aliases (*)

    The quickest way to get the YAML that you want is probably using deepcopy:

    from copy import deepcopy
    
    jobMap[0]['sequence']['commands'] = deepcopy(commandsA) + deepcopy(commandsB)