-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bdef451
commit 8282d88
Showing
4 changed files
with
165 additions
and
0 deletions.
There are no files selected for viewing
95 changes: 95 additions & 0 deletions
95
2020_07_15_51st/lightningtalks/yaml-parsing/example-cli.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" YAML one value editor CLI example | ||
author: Billy Duong | ||
Feel free to use/modify/edit this code. | ||
""" | ||
|
||
import sys, subprocess, uuid, argparse | ||
from ruamel.yaml import YAML | ||
|
||
|
||
# constants | ||
ACTION_READ = 'READ' | ||
ACTION_DELETE = 'DELETE' | ||
ACTION_UPDATE = 'UPDATE' | ||
ACTION_CHOICES = [ACTION_READ, ACTION_UPDATE, ACTION_DELETE] | ||
|
||
|
||
# setup argument parser | ||
parser = argparse.ArgumentParser(description='edit values of a yaml file') | ||
|
||
parser.add_argument('action', choices=ACTION_CHOICES, help='action executed (READ = output value | UPDATE = update value | DELETE = delete key)') | ||
parser.add_argument('target_file', help='target file') | ||
parser.add_argument('key', help='key') | ||
|
||
parser.add_argument('-nv', '--new-value', help='new value') | ||
parser.add_argument('-iw', '--inplace-write', action='store_true', help='writes directly to the file (default is stdout)') | ||
parser.add_argument('-v', '--verbose', action='store_true', help='additional information') | ||
|
||
|
||
def patch(yamlobj): | ||
'''patch yaml object functionality''' | ||
|
||
def get_key(key): | ||
data = yamlobj | ||
for v in key.split('.'): | ||
data = data[v] | ||
return data | ||
|
||
def write_key(key, data): | ||
target = yamlobj | ||
for v in key.split('.')[:-1]: | ||
target = target[v] | ||
lastkey = key.split('.')[-1] | ||
target[lastkey] = data | ||
|
||
def delete_key(key): | ||
target = yamlobj | ||
for v in key.split('.')[:-1]: | ||
target = target[v] | ||
lastkey = key.split('.')[-1] | ||
del target[lastkey] | ||
|
||
yamlobj.get_key = get_key | ||
yamlobj.write_key = write_key | ||
yamlobj.delete_key = delete_key | ||
|
||
|
||
if __name__ == '__main__': | ||
# parse arguments | ||
args = parser.parse_args() | ||
filepath = args.target_file | ||
key = args.key | ||
value = args.new_value | ||
action = args.action | ||
inplace_write = args.inplace_write | ||
VERBOSE = args.verbose | ||
|
||
# parse | ||
yaml = YAML() # uses roundtrip parser (keeps comments and order) | ||
result = yaml.load(open(filepath)) | ||
patch(result) # add functions to object | ||
|
||
# action update/delete/read | ||
if action == ACTION_UPDATE: | ||
if VERBOSE: | ||
print(f'INFO: Modifying {key} in {filepath}, setting "{value}"\n') | ||
result.write_key(key, value) | ||
elif action == ACTION_DELETE: | ||
if VERBOSE: | ||
print(f'INFO: Deleting {key} from {filepath}\n') | ||
result.delete_key(key) | ||
elif action == ACTION_READ: | ||
if VERBOSE: | ||
print(f'INFO: Reading {key} from {filepath}') | ||
print(result.get_key(key)) | ||
sys.exit(0) | ||
|
||
# output | ||
if inplace_write: | ||
yaml.dump(result, open(filepath, 'w')) | ||
else: | ||
print('OUTPUT:') | ||
yaml.dump(result, sys.stdout) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#!/usr/bin/env python3 | ||
import sys | ||
from ruamel.yaml import YAML | ||
|
||
# for more see: https://yaml.readthedocs.io/en/latest/ | ||
|
||
# read | ||
yaml = YAML() # uses roundtrip (keeps comments and order) | ||
# yaml = YAML(typ='safe') # alternative, does not keep comments and order | ||
result = yaml.load(open('[path_to_your_file]')) | ||
|
||
# modify | ||
print(result['db']['password']) # read value | ||
result['db']['password'] = 'MY_NEW_SECRET' # create/update value | ||
del result['deprecated']['key'] # delete key | ||
|
||
# output | ||
yaml.dump(result, sys.stdout) # write to stdout | ||
yaml.dump(result, open('[path_to_your_file]', 'w')) # write to file inplace |
13 changes: 13 additions & 0 deletions
13
2020_07_15_51st/lightningtalks/yaml-parsing/examples/example-test.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# MY ANSIBLE VAULT SECRET FILE | ||
|
||
# mysql credentials | ||
db: | ||
user: TEST_USER | ||
password: KEEP_THIS_SECRET | ||
|
||
# access to rest api | ||
rest_api: | ||
access_token: PLACE_TOKEN_HERE | ||
|
||
deprectated: | ||
key: REMOVE_THIS |
38 changes: 38 additions & 0 deletions
38
2020_07_15_51st/lightningtalks/yaml-parsing/presentation.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Automating YAML parsing / editing | ||
whoami: Billy Duong | ||
|
||
|
||
## Why? | ||
Why automate? | ||
|
||
- YAML is not machine parser friendly (e.g. regex) | ||
- I needed to manage multiple files 'semi-regularly' | ||
- Ex. ansible vault file, docker files, kubernetes, ... | ||
|
||
|
||
## What? | ||
What do I need? | ||
|
||
- Required: Read, edit, delete values | ||
- Required: Keep file structure!! | ||
- Required: Keep comments in file!! | ||
- Required: Additional scripting | ||
- Optional: Edit values based on keys (my.long.key) | ||
|
||
|
||
## How? | ||
How did I solve it? | ||
|
||
- Python 3 (personal preference) | ||
- ruamel.yaml (based on PyYAML) | ||
|
||
|
||
## Sources | ||
More information: | ||
- https://yaml.readthedocs.io/en/latest/ | ||
- https://yaml.org/ | ||
- https://en.wikipedia.org/wiki/YAML | ||
|
||
YAML usage examples: | ||
- https://docs.ansible.com/ansible/latest/user_guide/vault.html | ||
- https://docs.docker.com/compose/ |