From 2fe6a34e3f78d2e564bbe0b240f51f0501945d50 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 16 Nov 2020 16:40:54 +0000 Subject: [PATCH] Fix hashi_vault lookup approle authentication (#1138) (#1315) As per the plugin documentation and the Hashicorp Vault documentation (https://www.vaultproject.io/docs/auth/approle#secretid) secret_id is not mandatory. Moreover, using this lookup plugin without a secret_id used to work in Ansible 2.9. Co-authored-by: Jonathan Piron (cherry picked from commit 6cec8759d0a6c5330f64685335db2f7cc87b6a41) Co-authored-by: Jonathan Piron --- ...prole_authentication_without_secret_id.yml | 2 + plugins/lookup/hashi_vault.py | 2 +- .../tasks/approle_secret_id_less_setup.yml | 19 ++++++++ .../tasks/approle_secret_id_less_test.yml | 44 +++++++++++++++++++ .../lookup_hashi_vault/tasks/main.yml | 9 ++++ 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/1138-hashi_vault_fix_approle_authentication_without_secret_id.yml create mode 100644 tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/approle_secret_id_less_setup.yml create mode 100644 tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/approle_secret_id_less_test.yml diff --git a/changelogs/fragments/1138-hashi_vault_fix_approle_authentication_without_secret_id.yml b/changelogs/fragments/1138-hashi_vault_fix_approle_authentication_without_secret_id.yml new file mode 100644 index 0000000000..840e10d4a9 --- /dev/null +++ b/changelogs/fragments/1138-hashi_vault_fix_approle_authentication_without_secret_id.yml @@ -0,0 +1,2 @@ +bugfixes: +- hashi_vault - fix approle authentication without ``secret_id`` (https://github.com/ansible-collections/community.general/pull/1138). diff --git a/plugins/lookup/hashi_vault.py b/plugins/lookup/hashi_vault.py index bb39d1c30d..a4da243a3c 100644 --- a/plugins/lookup/hashi_vault.py +++ b/plugins/lookup/hashi_vault.py @@ -588,7 +588,7 @@ class LookupModule(LookupBase): self.validate_by_required_fields(auth_method, 'username', 'password') def validate_auth_approle(self, auth_method): - self.validate_by_required_fields(auth_method, 'role_id', 'secret_id') + self.validate_by_required_fields(auth_method, 'role_id') def validate_auth_token(self, auth_method): if auth_method == 'token': diff --git a/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/approle_secret_id_less_setup.yml b/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/approle_secret_id_less_setup.yml new file mode 100644 index 0000000000..34758813ab --- /dev/null +++ b/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/approle_secret_id_less_setup.yml @@ -0,0 +1,19 @@ +- name: 'Create an approle policy' + shell: "echo '{{ policy }}' | {{ vault_cmd }} policy write approle-policy-2 -" + vars: + policy: | + path "auth/approle/login" { + capabilities = [ "create", "read" ] + } + +- name: 'Enable the AppRole auth method' + command: '{{ vault_cmd }} auth enable approle' + register: enable_approle + failed_when: "enable_approle.rc!=0 and 'path is already in use' not in enable_approle.stderr" + +- name: 'Create a named role without secret id' + command: '{{ vault_cmd }} write auth/approle/role/test-role-2 policies="test-policy,approle-policy-2" bind_secret_id=false secret_id_bound_cidrs="0.0.0.0/0"' + +- name: 'Fetch the RoleID of the AppRole' + command: '{{ vault_cmd }} read -field=role_id auth/approle/role/test-role-2/role-id' + register: role_id_cmd_2 diff --git a/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/approle_secret_id_less_test.yml b/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/approle_secret_id_less_test.yml new file mode 100644 index 0000000000..f78a12f0e0 --- /dev/null +++ b/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/approle_secret_id_less_test.yml @@ -0,0 +1,44 @@ +- vars: + role_id: '{{ role_id_cmd_2.stdout }}' + block: + - name: 'Fetch secrets using "hashi_vault" lookup' + set_fact: + secret1: "{{ lookup('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/secret1 auth_method=approle role_id=' ~ role_id) }}" + secret2: "{{ lookup('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/secret2 auth_method=approle role_id=' ~ role_id) }}" + + - name: 'Check secret values' + fail: + msg: 'unexpected secret values' + when: secret1['value'] != 'foo1' or secret2['value'] != 'foo2' + + - name: 'Failure expected when erroneous credentials are used' + vars: + secret_wrong_cred: "{{ lookup('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/secret2 auth_method=approle role_id=foobar') }}" + 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('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/secret3 auth_method=approle 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('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/non_existent_secret4 auth_method=approle 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 diff --git a/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/main.yml b/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/main.yml index bd133846f2..9d0eee1885 100644 --- a/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/main.yml +++ b/tests/integration/targets/lookup_hashi_vault/lookup_hashi_vault/tasks/main.yml @@ -146,6 +146,10 @@ import_tasks: approle_setup.yml when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>') + - name: setup approle secret_id_less auth + import_tasks: approle_secret_id_less_setup.yml + when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>') + - name: setup token auth import_tasks: token_setup.yml @@ -158,6 +162,11 @@ auth_type: approle when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>') + - import_tasks: tests.yml + vars: + auth_type: approle_secret_id_less + when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>') + - import_tasks: tests.yml vars: auth_type: token