mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
hashi_vault lookup: add integration tests (#44814)
* hashi_vault lookup: add integration tests * hashi_vault lookup tests: use ansible-ci-files
This commit is contained in:
parent
afea00fa9f
commit
9984c0fd40
12 changed files with 338 additions and 0 deletions
2
test/integration/targets/lookup_hashi_vault/aliases
Normal file
2
test/integration/targets/lookup_hashi_vault/aliases
Normal file
|
@ -0,0 +1,2 @@
|
|||
shippable/posix/group2
|
||||
destructive
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
vault_base_path: 'secret/data/testproject'
|
||||
vault_base_path_kv: 'secret/testproject' # required by KV 2 engine
|
|
@ -0,0 +1,21 @@
|
|||
- name: 'Create an approle policy'
|
||||
shell: "echo '{{ policy }}' | {{ vault_cmd }} policy write approle-policy -"
|
||||
vars:
|
||||
policy: |
|
||||
path "auth/approle/login" {
|
||||
capabilities = [ "create", "read" ]
|
||||
}
|
||||
|
||||
- name: 'Enable the AppRole auth method'
|
||||
command: '{{ vault_cmd }} auth enable approle'
|
||||
|
||||
- name: 'Create a named role'
|
||||
command: '{{ vault_cmd }} write auth/approle/role/test-role policies="test-policy,approle-policy"'
|
||||
|
||||
- name: 'Fetch the RoleID of the AppRole'
|
||||
command: '{{ vault_cmd }} read -field=role_id auth/approle/role/test-role/role-id'
|
||||
register: role_id_cmd
|
||||
|
||||
- name: 'Get a SecretID issued against the AppRole'
|
||||
command: '{{ vault_cmd }} write -field=secret_id -f auth/approle/role/test-role/secret-id'
|
||||
register: secret_id_cmd
|
|
@ -0,0 +1,45 @@
|
|||
- vars:
|
||||
role_id: '{{ role_id_cmd.stdout }}'
|
||||
secret_id: '{{ secret_id_cmd.stdout }}'
|
||||
block:
|
||||
- name: 'Fetch secrets using "hashi_vault" lookup'
|
||||
set_fact:
|
||||
secret1: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret1 auth_method=approle secret_id=' ~ secret_id ~ ' role_id=' ~ role_id) }}"
|
||||
secret2: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret2 auth_method=approle secret_id=' ~ secret_id ~ ' role_id=' ~ role_id) }}"
|
||||
|
||||
- name: 'Check secret values'
|
||||
fail:
|
||||
msg: 'unexpected secret values'
|
||||
when: secret1['data']['value'] != 'foo1' or secret2['data']['value'] != 'foo2'
|
||||
|
||||
- name: 'Failure expected when erroneous credentials are used'
|
||||
vars:
|
||||
secret_wrong_cred: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret2 auth_method=approle secret_id=toto role_id=' ~ role_id) }}"
|
||||
debug:
|
||||
msg: 'Failure is expected ({{ secret_wrong_cred }})'
|
||||
register: test_wrong_cred
|
||||
ignore_errors: true
|
||||
|
||||
- name: 'Failure expected when unauthorized secret is read'
|
||||
vars:
|
||||
secret_unauthorized: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret3 auth_method=approle secret_id=' ~ secret_id ~ ' role_id=' ~ role_id) }}"
|
||||
debug:
|
||||
msg: 'Failure is expected ({{ secret_unauthorized }})'
|
||||
register: test_unauthorized
|
||||
ignore_errors: true
|
||||
|
||||
- name: 'Failure expected when inexistent secret is read'
|
||||
vars:
|
||||
secret_inexistent: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret4 auth_method=approle secret_id=' ~ secret_id ~ ' role_id=' ~ role_id) }}"
|
||||
debug:
|
||||
msg: 'Failure is expected ({{ secret_inexistent }})'
|
||||
register: test_inexistent
|
||||
ignore_errors: true
|
||||
|
||||
- name: 'Check expected failures'
|
||||
assert:
|
||||
msg: "an expected failure didn't occur"
|
||||
that:
|
||||
- test_wrong_cred is failed
|
||||
- test_unauthorized is failed
|
||||
- test_inexistent is failed
|
|
@ -0,0 +1,122 @@
|
|||
---
|
||||
- name: Install Hashi Vault on controlled node and test
|
||||
|
||||
vars:
|
||||
vault_version: '0.11.0'
|
||||
vault_uri: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/lookup_hashi_vault/vault_{{ vault_version }}_{{ ansible_system | lower }}_{{ vault_arch }}.zip'
|
||||
vault_cmd: '{{ local_temp_dir }}/vault'
|
||||
|
||||
connection: local # already defined in inventory for testhost, usefull when used with another inventory
|
||||
|
||||
block:
|
||||
- name: Create a local temporary directory
|
||||
tempfile:
|
||||
state: directory
|
||||
register: tempfile_result
|
||||
|
||||
- set_fact:
|
||||
local_temp_dir: '{{ tempfile_result.path }}'
|
||||
|
||||
- when: pyopenssl_version.stdout is version('0.15', '>=')
|
||||
block:
|
||||
- name: Generate privatekey
|
||||
openssl_privatekey:
|
||||
path: '{{ local_temp_dir }}/privatekey.pem'
|
||||
|
||||
- name: Generate CSR
|
||||
openssl_csr:
|
||||
path: '{{ local_temp_dir }}/csr.csr'
|
||||
privatekey_path: '{{ local_temp_dir }}/privatekey.pem'
|
||||
subject:
|
||||
commonName: localhost
|
||||
|
||||
- name: Generate selfsigned certificate
|
||||
openssl_certificate:
|
||||
path: '{{ local_temp_dir }}/cert.pem'
|
||||
csr_path: '{{ local_temp_dir }}/csr.csr'
|
||||
privatekey_path: '{{ local_temp_dir }}/privatekey.pem'
|
||||
provider: selfsigned
|
||||
selfsigned_digest: sha256
|
||||
register: selfsigned_certificate
|
||||
|
||||
- name: 'Install unzip'
|
||||
package:
|
||||
name: unzip
|
||||
when: ansible_distribution != "MacOSX" # unzip already installed
|
||||
|
||||
- assert:
|
||||
# Linux: x86_64, FreeBSD: amd64
|
||||
that: ansible_architecture in ['i386', 'x86_64', 'amd64']
|
||||
- set_fact:
|
||||
vault_arch: '386'
|
||||
when: ansible_architecture == 'i386'
|
||||
- set_fact:
|
||||
vault_arch: amd64
|
||||
when: ansible_architecture in ['x86_64', 'amd64']
|
||||
|
||||
- name: 'Download vault binary'
|
||||
unarchive:
|
||||
src: '{{ vault_uri }}'
|
||||
dest: '{{ local_temp_dir }}'
|
||||
remote_src: true
|
||||
|
||||
- environment:
|
||||
# used by vault command
|
||||
VAULT_DEV_ROOT_TOKEN_ID: '47542cbc-6bf8-4fba-8eda-02e0a0d29a0a'
|
||||
block:
|
||||
- name: 'Create configuration file'
|
||||
template:
|
||||
src: vault_config.hcl.j2
|
||||
dest: '{{ local_temp_dir }}/vault_config.hcl'
|
||||
|
||||
- name: 'Start vault service'
|
||||
environment:
|
||||
VAULT_ADDR: 'http://localhost:8200'
|
||||
block:
|
||||
- name: 'Start vault server (dev mode enabled)'
|
||||
shell: 'nohup {{ vault_cmd }} server -dev -config {{ local_temp_dir }}/vault_config.hcl </dev/null >/dev/null 2>&1 &'
|
||||
|
||||
- name: 'Create a test policy'
|
||||
shell: "echo '{{ policy }}' | {{ vault_cmd }} policy write test-policy -"
|
||||
vars:
|
||||
policy: |
|
||||
path "{{ vault_base_path }}/secret1" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "{{ vault_base_path }}/secret2" {
|
||||
capabilities = ["read", "update"]
|
||||
}
|
||||
path "{{ vault_base_path }}/secret3" {
|
||||
capabilities = ["deny"]
|
||||
}
|
||||
|
||||
- name: 'Create secrets'
|
||||
command: '{{ vault_cmd }} kv put {{ vault_base_path_kv }}/secret{{ item }} value=foo{{ item }}'
|
||||
loop: [1, 2, 3]
|
||||
|
||||
- name: setup approle auth
|
||||
import_tasks: approle_setup.yml
|
||||
when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>')
|
||||
|
||||
- name: setup token auth
|
||||
import_tasks: token_setup.yml
|
||||
|
||||
- import_tasks: tests.yml
|
||||
vars:
|
||||
auth_type: approle
|
||||
when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>')
|
||||
|
||||
- import_tasks: tests.yml
|
||||
vars:
|
||||
auth_type: token
|
||||
|
||||
always:
|
||||
- name: 'Kill vault process'
|
||||
shell: "kill $(cat {{ local_temp_dir }}/vault.pid)"
|
||||
ignore_errors: true
|
||||
|
||||
always:
|
||||
- name: 'Delete temp dir'
|
||||
file:
|
||||
path: '{{ local_temp_dir }}'
|
||||
state: absent
|
|
@ -0,0 +1,35 @@
|
|||
- name: 'test {{ auth_type }} auth without SSL (lookup parameters)'
|
||||
include_tasks: '{{ auth_type }}_test.yml'
|
||||
vars:
|
||||
conn_params: 'url=http://localhost:8200 '
|
||||
|
||||
- name: 'test {{ auth_type }} auth without SSL (environment variable)'
|
||||
include_tasks: '{{ auth_type }}_test.yml'
|
||||
args:
|
||||
apply:
|
||||
vars:
|
||||
conn_params: ''
|
||||
environment:
|
||||
VAULT_ADDR: 'http://localhost:8200'
|
||||
|
||||
- when: pyopenssl_version.stdout is version('0.15', '>=')
|
||||
block:
|
||||
- name: 'test {{ auth_type }} auth with certs (validation enabled, lookup parameters)'
|
||||
include_tasks: '{{ auth_type }}_test.yml'
|
||||
vars:
|
||||
conn_params: 'url=https://localhost:8201 cacert={{ local_temp_dir }}/cert.pem validate_certs=True '
|
||||
|
||||
- name: 'test {{ auth_type }} auth with certs (validation enabled, environment variables)'
|
||||
include_tasks: '{{ auth_type }}_test.yml'
|
||||
args:
|
||||
apply:
|
||||
vars:
|
||||
conn_params: ''
|
||||
environment:
|
||||
VAULT_ADDR: 'https://localhost:8201'
|
||||
VAULT_CACERT: '{{ local_temp_dir }}/cert.pem'
|
||||
|
||||
- name: 'test {{ auth_type }} auth with certs (validation disabled, lookup parameters)'
|
||||
include_tasks: '{{ auth_type }}_test.yml'
|
||||
vars:
|
||||
conn_params: 'url=https://localhost:8201 validate_certs=False '
|
|
@ -0,0 +1,3 @@
|
|||
- name: 'Create a test credentials (token)'
|
||||
command: '{{ vault_cmd }} token create -policy test-policy -field token'
|
||||
register: user_token_cmd
|
|
@ -0,0 +1,44 @@
|
|||
- vars:
|
||||
user_token: '{{ user_token_cmd.stdout }}'
|
||||
block:
|
||||
- name: 'Fetch secrets using "hashi_vault" lookup'
|
||||
set_fact:
|
||||
secret1: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret1 auth_method=token token=' ~ user_token) }}"
|
||||
secret2: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret2 token=' ~ user_token) }}"
|
||||
|
||||
- name: 'Check secret values'
|
||||
fail:
|
||||
msg: 'unexpected secret values'
|
||||
when: secret1['data']['value'] != 'foo1' or secret2['data']['value'] != 'foo2'
|
||||
|
||||
- name: 'Failure expected when erroneous credentials are used'
|
||||
vars:
|
||||
secret_wrong_cred: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret2 auth_method=token token=wrong_token') }}"
|
||||
debug:
|
||||
msg: 'Failure is expected ({{ secret_wrong_cred }})'
|
||||
register: test_wrong_cred
|
||||
ignore_errors: true
|
||||
|
||||
- name: 'Failure expected when unauthorized secret is read'
|
||||
vars:
|
||||
secret_unauthorized: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret3 token=' ~ user_token) }}"
|
||||
debug:
|
||||
msg: 'Failure is expected ({{ secret_unauthorized }})'
|
||||
register: test_unauthorized
|
||||
ignore_errors: true
|
||||
|
||||
- name: 'Failure expected when inexistent secret is read'
|
||||
vars:
|
||||
secret_inexistent: "{{ lookup('hashi_vault', conn_params ~ 'secret=' ~ vault_base_path ~ '/secret4 token=' ~ user_token) }}"
|
||||
debug:
|
||||
msg: 'Failure is expected ({{ secret_inexistent }})'
|
||||
register: test_inexistent
|
||||
ignore_errors: true
|
||||
|
||||
- name: 'Check expected failures'
|
||||
assert:
|
||||
msg: "an expected failure didn't occur"
|
||||
that:
|
||||
- test_wrong_cred is failed
|
||||
- test_unauthorized is failed
|
||||
- test_inexistent is failed
|
|
@ -0,0 +1,10 @@
|
|||
# {{ ansible_managed }}
|
||||
pid_file = "{{ local_temp_dir }}/vault.pid"
|
||||
{% if pyopenssl_version.stdout is version('0.15', '>=') %}
|
||||
listener "tcp" {
|
||||
tls_key_file = "{{ local_temp_dir }}/privatekey.pem"
|
||||
tls_cert_file = "{{ local_temp_dir }}/cert.pem"
|
||||
tls_disable = false
|
||||
address = "localhost:8201"
|
||||
}
|
||||
{% endif %}
|
|
@ -0,0 +1,19 @@
|
|||
- hosts: testhost
|
||||
tasks:
|
||||
- name: Install openssl
|
||||
import_role:
|
||||
name: setup_openssl
|
||||
|
||||
- name: "RedHat <= 7, select last version compatible with request 2.6.0 (this version doesn't support approle auth)"
|
||||
set_fact:
|
||||
hvac_package: 'hvac==0.2.5'
|
||||
when: ansible_distribution == 'RedHat' and ansible_distribution_major_version is version('7', '<=')
|
||||
|
||||
- name: 'CentOS < 7, select last version compatible with Python 2.6'
|
||||
set_fact:
|
||||
hvac_package: 'hvac==0.5.0'
|
||||
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version is version('7', '<')
|
||||
|
||||
- name: 'Install hvac Python package'
|
||||
pip:
|
||||
name: "{{ hvac_package|default('hvac') }}"
|
|
@ -0,0 +1,9 @@
|
|||
- hosts: testhost
|
||||
tasks:
|
||||
- name: register pyOpenSSL version
|
||||
command: python -c 'import OpenSSL; print(OpenSSL.__version__)'
|
||||
register: pyopenssl_version
|
||||
|
||||
- name: Test lookup hashi_vault
|
||||
import_role:
|
||||
name: lookup_hashi_vault/lookup_hashi_vault
|
25
test/integration/targets/lookup_hashi_vault/runme.sh
Executable file
25
test/integration/targets/lookup_hashi_vault/runme.sh
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -eux
|
||||
|
||||
# First install pyOpenSSL, then test lookup in a second playbook in order to
|
||||
# workaround this error which occurs on OS X 10.11 only:
|
||||
#
|
||||
# TASK [lookup_hashi_vault : test token auth with certs (validation enabled, lookup parameters)] ***
|
||||
# included: lookup_hashi_vault/tasks/token_test.yml for testhost
|
||||
#
|
||||
# TASK [lookup_hashi_vault : Fetch secrets using "hashi_vault" lookup] ***
|
||||
# From cffi callback <function _verify_callback at 0x106f995f0>:
|
||||
# Traceback (most recent call last):
|
||||
# File "/usr/local/lib/python2.7/site-packages/OpenSSL/SSL.py", line 309, in wrapper
|
||||
# _lib.X509_up_ref(x509)
|
||||
# AttributeError: 'module' object has no attribute 'X509_up_ref'
|
||||
# fatal: [testhost]: FAILED! => { "msg": "An unhandled exception occurred while running the lookup plugin 'hashi_vault'. Error was a <class 'requests.exceptions.SSLError'>, original message: HTTPSConnectionPool(host='localhost', port=8201): Max retries exceeded with url: /v1/auth/token/lookup-self (Caused by SSLError(SSLError(\"bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)\",),))"}
|
||||
|
||||
ANSIBLE_ROLES_PATH=../ \
|
||||
ANSIBLE_CONFIG=../../integration.cfg \
|
||||
ansible-playbook -i ../../inventory -e@../../integration_config.yml playbooks/install_dependencies.yml -v "$@"
|
||||
|
||||
ANSIBLE_ROLES_PATH=../ \
|
||||
ANSIBLE_CONFIG=../../integration.cfg \
|
||||
ansible-playbook -i ../../inventory -e@../../integration_config.yml playbooks/test_lookup_hashi_vault.yml -v "$@"
|
Loading…
Reference in a new issue