mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-05-08 22:33:53 +00:00
openssh_cert - Adding regenerate option (#256)
* Initial commit * Fixing unit tests * More unit fixes * Adding changelog fragment * Minor refactor in Certificate.generate() * Addressing option case-sensitivity and directive overrides * Renaming idempotency to regenerate * updating changelog * Minor refactoring of default options * Cleaning up with inline functions * Fixing false failures when regenerate=fail and improving clarity * Applying second round of review suggestions * adding helper for safe atomic moves
This commit is contained in:
@@ -22,6 +22,12 @@
|
||||
- name: Import key_idempotency tests
|
||||
import_tasks: ../tests/key_idempotency.yml
|
||||
|
||||
- name: Import options tests
|
||||
import_tasks: ../tests/options_idempotency.yml
|
||||
|
||||
- name: Import regenerate tests
|
||||
import_tasks: ../tests/regenerate.yml
|
||||
|
||||
- name: Import remove tests
|
||||
import_tasks: ../tests/remove.yml
|
||||
when: not (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6")
|
||||
|
||||
@@ -177,12 +177,17 @@
|
||||
valid_from: "2001-01-21"
|
||||
valid_to: "2019-01-21"
|
||||
changed: false
|
||||
# Options are currently not checked for idempotency purposes
|
||||
- test_name: Generate an OpenSSH user Certificate with no options (idempotent)
|
||||
type: user
|
||||
valid_from: "2001-01-21"
|
||||
valid_to: "2019-01-21"
|
||||
changed: false
|
||||
- test_name: Generate an OpenSSH user Certificate with no options - full idempotency (idempotent)
|
||||
type: user
|
||||
valid_from: "2001-01-21"
|
||||
valid_to: "2019-01-21"
|
||||
regenerate: full_idempotence
|
||||
changed: true
|
||||
- test_name: Generate cert without serial
|
||||
type: user
|
||||
valid_from: always
|
||||
@@ -228,13 +233,19 @@
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
changed: false
|
||||
# Identifiers are not included in idempotency checks so a new cert will not be generated
|
||||
- test_name: Generate cert with identifier
|
||||
type: user
|
||||
identifier: foo
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
changed: false
|
||||
- test_name: Generate cert with identifier - full idempotency
|
||||
type: user
|
||||
identifier: foo
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: full_idempotence
|
||||
changed: true
|
||||
|
||||
- name: Execute idempotency tests
|
||||
openssh_cert:
|
||||
@@ -251,6 +262,7 @@
|
||||
valid_at: "{{ test_case.valid_at | default(omit) }}"
|
||||
valid_from: "{{ test_case.valid_from | default(omit) }}"
|
||||
valid_to: "{{ test_case.valid_to | default(omit) }}"
|
||||
regenerate: "{{ test_case.regenerate | default(omit) }}"
|
||||
check_mode: "{{ test_case.check_mode | default(omit) }}"
|
||||
register: idempotency_test_output
|
||||
loop: "{{ test_cases }}"
|
||||
|
||||
@@ -40,12 +40,35 @@
|
||||
valid_to: forever
|
||||
register: new_public_key_output
|
||||
|
||||
# Signing key and public key are not considered during idempotency checks
|
||||
- name: Assert changes to public key or signing key results in no change
|
||||
- name: Generate cert with new signing key - full idempotency
|
||||
openssh_cert:
|
||||
type: user
|
||||
path: "{{ certificate_path }}"
|
||||
public_key: "{{ public_key }}"
|
||||
signing_key: "{{ new_signing_key }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: full_idempotence
|
||||
register: new_signing_key_full_idempotency_output
|
||||
|
||||
- name: Generate cert with new pubic key - full idempotency
|
||||
openssh_cert:
|
||||
type: user
|
||||
path: "{{ certificate_path }}"
|
||||
public_key: "{{ new_public_key }}"
|
||||
signing_key: "{{ new_signing_key }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: full_idempotence
|
||||
register: new_public_key_full_idempotency_output
|
||||
|
||||
- name: Assert changes to public key or signing key results in no change unless idempotency=full
|
||||
assert:
|
||||
that:
|
||||
- new_signing_key_output is not changed
|
||||
- new_public_key_output is not changed
|
||||
- new_signing_key_full_idempotency_output is changed
|
||||
- new_public_key_full_idempotency_output is changed
|
||||
|
||||
- name: Remove certificate
|
||||
openssh_cert:
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- name: Generate cert with no options
|
||||
openssh_cert:
|
||||
type: user
|
||||
path: "{{ certificate_path }}"
|
||||
public_key: "{{ public_key }}"
|
||||
signing_key: "{{ signing_key }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
options:
|
||||
- clear
|
||||
regenerate: full_idempotence
|
||||
register: no_options
|
||||
|
||||
- name: Generate cert with no options with explicit directives
|
||||
openssh_cert:
|
||||
type: user
|
||||
path: "{{ certificate_path }}"
|
||||
public_key: "{{ public_key }}"
|
||||
signing_key: "{{ signing_key }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
options:
|
||||
- no-user-rc
|
||||
- no-x11-forwarding
|
||||
- no-agent-forwarding
|
||||
- no-port-forwarding
|
||||
- no-pty
|
||||
regenerate: full_idempotence
|
||||
register: no_options_explicit_directives
|
||||
|
||||
- name: Generate cert with explicit extension
|
||||
openssh_cert:
|
||||
type: user
|
||||
path: "{{ certificate_path }}"
|
||||
public_key: "{{ public_key }}"
|
||||
signing_key: "{{ signing_key }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
options:
|
||||
- clear
|
||||
- permit-pty
|
||||
regenerate: full_idempotence
|
||||
register: explicit_extension_before
|
||||
|
||||
- name: Generate cert with explicit extension (idempotency)
|
||||
openssh_cert:
|
||||
type: user
|
||||
path: "{{ certificate_path }}"
|
||||
public_key: "{{ public_key }}"
|
||||
signing_key: "{{ signing_key }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
options:
|
||||
- clear
|
||||
- permit-pty
|
||||
regenerate: full_idempotence
|
||||
register: explicit_extension_after
|
||||
|
||||
- name: Generate cert with explicit extension and corresponding directive
|
||||
openssh_cert:
|
||||
type: user
|
||||
path: "{{ certificate_path }}"
|
||||
public_key: "{{ public_key }}"
|
||||
signing_key: "{{ signing_key }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
options:
|
||||
- no-pty
|
||||
- permit-pty
|
||||
regenerate: full_idempotence
|
||||
register: explicit_extension_and_directive
|
||||
|
||||
- name: Generate cert with default options
|
||||
openssh_cert:
|
||||
type: user
|
||||
path: "{{ certificate_path }}"
|
||||
public_key: "{{ public_key }}"
|
||||
signing_key: "{{ signing_key }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: full_idempotence
|
||||
register: default_options
|
||||
|
||||
- name: Assert options results
|
||||
assert:
|
||||
that:
|
||||
- no_options is changed
|
||||
- no_options_explicit_directives is not changed
|
||||
- explicit_extension_before is changed
|
||||
- explicit_extension_after is not changed
|
||||
- explicit_extension_and_directive is changed
|
||||
- default_options is not changed
|
||||
|
||||
- name: Remove certificate
|
||||
openssh_cert:
|
||||
path: "{{ certificate_path }}"
|
||||
state: absent
|
||||
135
tests/integration/targets/openssh_cert/tests/regenerate.yml
Normal file
135
tests/integration/targets/openssh_cert/tests/regenerate.yml
Normal file
@@ -0,0 +1,135 @@
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- set_fact:
|
||||
test_cases:
|
||||
- test_name: Generate certificate
|
||||
type: user
|
||||
signing_key: "{{ signing_key }}"
|
||||
public_key: "{{ public_key }}"
|
||||
path: "{{ certificate_path }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: never
|
||||
changed: true
|
||||
- test_name: Regenerate never - same options
|
||||
type: user
|
||||
signing_key: "{{ signing_key }}"
|
||||
public_key: "{{ public_key }}"
|
||||
path: "{{ certificate_path }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: never
|
||||
changed: false
|
||||
- test_name: Regenerate never - different options
|
||||
type: user
|
||||
signing_key: "{{ signing_key }}"
|
||||
public_key: "{{ public_key }}"
|
||||
path: "{{ certificate_path }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
options:
|
||||
- clear
|
||||
regenerate: never
|
||||
changed: false
|
||||
- test_name: Regenerate never with force
|
||||
force: true
|
||||
type: user
|
||||
signing_key: "{{ signing_key }}"
|
||||
public_key: "{{ public_key }}"
|
||||
path: "{{ certificate_path }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: never
|
||||
changed: true
|
||||
- test_name: Remove certificate
|
||||
path: "{{ certificate_path }}"
|
||||
state: absent
|
||||
changed: true
|
||||
- test_name: Regenerate fail - new certificate
|
||||
type: user
|
||||
signing_key: "{{ signing_key }}"
|
||||
public_key: "{{ public_key }}"
|
||||
path: "{{ certificate_path }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: fail
|
||||
changed: true
|
||||
- test_name: Regenerate fail - same options
|
||||
type: user
|
||||
signing_key: "{{ signing_key }}"
|
||||
public_key: "{{ public_key }}"
|
||||
path: "{{ certificate_path }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: fail
|
||||
changed: false
|
||||
- test_name: Regenerate fail - different options
|
||||
type: user
|
||||
signing_key: "{{ signing_key }}"
|
||||
public_key: "{{ public_key }}"
|
||||
path: "{{ certificate_path }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
options:
|
||||
- clear
|
||||
regenerate: fail
|
||||
changed: false
|
||||
ignore_errors: true
|
||||
- test_name: Regenerate fail with force
|
||||
force: true
|
||||
type: user
|
||||
signing_key: "{{ signing_key }}"
|
||||
public_key: "{{ public_key }}"
|
||||
path: "{{ certificate_path }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: fail
|
||||
changed: true
|
||||
- test_name: Regenerate always
|
||||
type: user
|
||||
signing_key: "{{ signing_key }}"
|
||||
public_key: "{{ public_key }}"
|
||||
path: "{{ certificate_path }}"
|
||||
valid_from: always
|
||||
valid_to: forever
|
||||
regenerate: always
|
||||
changed: true
|
||||
|
||||
- name: Execute regenerate tests
|
||||
openssh_cert:
|
||||
force: "{{ test_case.force | default(omit) }}"
|
||||
options: "{{ test_case.options | default(omit) }}"
|
||||
path: "{{ test_case.path | default(omit) }}"
|
||||
public_key: "{{ test_case.public_key | default(omit) }}"
|
||||
principals: "{{ test_case.principals | default(omit) }}"
|
||||
regenerate: "{{ test_case.regenerate | default(omit) }}"
|
||||
serial_number: "{{ test_case.serial_number | default(omit) }}"
|
||||
signing_key: "{{ test_case.signing_key | default(omit) }}"
|
||||
state: "{{ test_case.state | default(omit) }}"
|
||||
type: "{{ test_case.type | default(omit) }}"
|
||||
valid_at: "{{ test_case.valid_at | default(omit) }}"
|
||||
valid_from: "{{ test_case.valid_from | default(omit) }}"
|
||||
valid_to: "{{ test_case.valid_to | default(omit) }}"
|
||||
check_mode: "{{ test_case.check_mode | default(omit) }}"
|
||||
ignore_errors: "{{ test_case.ignore_errors | default(omit) }}"
|
||||
register: regenerate_tests_output
|
||||
loop: "{{ test_cases }}"
|
||||
loop_control:
|
||||
loop_var: test_case
|
||||
|
||||
- name: Assert task statuses
|
||||
assert:
|
||||
that:
|
||||
- result.changed == test_cases[index].changed
|
||||
loop: "{{ regenerate_tests_output.results }}"
|
||||
loop_control:
|
||||
index_var: index
|
||||
loop_var: result
|
||||
|
||||
- name: Remove certificate
|
||||
openssh_cert:
|
||||
path: "{{ certificate_path }}"
|
||||
state: absent
|
||||
Reference in New Issue
Block a user