From 85ac60e2c35acf59a3470e19475549fa6f610820 Mon Sep 17 00:00:00 2001 From: Ajpantuso Date: Wed, 4 Aug 2021 15:19:32 -0400 Subject: [PATCH] openssh_keypair - integration test refactoring (#259) * Initial commit * Fixed CRLF and ed25519 handling on CentOS6 * Separated expected test results for file permissions between backends * Fixed unprotected key base directory * Fixed PEM encoded file test --- .../targets/openssh_keypair/tasks/main.yml | 27 +- .../targets/openssh_keypair/tests/core.yml | 94 +++++++ .../tests/cryptography_backend.yml | 92 +++++++ .../targets/openssh_keypair/tests/invalid.yml | 138 ++++++++++ .../targets/openssh_keypair/tests/options.yml | 110 ++++++++ .../{tasks/impl.yml => tests/regenerate.yml} | 260 ++---------------- .../targets/openssh_keypair/tests/state.yml | 45 +++ .../openssh_keypair/tests/validate.yml | 169 ------------ 8 files changed, 525 insertions(+), 410 deletions(-) create mode 100644 tests/integration/targets/openssh_keypair/tests/core.yml create mode 100644 tests/integration/targets/openssh_keypair/tests/cryptography_backend.yml create mode 100644 tests/integration/targets/openssh_keypair/tests/invalid.yml create mode 100644 tests/integration/targets/openssh_keypair/tests/options.yml rename tests/integration/targets/openssh_keypair/{tasks/impl.yml => tests/regenerate.yml} (62%) create mode 100644 tests/integration/targets/openssh_keypair/tests/state.yml delete mode 100644 tests/integration/targets/openssh_keypair/tests/validate.yml diff --git a/tests/integration/targets/openssh_keypair/tasks/main.yml b/tests/integration/targets/openssh_keypair/tasks/main.yml index b16c9235..fb467cfa 100644 --- a/tests/integration/targets/openssh_keypair/tasks/main.yml +++ b/tests/integration/targets/openssh_keypair/tasks/main.yml @@ -17,7 +17,30 @@ backends: "{{ backends + ['cryptography'] }}" when: cryptography_version.stdout is version('3.0', '>=') and bcrypt_version.stdout is version('3.1.5', '>=') -- include_tasks: ./impl.yml +- include_tasks: ../tests/core.yml loop: "{{ backends }}" loop_control: - loop_var: backend \ No newline at end of file + loop_var: backend + +- include_tasks: ../tests/invalid.yml + loop: "{{ backends }}" + loop_control: + loop_var: backend + +- include_tasks: ../tests/options.yml + loop: "{{ backends }}" + loop_control: + loop_var: backend + +- include_tasks: ../tests/regenerate.yml + loop: "{{ backends }}" + loop_control: + loop_var: backend + +- include_tasks: ../tests/state.yml + loop: "{{ backends }}" + loop_control: + loop_var: backend + +- include_tasks: ../tests/cryptography_backend.yml + when: cryptography_version.stdout is version('3.0', '>=') and bcrypt_version.stdout is version('3.1.5', '>=') diff --git a/tests/integration/targets/openssh_keypair/tests/core.yml b/tests/integration/targets/openssh_keypair/tests/core.yml new file mode 100644 index 00000000..4bedea85 --- /dev/null +++ b/tests/integration/targets/openssh_keypair/tests/core.yml @@ -0,0 +1,94 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +- name: "({{ backend }}) Generate key (check mode)" + openssh_keypair: + path: "{{ output_dir }}/core" + size: 2048 + backend: "{{ backend }}" + register: check_core_output + check_mode: true + +- name: "({{ backend }}) Generate key" + openssh_keypair: + path: "{{ output_dir }}/core" + size: 2048 + backend: "{{ backend }}" + register: core_output + +- name: "({{ backend }}) Generate key (check mode idempotent)" + openssh_keypair: + path: "{{ output_dir }}/core" + size: 2048 + backend: "{{ backend }}" + register: idempotency_check_core_output + check_mode: true + +- name: "({{ backend }}) Generate key (idempotent)" + openssh_keypair: + path: '{{ output_dir }}/core' + size: 2048 + backend: "{{ backend }}" + register: idempotency_core_output + +- name: "({{ backend }}) Log key return values" + debug: + msg: "{{ core_output }}" + +- name: "({{ backend }}) Assert core behavior" + assert: + that: + - check_core_output is changed + - core_output is changed + - idempotency_check_core_output is not changed + - idempotency_check_core_output.public_key.startswith('ssh-rsa') + - idempotency_core_output is not changed + +- name: "({{ backend }}) Assert key returns fingerprint" + assert: + that: + - core_output['fingerprint'] is string + - core_output['fingerprint'].startswith('SHA256:') + # only distro old enough that it still gives md5 with no prefix + when: not (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6') + +- name: "({{ backend }}) Assert key returns public_key" + assert: + that: + - core_output['public_key'] is string + - core_output['public_key'].startswith('ssh-rsa ') + +- name: "({{ backend }}) Assert key returns size value" + assert: + that: + - core_output['size']|type_debug == 'int' + - core_output['size'] == 2048 + +- name: "({{ backend }}) Assert key returns key type" + assert: + that: + - core_output['type'] is string + - core_output['type'] == 'rsa' + +- name: "({{ backend }}) Retrieve key size from 'ssh-keygen'" + shell: "ssh-keygen -lf {{ output_dir }}/core | grep -o -E '^[0-9]+'" + register: core_size_ssh_keygen + +- name: "({{ backend }}) Assert key size matches 'ssh-keygen' output" + assert: + that: + - core_size_ssh_keygen.stdout == '2048' + +- name: "({{ backend }}) Assert public key module return equal to the public key content" + assert: + that: + - "core_output.public_key == lookup('file', output_dir ~ '/core.pub').strip('\n')" + +- name: "({{ backend }}) Remove key" + openssh_keypair: + path: '{{ output_dir }}/core' + backend: "{{ backend }}" + state: absent diff --git a/tests/integration/targets/openssh_keypair/tests/cryptography_backend.yml b/tests/integration/targets/openssh_keypair/tests/cryptography_backend.yml new file mode 100644 index 00000000..a0bd2f4a --- /dev/null +++ b/tests/integration/targets/openssh_keypair/tests/cryptography_backend.yml @@ -0,0 +1,92 @@ +--- +- name: Generate a password protected key + command: 'ssh-keygen -f {{ output_dir }}/password_protected -N {{ passphrase }}' + +- name: Modify the password protected key with passphrase + openssh_keypair: + path: '{{ output_dir }}/password_protected' + size: 1024 + passphrase: "{{ passphrase }}" + backend: cryptography + register: password_protected_output + +- name: Check password protected key idempotency + openssh_keypair: + path: '{{ output_dir }}/password_protected' + size: 1024 + passphrase: "{{ passphrase }}" + backend: cryptography + register: password_protected_idempotency_output + +- name: Ensure that ssh-keygen can read keys generated with passphrase + command: 'ssh-keygen -yf {{ output_dir }}/password_protected -P {{ passphrase }}' + register: password_protected_ssh_keygen_output + +- name: Check that password protected key with passphrase was regenerated + assert: + that: + - password_protected_output is changed + - password_protected_idempotency_output is not changed + - password_protected_ssh_keygen_output is success + +- name: Remove password protected key + openssh_keypair: + path: '{{ output_dir }}/password_protected' + backend: cryptography + state: absent + +- name: Generate an unprotected key + openssh_keypair: + path: '{{ output_dir }}/unprotected' + backend: cryptography + +- name: Modify unprotected key with passphrase + openssh_keypair: + path: '{{ output_dir }}/unprotected' + size: 2048 + passphrase: "{{ passphrase }}" + backend: cryptography + ignore_errors: true + register: unprotected_modification_output + +- name: Modify unprotected key with passphrase (force) + openssh_keypair: + path: '{{ output_dir }}/unprotected' + size: 2048 + passphrase: "{{ passphrase }}" + force: true + backend: cryptography + register: force_unprotected_modification_output + +- name: Check that unprotected key was modified + assert: + that: + - unprotected_modification_output is failed + - force_unprotected_modification_output is changed + +- name: Remove unprotected key + openssh_keypair: + path: '{{ output_dir }}/unprotected' + backend: cryptography + state: absent + +- name: Generate PEM encoded key with passphrase + command: 'ssh-keygen -b 4096 -f {{ output_dir }}/pem_encoded -N {{ passphrase }} -m PEM' + +- name: Try to verify a PEM encoded key + openssh_keypair: + path: '{{ output_dir }}/pem_encoded' + passphrase: "{{ passphrase }}" + backend: cryptography + register: pem_encoded_output + +- name: Check that PEM encoded file is read without errors + assert: + that: + - pem_encoded_output is not changed + +- name: Remove PEM encoded key + openssh_keypair: + path: '{{ output_dir }}/pem_encoded' + backend: cryptography + state: absent diff --git a/tests/integration/targets/openssh_keypair/tests/invalid.yml b/tests/integration/targets/openssh_keypair/tests/invalid.yml new file mode 100644 index 00000000..a2ed9744 --- /dev/null +++ b/tests/integration/targets/openssh_keypair/tests/invalid.yml @@ -0,0 +1,138 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +- name: "({{ backend }}) Generate key - broken" + copy: + dest: '{{ item }}' + content: '' + mode: '0700' + loop: + - "{{ output_dir }}/broken" + - "{{ output_dir }}/broken.pub" + +- name: "({{ backend }}) Regenerate key - broken" + openssh_keypair: + path: "{{ output_dir }}/broken" + backend: "{{ backend }}" + register: broken_output + ignore_errors: true + +- name: "({{ backend }}) Assert broken key causes failure - broken" + assert: + that: + - broken_output is failed + - "'Unable to read the key. The key is protected with a passphrase or broken.' in broken_output.msg" + +- name: "({{ backend }}) Regenerate key with force - broken" + openssh_keypair: + path: "{{ output_dir }}/broken" + backend: "{{ backend }}" + force: true + register: force_broken_output + +- name: "({{ backend }}) Assert broken key regenerated when 'force=true' - broken" + assert: + that: + - force_broken_output is changed + +- name: "({{ backend }}) Remove key - broken" + openssh_keypair: + path: "{{ output_dir }}/broken" + backend: "{{ backend }}" + state: absent + +- name: "({{ backend }}) Generate key - write-only" + openssh_keypair: + path: "{{ output_dir }}/write-only" + mode: "0200" + backend: "{{ backend }}" + +- name: "({{ backend }}) Check private key status - write-only" + stat: + path: '{{ output_dir }}/write-only' + register: write_only_private_key + +- name: "({{ backend }}) Check public key status - write-only" + stat: + path: '{{ output_dir }}/write-only.pub' + register: write_only_public_key + +- name: "({{ backend }}) Assert that private and public keys match permissions - write-only" + assert: + that: + - write_only_private_key.stat.mode == '0200' + - write_only_public_key.stat.mode == '0200' + +- name: "({{ backend }}) Regenerate key with force - write-only" + openssh_keypair: + path: "{{ output_dir }}/write-only" + backend: "{{ backend }}" + force: true + register: write_only_output + +- name: "({{ backend }}) Check private key status after regeneration - write-only" + stat: + path: '{{ output_dir }}/write-only' + register: write_only_private_key_after + +- name: "({{ backend }}) Assert key is regenerated - write-only" + assert: + that: + - write_only_output is changed + +- name: "({{ backend }}) Assert key permissions are preserved with 'opensshbin'" + assert: + that: + - write_only_private_key_after.stat.mode == '0200' + when: backend == 'opensshbin' + +- name: "({{ backend }}) Assert key permissions are not preserved with 'cryptography'" + assert: + that: + - write_only_private_key_after.stat.mode == '0600' + when: backend == 'cryptography' + +- name: "({{ backend }}) Remove key - write-only" + openssh_keypair: + path: "{{ output_dir }}/write-only" + backend: "{{ backend }}" + state: absent + +- name: "({{ backend }}) Generate key with ssh-keygen - password_protected" + command: "ssh-keygen -f {{ output_dir }}/password_protected -N {{ passphrase }}" + +- name: "({{ backend }}) Modify key - password_protected" + openssh_keypair: + path: "{{ output_dir }}/password_protected" + size: 2048 + backend: "{{ backend }}" + register: password_protected_output + ignore_errors: true + +- name: "({{ backend }}) Assert key cannot be read - password_protected" + assert: + that: + - password_protected_output is failed + - "'Unable to read the key. The key is protected with a passphrase or broken.' in password_protected_output.msg" + +- name: "({{ backend }}) Modify key with 'force=true' - password_protected" + openssh_keypair: + path: "{{ output_dir }}/password_protected" + size: 2048 + backend: "{{ backend }}" + force: true + register: force_password_protected_output + +- name: "({{ backend }}) Assert key regenerated with 'force=true' - password_protected" + assert: + that: + - force_password_protected_output is changed + +- name: "({{ backend }}) Remove key - password_protected" + openssh_keypair: + path: "{{ output_dir }}/password_protected" + backend: "{{ backend }}" + state: absent diff --git a/tests/integration/targets/openssh_keypair/tests/options.yml b/tests/integration/targets/openssh_keypair/tests/options.yml new file mode 100644 index 00000000..f6d83651 --- /dev/null +++ b/tests/integration/targets/openssh_keypair/tests/options.yml @@ -0,0 +1,110 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +- set_fact: + key_types: + - rsa + - dsa + - ecdsa + +- name: "({{ backend }}) Generate keys with default size - size" + openssh_keypair: + path: "{{ output_dir }}/default_size_{{ item }}" + type: "{{ item }}" + backend: "{{ backend }}" + loop: "{{ key_types }}" + +- name: "({{ backend }}) Retrieve key size from 'ssh-keygen' - size" + shell: "ssh-keygen -lf {{ output_dir }}/default_size_{{ item }} | grep -o -E '^[0-9]+'" + loop: "{{ key_types }}" + register: key_size_output + +- name: "({{ backend }}) Assert key sizes match default size - size" + assert: + that: + - key_size_output.results[0].stdout == '4096' + - key_size_output.results[1].stdout == '1024' + - key_size_output.results[2].stdout == '256' + +- name: "({{ backend }}) Remove keys - size" + openssh_keypair: + path: "{{ output_dir }}/default_size_{{ item }}" + state: absent + loop: "{{ key_types }}" + +- block: + - name: "({{ backend }}) Generate ed25519 key with default size - size" + openssh_keypair: + path: "{{ output_dir }}/default_size_ed25519" + type: ed25519 + backend: "{{ backend }}" + + - name: "({{ backend }}) Retrieve ed25519 key size from 'ssh-keygen' - size" + shell: "ssh-keygen -lf {{ output_dir }}/default_size_ed25519 | grep -o -E '^[0-9]+'" + register: ed25519_key_size_output + + - name: "({{ backend }}) Assert ed25519 key size matches default size - size" + assert: + that: + - ed25519_key_size_output.stdout == '256' + + - name: "({{ backend }}) Remove ed25519 key - size" + openssh_keypair: + path: "{{ output_dir }}/default_size_ed25519" + state: absent + when: not (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6') + +- name: "({{ backend }}) Generate key - force" + openssh_keypair: + path: "{{ output_dir }}/force" + type: rsa + backend: "{{ backend }}" + +- name: "({{ backend }}) Regenerate key - force" + openssh_keypair: + path: "{{ output_dir }}/force" + type: rsa + force: true + backend: "{{ backend }}" + register: force_output + +- name: "({{ backend }}) Assert key regenerated - force" + assert: + that: + - force_output is changed + +- name: "({{ backend }}) Remove key - force" + openssh_keypair: + path: "{{ output_dir }}/force" + state: absent + backend: "{{ backend }}" + +- name: "({{ backend }}) Generate key - comment" + openssh_keypair: + path: "{{ output_dir }}/comment" + comment: "test@comment" + backend: "{{ backend }}" + register: comment_output + +- name: "({{ backend }}) Modify comment - comment" + openssh_keypair: + path: "{{ output_dir }}/comment" + comment: "test_modified@comment" + backend: "{{ backend }}" + register: modified_comment_output + +- name: "({{ backend }}) Assert only comment changed - comment" + assert: + that: + - comment_output.public_key == modified_comment_output.public_key + - comment_output.comment == 'test@comment' + - modified_comment_output.comment == 'test_modified@comment' + +- name: "({{ backend }}) Remove key - comment" + openssh_keypair: + path: "{{ output_dir }}/comment" + state: absent + backend: "{{ backend }}" diff --git a/tests/integration/targets/openssh_keypair/tasks/impl.yml b/tests/integration/targets/openssh_keypair/tests/regenerate.yml similarity index 62% rename from tests/integration/targets/openssh_keypair/tasks/impl.yml rename to tests/integration/targets/openssh_keypair/tests/regenerate.yml index c1d27b7c..6f7b4681 100644 --- a/tests/integration/targets/openssh_keypair/tasks/impl.yml +++ b/tests/integration/targets/openssh_keypair/tests/regenerate.yml @@ -4,232 +4,14 @@ # and should not be used as examples of how to write Ansible roles # #################################################################### - # Ensures no conflicts from previous test runs +# Ensures no conflicts from previous test runs - name: "({{ backend }}) Cleanup Output Directory" ansible.builtin.file: path: "{{ item }}" state: absent with_fileglob: - - "{{ output_dir }}/privatekey*" - "{{ output_dir }}/regenerate*" -- name: "({{ backend }}) Generate privatekey1 - standard (check mode)" - openssh_keypair: - path: '{{ output_dir }}/privatekey1' - size: 2048 - backend: "{{ backend }}" - register: privatekey1_result_check - check_mode: true - -- name: "({{ backend }}) Generate privatekey1 - standard" - openssh_keypair: - path: '{{ output_dir }}/privatekey1' - size: 2048 - backend: "{{ backend }}" - register: privatekey1_result - -- name: "({{ backend }}) Generate privatekey1 - standard (check mode idempotent)" - openssh_keypair: - path: '{{ output_dir }}/privatekey1' - size: 2048 - backend: "{{ backend }}" - register: privatekey1_idem_result_check - check_mode: true - -- name: "({{ backend }}) Generate privatekey1 - standard (idempotent)" - openssh_keypair: - path: '{{ output_dir }}/privatekey1' - size: 2048 - backend: "{{ backend }}" - register: privatekey1_idem_result - -- name: "({{ backend }}) Generate privatekey2 - default size" - openssh_keypair: - path: '{{ output_dir }}/privatekey2' - backend: "{{ backend }}" - -- name: "({{ backend }}) Generate privatekey3 - type dsa" - openssh_keypair: - path: '{{ output_dir }}/privatekey3' - type: dsa - backend: "{{ backend }}" - -- name: "({{ backend }}) Generate privatekey4 - standard" - openssh_keypair: - path: '{{ output_dir }}/privatekey4' - size: 2048 - backend: "{{ backend }}" - -- name: "({{ backend }}) Delete privatekey4 - standard" - openssh_keypair: - state: absent - path: '{{ output_dir }}/privatekey4' - backend: "{{ backend }}" - -- name: "({{ backend }}) Generate privatekey5 - standard" - openssh_keypair: - path: '{{ output_dir }}/privatekey5' - size: 2048 - backend: "{{ backend }}" - register: publickey_gen - -- name: "({{ backend }}) Generate privatekey6" - openssh_keypair: - path: '{{ output_dir }}/privatekey6' - type: rsa - size: 2048 - backend: "{{ backend }}" - -- name: "({{ backend }}) Regenerate privatekey6 via force" - openssh_keypair: - path: '{{ output_dir }}/privatekey6' - type: rsa - size: 2048 - force: yes - backend: "{{ backend }}" - register: output_regenerated_via_force - -- name: "({{ backend }}) Create broken key" - copy: - dest: '{{ item }}' - content: '' - mode: '0700' - loop: - - '{{ output_dir }}/privatekeybroken' - - '{{ output_dir }}/privatekeybroken.pub' - -- name: "({{ backend }}) Regenerate broken key - should fail" - openssh_keypair: - path: '{{ output_dir }}/privatekeybroken' - type: rsa - size: 2048 - backend: "{{ backend }}" - register: output_broken - ignore_errors: yes - -- name: "({{ backend }}) Regenerate broken key with force" - openssh_keypair: - path: '{{ output_dir }}/privatekeybroken' - type: rsa - force: yes - size: 2048 - backend: "{{ backend }}" - register: output_broken_force - -- name: "({{ backend }}) Generate read-only private key" - openssh_keypair: - path: '{{ output_dir }}/privatekeyreadonly' - type: rsa - mode: '0200' - size: 2048 - backend: "{{ backend }}" - -- name: "({{ backend }}) Regenerate read-only private key via force" - openssh_keypair: - path: '{{ output_dir }}/privatekeyreadonly' - type: rsa - force: yes - size: 2048 - backend: "{{ backend }}" - register: output_read_only - -- name: "({{ backend }}) Generate privatekey7 - standard with comment" - openssh_keypair: - path: '{{ output_dir }}/privatekey7' - comment: 'test@privatekey7' - size: 2048 - backend: "{{ backend }}" - register: privatekey7_result - -- name: "({{ backend }}) Modify privatekey7 comment" - openssh_keypair: - path: '{{ output_dir }}/privatekey7' - comment: 'test_modified@privatekey7' - size: 2048 - backend: "{{ backend }}" - register: privatekey7_modified_result - -- name: "({{ backend }}) Generate password protected key" - command: 'ssh-keygen -f {{ output_dir }}/privatekey8 -N {{ passphrase }}' - -- name: "({{ backend }}) Try to modify the password protected key - should fail" - openssh_keypair: - path: '{{ output_dir }}/privatekey8' - size: 2048 - backend: "{{ backend }}" - register: privatekey8_result - ignore_errors: yes - -- name: "({{ backend }}) Try to modify the password protected key with force=yes" - openssh_keypair: - path: '{{ output_dir }}/privatekey8' - force: yes - size: 2048 - backend: "{{ backend }}" - register: privatekey8_result_force - -- name: "({{ backend }}) Generate another password protected key" - command: 'ssh-keygen -f {{ output_dir }}/privatekey9 -N {{ passphrase }}' - -- name: "({{ backend }}) Try to modify the password protected key with passphrase" - openssh_keypair: - path: '{{ output_dir }}/privatekey9' - size: 1024 - passphrase: "{{ passphrase }}" - backend: "{{ backend }}" - register: privatekey9_modified_result - when: backend == 'cryptography' - -- name: "({{ backend }}) Generate another unprotected key" - openssh_keypair: - path: '{{ output_dir }}/privatekey10' - size: 2048 - backend: "{{ backend }}" - -- name: "({{ backend }}) Try to Modify unprotected key with passphrase" - openssh_keypair: - path: '{{ output_dir }}/privatekey10' - size: 2048 - passphrase: "{{ passphrase }}" - backend: "{{ backend }}" - ignore_errors: true - register: privatekey10_result - when: backend == 'cryptography' - - -- name: "({{ backend }}) Try to force modify the password protected key with force=true" - openssh_keypair: - path: '{{ output_dir }}/privatekey10' - size: 2048 - passphrase: "{{ passphrase }}" - force: true - backend: "{{ backend }}" - register: privatekey10_result_force - when: backend == 'cryptography' - -- name: "({{ backend }}) Ensure that ssh-keygen can read keys generated with passphrase" - command: 'ssh-keygen -yf {{ output_dir }}/privatekey10 -P {{ passphrase }}' - register: privatekey10_result_sshkeygen - when: backend == 'cryptography' - -- name: "({{ backend }}) Generate PEM encoded key with passphrase" - command: 'ssh-keygen -f {{ output_dir }}/privatekey11 -N {{ passphrase }} -m PEM' - when: backend == 'cryptography' - -- name: "({{ backend }}) Try to verify a PEM encoded key" - openssh_keypair: - path: '{{ output_dir }}/privatekey11' - size: 2048 - passphrase: "{{ passphrase }}" - backend: "{{ backend }}" - register: privatekey11_result - when: backend == 'cryptography' - -- import_tasks: ../tests/validate.yml - - -# Test regenerate option - - name: "({{ backend }}) Regenerate - setup simple keys" openssh_keypair: path: '{{ output_dir }}/regenerate-a-{{ item }}' @@ -249,7 +31,7 @@ with_nested: - "{{ regenerate_values }}" - [ '', '.pub' ] - - + - name: "({{ backend }}) Regenerate - setup password protected keys for passphrse test" command: 'ssh-keygen -f {{ output_dir }}/regenerate-d-{{ item }} -N {{ passphrase }}' loop: "{{ regenerate_values }}" @@ -261,9 +43,9 @@ size: 1024 regenerate: '{{ item }}' backend: "{{ backend }}" - check_mode: yes + check_mode: true loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result - assert: that: @@ -284,7 +66,7 @@ regenerate: '{{ item }}' backend: "{{ backend }}" loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result - assert: that: @@ -304,9 +86,9 @@ size: 1024 regenerate: '{{ item }}' backend: "{{ backend }}" - check_mode: yes + check_mode: true loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result - assert: that: @@ -327,9 +109,9 @@ passphrase: "{{ passphrase }}" regenerate: '{{ item }}' backend: "{{ backend }}" - check_mode: yes + check_mode: true loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result when: backend == 'cryptography' @@ -351,7 +133,7 @@ regenerate: '{{ item }}' backend: "{{ backend }}" loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result - assert: that: @@ -373,7 +155,7 @@ regenerate: '{{ item }}' backend: "{{ backend }}" loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result when: backend == 'cryptography' @@ -394,7 +176,7 @@ size: 1024 regenerate: '{{ item }}' backend: "{{ backend }}" - check_mode: yes + check_mode: true loop: "{{ regenerate_values }}" register: result - assert: @@ -429,9 +211,9 @@ size: 1048 regenerate: '{{ item }}' backend: "{{ backend }}" - check_mode: yes + check_mode: true loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result - assert: that: @@ -450,7 +232,7 @@ regenerate: '{{ item }}' backend: "{{ backend }}" loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result - assert: that: @@ -478,9 +260,9 @@ size: 1024 regenerate: '{{ item }}' backend: "{{ backend }}" - check_mode: yes + check_mode: true loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result - assert: that: @@ -499,7 +281,7 @@ regenerate: '{{ item }}' backend: "{{ backend }}" loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result - assert: that: @@ -528,9 +310,9 @@ comment: test comment regenerate: '{{ item }}' backend: "{{ backend }}" - check_mode: yes + check_mode: true loop: "{{ regenerate_values }}" - ignore_errors: yes + ignore_errors: true register: result - assert: that: @@ -549,7 +331,7 @@ - assert: that: - result is changed - # for all values but 'always', the key should have not been regenerated. + # for all values but 'always', the key should not be regenerated. # verify this by comparing fingerprints: - result.results[0].fingerprint == result.results[1].fingerprint - result.results[0].fingerprint == result.results[2].fingerprint diff --git a/tests/integration/targets/openssh_keypair/tests/state.yml b/tests/integration/targets/openssh_keypair/tests/state.yml new file mode 100644 index 00000000..c984dbef --- /dev/null +++ b/tests/integration/targets/openssh_keypair/tests/state.yml @@ -0,0 +1,45 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +- name: "({{ backend }}) Generate key" + openssh_keypair: + path: '{{ output_dir }}/removed' + backend: "{{ backend }}" + state: present + +- name: "({{ backend }}) Generate key (idempotency)" + openssh_keypair: + path: '{{ output_dir }}/removed' + backend: "{{ backend }}" + state: present + +- name: "({{ backend }}) Remove key" + openssh_keypair: + state: absent + path: '{{ output_dir }}/removed' + backend: "{{ backend }}" + +- name: "({{ backend }}) Remove key (idempotency)" + openssh_keypair: + state: absent + path: '{{ output_dir }}/removed' + backend: "{{ backend }}" + +- name: "({{ backend }}) Check private key status" + stat: + path: '{{ output_dir }}/removed' + register: removed_private_key + +- name: "({{ backend }}) Check public key status" + stat: + path: '{{ output_dir }}/removed.pub' + register: removed_public_key + +- name: "({{ backend }}) Assert key pair files are removed" + assert: + that: + - not removed_private_key.stat.exists + - not removed_public_key.stat.exists diff --git a/tests/integration/targets/openssh_keypair/tests/validate.yml b/tests/integration/targets/openssh_keypair/tests/validate.yml deleted file mode 100644 index 4a61019f..00000000 --- a/tests/integration/targets/openssh_keypair/tests/validate.yml +++ /dev/null @@ -1,169 +0,0 @@ ---- -- name: "({{ backend }}) Log privatekey1 return values" - debug: - var: privatekey1_result - -- name: "({{ backend }}) Validate general behavior" - assert: - that: - - privatekey1_result_check is changed - - privatekey1_result is changed - - privatekey1_idem_result_check is not changed - - privatekey1_idem_result_check.public_key.startswith("ssh-rsa") - - privatekey1_idem_result is not changed - -- name: "({{ backend }}) Validate privatekey1 return fingerprint" - assert: - that: - - privatekey1_result["fingerprint"] is string - - privatekey1_result["fingerprint"].startswith("SHA256:") - # only distro old enough that it still gives md5 with no prefix - when: ansible_distribution != 'CentOS' and ansible_distribution_major_version != '6' - -- name: "({{ backend }}) Validate privatekey1 return public_key" - assert: - that: - - privatekey1_result["public_key"] is string - - privatekey1_result["public_key"].startswith("ssh-rsa ") - -- name: "({{ backend }}) Validate privatekey1 return size value" - assert: - that: - - privatekey1_result["size"]|type_debug == 'int' - - privatekey1_result["size"] == 2048 - -- name: "({{ backend }}) Validate privatekey1 return key type" - assert: - that: - - privatekey1_result["type"] is string - - privatekey1_result["type"] == "rsa" - -- name: "({{ backend }}) Validate privatekey1 (test - RSA key with size 2048 bits)" - shell: "ssh-keygen -lf {{ output_dir }}/privatekey1 | grep -o -E '^[0-9]+'" - register: privatekey1 - -- name: "({{ backend }}) Validate privatekey1 (assert - RSA key with size 2048 bits)" - assert: - that: - - privatekey1.stdout == '2048' - -- name: "({{ backend }}) Validate privatekey1 idempotence" - assert: - that: - - privatekey1_idem_result is not changed - - -- name: "({{ backend }}) Validate privatekey2 (test - RSA key with default size 4096 bits)" - shell: "ssh-keygen -lf {{ output_dir }}/privatekey2 | grep -o -E '^[0-9]+'" - register: privatekey2 - -- name: "({{ backend }}) Validate privatekey2 (assert - RSA key with size 4096 bits)" - assert: - that: - - privatekey2.stdout == '4096' - - -- name: "({{ backend }}) Validate privatekey3 (test - DSA key with size 1024 bits)" - shell: "ssh-keygen -lf {{ output_dir }}/privatekey3 | grep -o -E '^[0-9]+'" - register: privatekey3 - -- name: "({{ backend }}) Validate privatekey3 (assert - DSA key with size 4096 bits)" - assert: - that: - - privatekey3.stdout == '1024' - - -- name: "({{ backend }}) Validate privatekey4 (test - Ensure key has been removed)" - stat: - path: '{{ output_dir }}/privatekey4' - register: privatekey4 - -- name: "({{ backend }}) Validate privatekey4 (assert - Ensure key has been removed)" - assert: - that: - - privatekey4.stat.exists == False - - -- name: "({{ backend }}) Validate privatekey5 (assert - Public key module output equal to the public key on host)" - assert: - that: - - "publickey_gen.public_key == lookup('file', output_dir ~ '/privatekey5.pub').strip('\n')" - -- name: "({{ backend }}) Verify that privatekey6 will be regenerated via force" - assert: - that: - - output_regenerated_via_force is changed - - -- name: "({{ backend }}) Verify that broken key will cause failure" - assert: - that: - - output_broken is failed - - "'Unable to read the key. The key is protected with a passphrase or broken.' in output_broken.msg" - - -- name: "({{ backend }}) Verify that broken key will be regenerated if force=yes is specified" - assert: - that: - - output_broken_force is changed - - -- name: "({{ backend }}) Verify that read-only key will be regenerated" - assert: - that: - - output_read_only is changed - - -- name: "({{ backend }}) Validate privatekey7 (assert - Public key remains the same after comment change)" - assert: - that: - - privatekey7_result.public_key == privatekey7_modified_result.public_key - -- name: "({{ backend }}) Validate privatekey7 comment on creation" - assert: - that: - - privatekey7_result.comment == 'test@privatekey7' - -- name: "({{ backend }}) Validate privatekey7 comment update" - assert: - that: - - privatekey7_modified_result.comment == 'test_modified@privatekey7' - -- name: "({{ backend }}) Check that password protected key made module fail" - assert: - that: - - privatekey8_result is failed - - "'Unable to read the key. The key is protected with a passphrase or broken.' in privatekey8_result.msg" - -- name: "({{ backend }}) Check that password protected key was regenerated with force=yes" - assert: - that: - - privatekey8_result_force is changed - -- block: - - name: "({{ backend }}) Check that password protected key with passphrase was regenerated" - assert: - that: - - privatekey9_modified_result is changed - - - name: "({{ backend }}) Check that modifying unprotected key with passphrase fails" - assert: - that: - - privatekey10_result is failed - - "'Unable to read the key. The key is protected with a passphrase or broken.' in privatekey8_result.msg" - - - name: "({{ backend }}) Check that unprotected key was regenerated with force=yes and passphrase supplied" - assert: - that: - - privatekey10_result_force is changed - - - name: "({{ backend }}) Check that ssh-keygen output from passphrase protected key matches openssh_keypair" - assert: - that: - - privatekey10_result_force.public_key == privatekey10_result_sshkeygen.stdout - - - name: "({{ backend }}) Check that PEM encoded private keys are loaded successfully" - assert: - that: - - privatekey11_result is success - when: backend == 'cryptography'