From 5b93288ff7bea63ec719665e5d5b38f938afbf33 Mon Sep 17 00:00:00 2001 From: "Manuel Amador (Rudd-O)" Date: Sun, 7 May 2017 15:51:32 +0000 Subject: [PATCH] qubes-pass lookup plugin added. --- README.md | 3 +++ lookup_plugins/README.md | 41 ++++++++++++++++++++++++++++++++++++ lookup_plugins/qubes-pass.py | 38 +++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 lookup_plugins/README.md create mode 100644 lookup_plugins/qubes-pass.py diff --git a/README.md b/README.md index 8e2ef51..54d2c13 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ The software in this kit includes the following: [Qubes OS 3.1 Salt management stack](https://www.qubes-os.org/news/2015/12/14/mgmt-stack/). 5. A [set of DevOps automation skeletons / examples](./examples/) to get you up and running without having to construct everything yourself. +6. A [lookup plugin](./lookup_plugins) for + [`qubes-pass`](https://github.com/Rudd-O/qubes-pass) to get you to + store passwords needed to manage your infrastructure in separate VMs. `bombshell-client` and the other programs in this toolkit that depend on it, can be used to run operations from one VM to another, diff --git a/lookup_plugins/README.md b/lookup_plugins/README.md new file mode 100644 index 0000000..4f4a768 --- /dev/null +++ b/lookup_plugins/README.md @@ -0,0 +1,41 @@ +# Ansible Qubes Pass lookup plugin + +This lookup plugin has the ability to look up a password in another Qubes VM +by using the excellent [`qubes-pass`](https://github.com/Rudd-O/qubes-pass) +to retrieve it from the VM. It also (by default) automatically creates +password entries that do not exist yet, such that you do not have to ever +manually create passwords for your playbooks and variables. + +Here is how you use it: + +``` +- hosts: myhost + become: yes + vars: + thepassword: '{{ lookup("qubes-pass", "loginpwds/John Smith") }}' + tasks: + - copy: + name: /root/mountcreds + contents: '{{ thepassword }}' + owner: root + group: root + mode: 0600 +``` + +When executed, this simple playbook will set the variable `thepassword` +to the contents of the key `loginpwds/John Smith` in the password store +of your designated password store VM. If the key does not exist, then +the key will be created automatically with a 32 character password. + +You can also explicitly specify the VM: + +``` + thepassword: '{{ lookup("qubes-pass", "loginpwds/John Smith", vm=vault) }}' +``` + +You can also disable automatic creation of the password. This will simply +fail if the password does not exist: + +``` + thepassword: '{{ lookup("qubes-pass", "loginpwds/John Smith", create=False) }}' +``` diff --git a/lookup_plugins/qubes-pass.py b/lookup_plugins/qubes-pass.py new file mode 100644 index 0000000..eaab1e1 --- /dev/null +++ b/lookup_plugins/qubes-pass.py @@ -0,0 +1,38 @@ +from ansible.errors import AnsibleError, AnsibleParserError +from ansible.plugins.lookup import LookupBase + +import subprocess + +try: + from __main__ import display +except ImportError: + from ansible.utils.display import Display + display = Display() + + +class LookupModule(LookupBase): + + def run(self, entry, variables=None, vm=None, create=True): + + ret = [] + + cmd = ['qvm-pass'] + if vm is not None: + cmd += ['-d', vm] + if create: + cmd += ['get-or-generate'] + else: + cmd += ['get-or-generate'] + cmd += ['--', entry] + + display.vvvv(u"Password lookup using command %s" % cmd) + + try: + ret = subprocess.check_output(cmd)[:-1] + except subprocess.CalledProcessError as e: + if e.retcode == 8: + raise AnsibleError("qubes-pass could not locate password entry %s in store" % entry) + else: + raise AnsibleError("qubes-pass lookup failed: %s" % e) + + return ret