Add yaml support to passwordstore. (#1681)

Co-authored-by: Florian Bergmann <Florian.Bergmann@datev.de>
pull/1693/head
Florian Bergmann 2021-01-28 09:24:28 +01:00 committed by GitHub
parent 5a52b573fe
commit f955a85848
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 4 deletions

View File

@ -0,0 +1,2 @@
breaking_changes:
- "passwordstore lookup plugin - now parsing a password store entry as YAML if possible, skipping the first line (which by convention only contains the password and nothing else). If it cannot be parsed as YAML, the old ``key: value`` parser will be used to process the entry. Can break backwards compatibility if YAML formatted code was parsed in a non-YAML interpreted way, e.g. ``foo: [bar, baz]`` will become a list with two elements in the new version, but a string ``'[bar, baz]'`` in the old (https://github.com/ansible-collections/community.general/issues/1673)."

View File

@ -105,6 +105,8 @@ _raw:
import os import os
import subprocess import subprocess
import time import time
import yaml
from distutils import util from distutils import util
from ansible.errors import AnsibleError, AnsibleAssertionError from ansible.errors import AnsibleError, AnsibleAssertionError
@ -209,6 +211,11 @@ class LookupModule(LookupBase):
).splitlines() ).splitlines()
self.password = self.passoutput[0] self.password = self.passoutput[0]
self.passdict = {} self.passdict = {}
try:
values = yaml.safe_load('\n'.join(self.passoutput[1:]))
for key, item in values.items():
self.passdict[key] = item
except (yaml.YAMLError, AttributeError):
for line in self.passoutput[1:]: for line in self.passoutput[1:]:
if ':' in line: if ':' in line:
name, value = line.split(':', 1) name, value = line.split(':', 1)

View File

@ -60,3 +60,63 @@
assert: assert:
that: that:
- readpass == newpass - readpass == newpass
# As inserting multiline passwords on the commandline would require something
# like expect, simply create it by using default gpg on a file with the correct
# structure.
- name: Create the YAML password content
copy:
dest: "~/.password-store/test-yaml-pass"
content: |
testpassword
key: |
multi
line
- name: Read .gpg-id from .password-store
set_fact:
gpgid: "{{ lookup('file', '~/.password-store/.gpg-id') }}"
- name: Encrypt the file using the gpg key
command: "{{ gpg2_bin }} --batch --encrypt -r {{ gpgid }} ~/.password-store/test-yaml-pass"
- name: Fetch a password with YAML subkey
set_fact:
readyamlpass: "{{ lookup('community.general.passwordstore', 'test-yaml-pass subkey=key') }}"
- name: Read a yaml subkey
assert:
that:
- readyamlpass == 'multi\nline'
- name: Create a non-YAML multiline file
copy:
dest: "~/.password-store/test-multiline-pass"
content: |
testpassword
random additional line
- name: Read .gpg-id from .password-store
set_fact:
gpgid: "{{ lookup('file', '~/.password-store/.gpg-id') }}"
- name: Encrypt the file using the gpg key
command: "{{ gpg2_bin }} --batch --encrypt -r {{ gpgid }} ~/.password-store/test-multiline-pass"
- name: Fetch password from multiline file
set_fact:
readyamlpass: "{{ lookup('community.general.passwordstore', 'test-multiline-pass') }}"
- name: Multiline pass only returns first line
assert:
that:
- readyamlpass == 'testpassword'
- name: Fetch all from multiline file
set_fact:
readyamlpass: "{{ lookup('community.general.passwordstore', 'test-multiline-pass returnall=yes') }}"
- name: Multiline pass returnall returns everything in the file
assert:
that:
- readyamlpass == 'testpassword\nrandom additional line'