Skip to content

Instantly share code, notes, and snippets.

@weshouman
Last active September 21, 2023 21:51
Show Gist options
  • Save weshouman/0f59aee1d259d178b21d8084a815e2e4 to your computer and use it in GitHub Desktop.
Save weshouman/0f59aee1d259d178b21d8084a815e2e4 to your computer and use it in GitHub Desktop.
Unentangling my yaml confusion
#!/usr/bin/python
# This script cleans up reference keys assuming they start with an underscore
import yaml
import argparse
def read_data(input_file):
# Read YAML file
with open(input_file, 'r') as f:
data = yaml.safe_load(f)
return data
def cleanup_underscore_keys(data):
# Remove keys that start with an underscore
keys_to_remove = [key for key in data if key.startswith('_')]
for key in keys_to_remove:
del data[key]
return data
def dump_yaml(data):
# Dump the dictionary to a YAML-formatted string and print
yaml_str = yaml.safe_dump(data)
return yaml_str
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Explode a YAML file.')
parser.add_argument('--in', dest='input_file', required=True,
help='the input YAML file to explode')
args = parser.parse_args()
data = read_data(args.input_file)
data = cleanup_underscore_keys(data)
data_str = dump_yaml(data)
print(data_str)

This won't work as the auth object under the clouds: key would replace the auth of the defaults, as YAML anchoring makes a shallow copy

_cloud_refs:
  _defaults: &defaults
    auth:
      auth_url: dufault_url
      username: default_user
      user_domain_name: "default_domain"
    region_name: "default_region"

clouds:
  project-one:
    <<: *defaults
    auth:
      project_id: ID_1
      project_name: "project_one"

  project-two:
    <<: *defaults
    auth:
      project_id: ID_2
      project_name: "project_two"

However, this would work, meaning we would need to anchor manually in each level

_cloud_refs:
  _defaults: &defaults
    auth: &defaults_auth
      auth_url: dufault_url
      username: default_user
      user_domain_name: "default_domain"
    region_name: "default_region"
    identity_api_version: 3

clouds:
  project-one:
    <<: *defaults
    auth:
      <<: *defaults_auth
      project_id: ID_1
      project_name: "project_one"

  project-two:
    <<: *defaults
    auth:
      <<: *defaults_auth
      project_id: ID_2
      project_name: "project_two"

To try exploding the yaml configuration for testing, we could one of the following 2 options

Exploding Anchors with yq

Use yq eval 'explode(.)' /path/to/file

Notes:

  • We need to use yq from snap version, as the one of pip does not have eval
  • The snap version of yq does not work with files in /tmp nor with file in hidden directories. So we would need the file to exist in the home directory in a non-hidden dir. Modifying the connections mentioned in snap connections yq is the responsibility of the maintainer.

Exploding Anchors with Python

Install pyyaml pip install pyyaml and run exploder.py --in /path/to/file

import yaml
import argparse

def explode_yaml(input_file):
    # Read YAML file
    with open(input_file, 'r') as f:
        data = yaml.safe_load(f)
        
    # Write back to terminal
    yaml_str = yaml.safe_dump(data)
    print(yaml_str)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Explode a YAML file.')
    parser.add_argument('--in', dest='input_file', required=True,
                        help='the input YAML file to explode')
    args = parser.parse_args()

    explode_yaml(args.input_file)

The following script

foo:
  - pleh: help
  - stuff:
      food:
      - foo: bar
  - stuff2:
    food:
    - foo: bar


foo2:
- pleh2: help
- stuff: null

foo3:
  pleh3: help
  stuff: no

gets converted to the following json

{
  "foo": [
    {
      "pleh": "help"
    },
    {
      "stuff": {
        "food": [
          {
            "foo": "bar"
          }
        ]
      }
    },
    {
      "stuff2": null,
      "food": [
        {
          "foo": "bar"
        }
      ]
    }
  ],
  "foo2": [
    {
      "pleh2": "help"
    },
    {
      "stuff": null
    }
  ],
  "foo3": {
    "pleh3": "help",
    "stuff": false
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment