From 8a0a787405274dfcf1212b6348195ec3ac1b4cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Parunakian?= Date: Fri, 8 Jun 2018 16:33:53 +0200 Subject: [PATCH] Add backup option to passwordstore lookup (and improve doc) (#39676) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add backup option in passwordstore lookup * Update passwordstore lookup documentation * Add precision regarding backup param * Fix empty line added at EOF * Add version_added attribute for backup option * Switch examples to multi-line YAML * Fix documentation for overwrite option * Add changelog fragment for passwordstore lookup * Update version added for new feature to 2.7 Co-authored by: Stéphane Parunakian --- .../passwordstore-lookup-backup.yaml | 3 ++ lib/ansible/plugins/lookup/passwordstore.py | 47 ++++++++++++------- 2 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 changelogs/fragments/passwordstore-lookup-backup.yaml diff --git a/changelogs/fragments/passwordstore-lookup-backup.yaml b/changelogs/fragments/passwordstore-lookup-backup.yaml new file mode 100644 index 00000000000..62067a6a5c7 --- /dev/null +++ b/changelogs/fragments/passwordstore-lookup-backup.yaml @@ -0,0 +1,3 @@ +--- +minor_changes: + - passwordstore - Add backup option when overwriting password (off by default) diff --git a/lib/ansible/plugins/lookup/passwordstore.py b/lib/ansible/plugins/lookup/passwordstore.py index d06f37bef1b..334b50f00eb 100644 --- a/lib/ansible/plugins/lookup/passwordstore.py +++ b/lib/ansible/plugins/lookup/passwordstore.py @@ -22,52 +22,63 @@ DOCUMENTATION = """ description: location of the password store default: '~/.password-store' directory: - description: directory of the password store + description: The directory of the password store. env: - name: PASSWORD_STORE_DIR create: - description: flag to create the password + description: Create the password if it does not already exist. type: bool default: 'no' overwrite: - description: flag to overwrite the password + description: Overwrite the password if it does already exist. type: bool default: 'no' returnall: - description: flag to return all the contents of the password store + description: Return all the content of the password, not only the first line. type: bool default: 'no' subkey: - description: subkey to return + description: Return a specific subkey of the password. default: password userpass: - description: user password + description: Specify a password to save, instead of a generated one. length: - description: password length + description: The length of the generated password type: integer default: 16 + backup: + description: Used with C(overwrite=yes). Backup the previous password in a subkey. + type: bool + default: 'no' + version_added: 2.7 """ EXAMPLES = """ # Debug is used for examples, BAD IDEA to show passwords on screen - name: Basic lookup. Fails if example/test doesn't exist - debug: msg="{{ lookup('passwordstore', 'example/test')}}" + debug: + msg: "{{ lookup('passwordstore', 'example/test')}}" - name: Create pass with random 16 character password. If password exists just give the password - debug: var=mypassword + debug: + var: mypassword vars: mypassword: "{{ lookup('passwordstore', 'example/test create=true')}}" - name: Different size password - debug: msg="{{ lookup('passwordstore', 'example/test create=true length=42')}}" + debug: + msg: "{{ lookup('passwordstore', 'example/test create=true length=42')}}" - name: Create password and overwrite the password if it exists. As a bonus, this module includes the old password inside the pass file - debug: msg="{{ lookup('passwordstore', 'example/test create=true overwrite=true')}}" + debug: + msg: "{{ lookup('passwordstore', 'example/test create=true overwrite=true')}}" - name: Return the value for user in the KV pair user, username - debug: msg="{{ lookup('passwordstore', 'example/test subkey=user')}}" + debug: + msg: "{{ lookup('passwordstore', 'example/test subkey=user')}}" - name: Return the entire password file content - set_fact: passfilecontent="{{ lookup('passwordstore', 'example/test returnall=true')}}" + set_fact: + passfilecontent: "{{ lookup('passwordstore', 'example/test returnall=true')}}" """ RETURN = """ @@ -144,7 +155,7 @@ class LookupModule(LookupBase): raise AnsibleError(e) # check and convert values try: - for key in ['create', 'returnall', 'overwrite']: + for key in ['create', 'returnall', 'overwrite', 'backup']: if not isinstance(self.paramvals[key], bool): self.paramvals[key] = util.strtobool(self.paramvals[key]) except (ValueError, AssertionError) as e: @@ -197,8 +208,11 @@ class LookupModule(LookupBase): # generate new password, insert old lines from current result and return new password newpass = self.get_newpass() datetime = time.strftime("%d/%m/%Y %H:%M:%S") - msg = newpass + '\n' + '\n'.join(self.passoutput[1:]) - msg += "\nlookup_pass: old password was {0} (Updated on {1})\n".format(self.password, datetime) + msg = newpass + '\n' + if self.passoutput[1:]: + msg += '\n'.join(self.passoutput[1:]) + '\n' + if self.paramvals['backup']: + msg += "lookup_pass: old password was {0} (Updated on {1})\n".format(self.password, datetime) try: check_output2(['pass', 'insert', '-f', '-m', self.passname], input=msg) except (subprocess.CalledProcessError) as e: @@ -238,6 +252,7 @@ class LookupModule(LookupBase): 'overwrite': False, 'userpass': '', 'length': 16, + 'backup': False, } for term in terms: