Skip to content

Instantly share code, notes, and snippets.

@jordiclariana
Created August 2, 2018 12:44
Show Gist options
  • Save jordiclariana/d0fd23bacc92f9640cf84387ca5d4dcd to your computer and use it in GitHub Desktop.
Save jordiclariana/d0fd23bacc92f9640cf84387ca5d4dcd to your computer and use it in GitHub Desktop.
Turn full ansible-vault encrypted yaml to a regular yaml with per variable encrypted
#!/usr/bin/python2.7
from ansible.parsing import vault
from ansible.errors import AnsibleError
from ansible.constants import DEFAULT_VAULT_ID_MATCH
import ruamel.yaml as yaml
import re
import sys
import os
SECRETSFILE = sys.argv[1]
# Get Vault password and create ansible.vault object
PASS_FILE = os.path.expanduser("~/.vault_pass.txt")
with open(PASS_FILE, 'r') as vault_pass_file:
VAULTPASS = vault_pass_file.readline().strip()
v = vault.VaultLib([(DEFAULT_VAULT_ID_MATCH, vault.VaultSecret(VAULTPASS))])
# Read the yaml file all encrypted
with open(SECRETSFILE, 'r') as secret_file:
secret_file_content = secret_file.read()
# Useful colors for the output
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
# Go through all yaml elements and encrypt when necessary
def modify_all_simple_dict_values(data, modfn):
if isinstance(data, dict):
for k, v in data.iteritems():
if (isinstance(v, dict) or
isinstance(v, list) or
isinstance(v, tuple)):
modify_all_simple_dict_values(v, modfn)
else:
data[k] = modfn(k, v)
elif isinstance(data, list) or isinstance(data, tuple):
for item in data:
modify_all_simple_dict_values(item, modfn)
return data
# Propmt to either encrypt or not yaml value and do so
def modfn(key, value):
t = raw_input("Encrypt {bold}'{key}'{endc} with value {header}'{value}'{endc}? (y/N) ".format(
key=key, value=value, header=bcolors.HEADER, bold=bcolors.BOLD, endc=bcolors.ENDC))
if t.lower() == "y":
try:
value = yaml.scalarstring.PreservedScalarString("{}".format(
v.encrypt(value.strip())))
print " {}ENCRYPTED{}".format(bcolors.OKGREEN, bcolors.ENDC)
except AnsibleError:
print " {}ERROR ENCRYPTING{}".format(bcolors.FAIL, bcolors.ENDC)
else:
print " {}NOT ENCRYPTED{}".format(bcolors.WARNING, bcolors.ENDC)
return value
# Decrypt yaml file and parse it
myyaml = yaml.round_trip_load(
v.decrypt(secret_file_content),
preserve_quotes=True)
# Dump yaml object to string
DD = yaml.round_trip_dump(
modify_all_simple_dict_values(myyaml, modfn),
explicit_start=False,
block_seq_indent=2)
# Prepend '!vault |' to all new encrypted values
prevline = ""
DD2 = ""
for line in DD.split('\n'):
if prevline != "":
if re.search(r"^ *\$ANSIBLE_VAULT", line):
prevline = re.sub(r'\|', '!vault |', prevline)
DD2 = DD2 + "\n" + prevline
prevline = line
# Save new yaml file (appending .pef to preserve original one)
with open("{}.pef".format(SECRETSFILE), "w") as plain_encrypted_file:
plain_encrypted_file.write(DD2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment