98 lines
3.2 KiB
Python
98 lines
3.2 KiB
Python
|
#!/usr/bin/env python3
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
import argparse
|
||
|
import configparser
|
||
|
import logging
|
||
|
import os
|
||
|
import subprocess
|
||
|
import sys
|
||
|
|
||
|
ANSIBLE_ENV_DIR = os.getenv("ANSIBLE_CONFIG")
|
||
|
ANSIBLE_DIR = "/etc/ansible"
|
||
|
CURRENT_DIR = os.getcwd()
|
||
|
HOME_DIR = os.getenv("HOME")
|
||
|
|
||
|
ANSIBLE_CONFIG_SECTION = "gopass"
|
||
|
ANSIBLE_CONFIG_KEY = "key_path"
|
||
|
|
||
|
class ShutdownHandler(logging.Handler):
|
||
|
def emit(self, record):
|
||
|
logging.shutdown()
|
||
|
sys.exit(1)
|
||
|
|
||
|
def find_ansible_config_value(section, key):
|
||
|
config = configparser.ConfigParser()
|
||
|
|
||
|
ansible_config_dirs = [CURRENT_DIR, HOME_DIR, ANSIBLE_DIR]
|
||
|
if ANSIBLE_ENV_DIR:
|
||
|
ansible_config_dirs.insert(0, ANSIBLE_ENV_DIR)
|
||
|
|
||
|
for ansible_config_dir in ansible_config_dirs:
|
||
|
ansible_config_path = os.path.join(ansible_config_dir, "ansible.cfg")
|
||
|
config.read(ansible_config_path)
|
||
|
|
||
|
try:
|
||
|
return config[section][key]
|
||
|
except KeyError:
|
||
|
logging.debug(f"Cannot find '{key}' key in '{ansible_config_path}' config file")
|
||
|
|
||
|
ansible_config_paths = ':'.join(ansible_config_dirs)
|
||
|
raise RuntimeError(f"Cannot find key '{ANSIBLE_CONFIG_KEY}' in {ansible_config_paths}")
|
||
|
|
||
|
def build_arg_parser():
|
||
|
parser = argparse.ArgumentParser(description='Get a vault password from user keyring')
|
||
|
|
||
|
parser.add_argument('--vault-id', action='store', default='',
|
||
|
dest='vault_id',
|
||
|
help='Name of the vault secret to get from keyring')
|
||
|
return parser
|
||
|
|
||
|
def main():
|
||
|
logger = logging.getLogger()
|
||
|
logger.setLevel(logging.NOTSET)
|
||
|
|
||
|
formatter = logging.Formatter("%(levelname)s: %(message)s")
|
||
|
|
||
|
stdout_handler = logging.StreamHandler(sys.stdout)
|
||
|
stdout_handler.setLevel(logging.INFO)
|
||
|
stdout_handler.addFilter(lambda record: record.levelno <= logging.INFO)
|
||
|
stdout_handler.setFormatter(formatter)
|
||
|
logger.addHandler(stdout_handler)
|
||
|
|
||
|
stderr_handler = logging.StreamHandler(sys.stderr)
|
||
|
stderr_handler.setLevel(logging.WARNING)
|
||
|
stderr_handler.setFormatter(formatter)
|
||
|
logger.addHandler(stderr_handler)
|
||
|
|
||
|
logger.addHandler(ShutdownHandler(level=logging.ERROR))
|
||
|
|
||
|
try:
|
||
|
ansible_config_value = find_ansible_config_value(ANSIBLE_CONFIG_SECTION, ANSIBLE_CONFIG_KEY)
|
||
|
except RuntimeError as e:
|
||
|
logging.error(e)
|
||
|
|
||
|
arg_parser = build_arg_parser()
|
||
|
args = arg_parser.parse_args()
|
||
|
|
||
|
ansible_vault_id = args.vault_id
|
||
|
gopass_key_path = os.path.join(ansible_config_value, ansible_vault_id)
|
||
|
|
||
|
gopass_keys_cmd = subprocess.run(["gopass", "ls", "--flat"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||
|
if gopass_keys_cmd.returncode != 0:
|
||
|
logging.error(gopass_keys_cmd.stderr.decode())
|
||
|
gopass_keys = map(bytes.decode, gopass_keys_cmd.stdout.splitlines())
|
||
|
|
||
|
try:
|
||
|
gopass_keyname = next(key for key in gopass_keys if key.endswith(gopass_key_path))
|
||
|
except StopIteration:
|
||
|
logging.error(f"Cannot find '{gopass_key_path}' entry in gopass")
|
||
|
|
||
|
ansible_vault_pass_cmd = subprocess.run(["gopass", "show", "-o", gopass_keyname], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||
|
if ansible_vault_pass_cmd.returncode != 0:
|
||
|
logging.error(ansible_vault_pass_cmd.stderr.decode())
|
||
|
print(ansible_vault_pass_cmd.stdout.decode())
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|