mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
passwordstore: Add some real gopass integration tests (#5030)
* passwordstore: Add some real go tests This is work in progress. * passwordstore: Fix gopass init * Init gopass store in explicit path in integration test * passwordstore: Show versions of tools in integration test * passwordstore: Install gopass from different location on Debian Part of integration tests * passwordstore: Add changelog fragment for #5030 * passwordstore: Address review feedback
This commit is contained in:
parent
c273498a03
commit
74f2e1d28b
7 changed files with 182 additions and 148 deletions
|
@ -31,6 +31,26 @@
|
||||||
disable_gpg_check: yes
|
disable_gpg_check: yes
|
||||||
when: ansible_facts.pkg_mgr in ['zypper', 'community.general.zypper']
|
when: ansible_facts.pkg_mgr in ['zypper', 'community.general.zypper']
|
||||||
|
|
||||||
|
# See https://github.com/gopasspw/gopass/issues/1849#issuecomment-802789285
|
||||||
|
- name: Install gopass on Debian
|
||||||
|
when: ansible_facts.os_family == 'Debian'
|
||||||
|
become: yes
|
||||||
|
block:
|
||||||
|
- name: Fetch gopass repo keyring
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://packages.gopass.pw/repos/gopass/gopass-archive-keyring.gpg
|
||||||
|
dest: /usr/share/keyrings/gopass-archive-keyring.gpg
|
||||||
|
- name: Add gopass repo
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: "deb [arch=amd64,arm64,armhf \
|
||||||
|
signed-by=/usr/share/keyrings/gopass-archive-keyring.gpg] \
|
||||||
|
https://packages.gopass.pw/repos/gopass stable main"
|
||||||
|
state: present
|
||||||
|
- name: Update apt-cache and install gopass package
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: gopass
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
- name: Install on macOS
|
- name: Install on macOS
|
||||||
when: ansible_facts.distribution == 'MacOSX'
|
when: ansible_facts.distribution == 'MacOSX'
|
||||||
block:
|
block:
|
||||||
|
@ -48,6 +68,7 @@
|
||||||
name:
|
name:
|
||||||
- gnupg2
|
- gnupg2
|
||||||
- pass
|
- pass
|
||||||
|
- gopass
|
||||||
state: present
|
state: present
|
||||||
update_homebrew: no
|
update_homebrew: no
|
||||||
become: yes
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
- name: Create a password ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
newpass: "{{ lookup('community.general.passwordstore', 'test-pass length=8 create=yes', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Fetch password from an existing file ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
readpass: "{{ lookup('community.general.passwordstore', 'test-pass', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Verify password ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- readpass == newpass
|
||||||
|
|
||||||
|
- name: Create a password with equal sign ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
newpass: "{{ lookup('community.general.passwordstore', 'test-pass-equal userpass=SimpleSample= create=yes', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Fetch a password with equal sign ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
readpass: "{{ lookup('community.general.passwordstore', 'test-pass-equal', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Verify password ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- readpass == newpass
|
||||||
|
|
||||||
|
- name: Create a password using missing=create ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
newpass: "{{ lookup('community.general.passwordstore', 'test-missing-create missing=create length=8', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Fetch password from an existing file ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
readpass: "{{ lookup('community.general.passwordstore', 'test-missing-create', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Verify password ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- readpass == newpass
|
||||||
|
|
||||||
|
- name: Fetch password from existing file using missing=empty ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
readpass: "{{ lookup('community.general.passwordstore', 'test-missing-create missing=empty', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Verify password ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- readpass == newpass
|
||||||
|
|
||||||
|
- name: Fetch password from non-existing file using missing=empty ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
readpass: "{{ query('community.general.passwordstore', 'test-missing-pass missing=empty', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Verify password ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- readpass == [ none ]
|
||||||
|
|
||||||
|
- name: Create the YAML password ({{ backend }})
|
||||||
|
command: "{{ backend }} insert -m -f test-yaml-pass"
|
||||||
|
args:
|
||||||
|
stdin: |
|
||||||
|
testpassword
|
||||||
|
key: |
|
||||||
|
multi
|
||||||
|
line
|
||||||
|
|
||||||
|
- name: Fetch a password with YAML subkey ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
readyamlpass: "{{ lookup('community.general.passwordstore', 'test-yaml-pass subkey=key', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Read a yaml subkey ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- readyamlpass == 'multi\nline\n'
|
||||||
|
|
||||||
|
- name: Create a non-YAML multiline file ({{ backend }})
|
||||||
|
command: "{{ backend }} insert -m -f test-multiline-pass"
|
||||||
|
args:
|
||||||
|
stdin: |
|
||||||
|
testpassword
|
||||||
|
random additional line
|
||||||
|
|
||||||
|
- name: Fetch password from multiline file ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
readyamlpass: "{{ lookup('community.general.passwordstore', 'test-multiline-pass', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Multiline pass only returns first line ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- readyamlpass == 'testpassword'
|
||||||
|
|
||||||
|
- name: Fetch all from multiline file ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
readyamlpass: "{{ lookup('community.general.passwordstore', 'test-multiline-pass returnall=yes', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Multiline pass returnall returns everything in the file ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- readyamlpass == 'testpassword\nrandom additional line\n'
|
||||||
|
|
||||||
|
- name: Create a password in a folder ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
newpass: "{{ lookup('community.general.passwordstore', 'folder/test-pass length=8 create=yes', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Fetch password from folder ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
readpass: "{{ lookup('community.general.passwordstore', 'folder/test-pass', backend=backend) }}"
|
||||||
|
|
||||||
|
- name: Verify password from folder ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- readpass == newpass
|
||||||
|
|
||||||
|
- name: Try to read folder as passname ({{ backend }})
|
||||||
|
set_fact:
|
||||||
|
newpass: "{{ lookup('community.general.passwordstore', 'folder', backend=backend) }}"
|
||||||
|
ignore_errors: true
|
||||||
|
register: eval_error
|
||||||
|
|
||||||
|
- name: Make sure reading folder as passname failed ({{ backend }})
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- eval_error is failed
|
||||||
|
- '"passname folder not found" in eval_error.msg'
|
||||||
|
when: backend != "gopass" # Remove this line once gopass backend can handle this
|
|
@ -41,12 +41,10 @@
|
||||||
- name: Try to find gopass in path
|
- name: Try to find gopass in path
|
||||||
command: which gopass
|
command: which gopass
|
||||||
register: result
|
register: result
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Store path of gopass executable
|
- name: Store path of gopass executable
|
||||||
set_fact:
|
set_fact:
|
||||||
gopasspath: "{{ (result.rc == 0) |
|
gopasspath: "{{ result.stdout }}"
|
||||||
ternary(result.stdout, (passpath | dirname, 'gopass') | path_join) }}"
|
|
||||||
|
|
||||||
- name: Move original gopass into place if there was a leftover
|
- name: Move original gopass into place if there was a leftover
|
||||||
command:
|
command:
|
||||||
|
@ -57,6 +55,18 @@
|
||||||
args:
|
args:
|
||||||
removes: "{{ gopasspath }}.testorig"
|
removes: "{{ gopasspath }}.testorig"
|
||||||
|
|
||||||
|
- name: Get versions of tools
|
||||||
|
command: "{{ item }} --version"
|
||||||
|
register: versions
|
||||||
|
loop:
|
||||||
|
- "{{ gpg2_bin }}"
|
||||||
|
- pass
|
||||||
|
- gopass
|
||||||
|
|
||||||
|
- name: Output versions of tools
|
||||||
|
debug:
|
||||||
|
msg: "{{ versions.results | map(attribute='stdout_lines') }}"
|
||||||
|
|
||||||
# How to generate a new GPG key:
|
# How to generate a new GPG key:
|
||||||
# gpg2 --batch --gen-key input # See templates/input
|
# gpg2 --batch --gen-key input # See templates/input
|
||||||
# gpg2 --list-secret-keys --keyid-format LONG
|
# gpg2 --list-secret-keys --keyid-format LONG
|
||||||
|
@ -70,150 +80,22 @@
|
||||||
- name: Trust key
|
- name: Trust key
|
||||||
shell: echo "D3E1CC8934E97270CEB066023AF1BD3619AB496A:6:" | {{ gpg2_bin }} --import-ownertrust
|
shell: echo "D3E1CC8934E97270CEB066023AF1BD3619AB496A:6:" | {{ gpg2_bin }} --import-ownertrust
|
||||||
|
|
||||||
- name: Initialise passwordstore
|
- name: Initialise pass passwordstore
|
||||||
command: pass init ansible-test
|
command: pass init ansible-test
|
||||||
|
|
||||||
- name: Create a password
|
- name: Initialise gopass passwordstore
|
||||||
set_fact:
|
command: gopass init --path $HOME/.gopass-store ansible-test
|
||||||
newpass: "{{ lookup('community.general.passwordstore', 'test-pass length=8 create=yes') }}"
|
args:
|
||||||
|
creates: "{{ lookup('env','HOME') }}/.gopass-store"
|
||||||
|
|
||||||
- name: Fetch password from an existing file
|
# these tests should apply to all backends
|
||||||
set_fact:
|
- name: Password tests
|
||||||
readpass: "{{ lookup('community.general.passwordstore', 'test-pass') }}"
|
include_tasks: password_tests.yml
|
||||||
|
loop:
|
||||||
- name: Verify password
|
- pass
|
||||||
assert:
|
- gopass
|
||||||
that:
|
loop_control:
|
||||||
- readpass == newpass
|
loop_var: backend
|
||||||
|
|
||||||
- name: Create a password with equal sign
|
|
||||||
set_fact:
|
|
||||||
newpass: "{{ lookup('community.general.passwordstore', 'test-pass-equal userpass=SimpleSample= create=yes') }}"
|
|
||||||
|
|
||||||
- name: Fetch a password with equal sign
|
|
||||||
set_fact:
|
|
||||||
readpass: "{{ lookup('community.general.passwordstore', 'test-pass-equal') }}"
|
|
||||||
|
|
||||||
- name: Verify password
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- readpass == newpass
|
|
||||||
|
|
||||||
- name: Create a password using missing=create
|
|
||||||
set_fact:
|
|
||||||
newpass: "{{ lookup('community.general.passwordstore', 'test-missing-create missing=create length=8') }}"
|
|
||||||
|
|
||||||
- name: Fetch password from an existing file
|
|
||||||
set_fact:
|
|
||||||
readpass: "{{ lookup('community.general.passwordstore', 'test-missing-create') }}"
|
|
||||||
|
|
||||||
- name: Verify password
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- readpass == newpass
|
|
||||||
|
|
||||||
- name: Fetch password from existing file using missing=empty
|
|
||||||
set_fact:
|
|
||||||
readpass: "{{ lookup('community.general.passwordstore', 'test-missing-create missing=empty') }}"
|
|
||||||
|
|
||||||
- name: Verify password
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- readpass == newpass
|
|
||||||
|
|
||||||
- name: Fetch password from non-existing file using missing=empty
|
|
||||||
set_fact:
|
|
||||||
readpass: "{{ query('community.general.passwordstore', 'test-missing-pass missing=empty') }}"
|
|
||||||
|
|
||||||
- name: Verify password
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- readpass == [ none ]
|
|
||||||
|
|
||||||
# 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'
|
|
||||||
|
|
||||||
- name: Create a password in a folder
|
|
||||||
set_fact:
|
|
||||||
newpass: "{{ lookup('community.general.passwordstore', 'folder/test-pass length=8 create=yes') }}"
|
|
||||||
|
|
||||||
- name: Fetch password from folder
|
|
||||||
set_fact:
|
|
||||||
readpass: "{{ lookup('community.general.passwordstore', 'folder/test-pass') }}"
|
|
||||||
|
|
||||||
- name: Verify password from folder
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- readpass == newpass
|
|
||||||
|
|
||||||
- name: Try to read folder as passname
|
|
||||||
set_fact:
|
|
||||||
newpass: "{{ lookup('community.general.passwordstore', 'folder') }}"
|
|
||||||
ignore_errors: true
|
|
||||||
register: eval_error
|
|
||||||
|
|
||||||
- name: Make sure reading folder as passname failed
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- eval_error is failed
|
|
||||||
- '"passname folder not found" in eval_error.msg'
|
|
||||||
|
|
||||||
- name: Change passwordstore location explicitly
|
- name: Change passwordstore location explicitly
|
||||||
set_fact:
|
set_fact:
|
||||||
|
@ -289,11 +171,13 @@
|
||||||
args:
|
args:
|
||||||
removes: "{{ passpath }}.testorig"
|
removes: "{{ passpath }}.testorig"
|
||||||
|
|
||||||
- name: Very basic gopass compatibility test
|
# This are in addition to the real gopass tests above
|
||||||
|
# and verify plugin logic
|
||||||
|
- name: gopass plugin logic tests
|
||||||
vars:
|
vars:
|
||||||
passwordstore_backend: "gopass"
|
passwordstore_backend: "gopass"
|
||||||
block:
|
block:
|
||||||
- name: check if gopass executable exists
|
- name: Check if gopass executable exists
|
||||||
stat:
|
stat:
|
||||||
path: "{{ gopasspath }}"
|
path: "{{ gopasspath }}"
|
||||||
register: gopass_check
|
register: gopass_check
|
||||||
|
@ -322,11 +206,11 @@
|
||||||
dest: "{{ gopasspath }}"
|
dest: "{{ gopasspath }}"
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
|
|
||||||
- name: Try to read folder as passname using gopass
|
- name: Try to read folder as passname using gopass mock
|
||||||
set_fact:
|
set_fact:
|
||||||
newpass: "{{ lookup('community.general.passwordstore', 'folder') }}"
|
newpass: "{{ lookup('community.general.passwordstore', 'folder') }}"
|
||||||
|
|
||||||
- name: Verify password received from gopass
|
- name: Verify password received from gopass mock
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- newpass == "gopass_ok"
|
- newpass == "gopass_ok"
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
passwordstore_packages:
|
passwordstore_packages:
|
||||||
|
- gopass
|
||||||
- pass
|
- pass
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
passwordstore_packages:
|
passwordstore_packages:
|
||||||
|
- gopass
|
||||||
- pass
|
- pass
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
passwordstore_packages:
|
passwordstore_packages:
|
||||||
|
- gopass
|
||||||
- pass
|
- pass
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
passwordstore_packages:
|
passwordstore_packages:
|
||||||
|
- gopass
|
||||||
- gnupg
|
- gnupg
|
||||||
- password-store
|
- password-store
|
||||||
|
|
Loading…
Reference in a new issue