community.docker/tests/integration/targets/docker_secret/tasks/test_secrets.yml
András Maróy b481fa4801
Add support for rotating docker secrets (#293)
* Add parameters for rolling updates to `docker_secret`

* Extract `remove_secrets` to its own function in `docker_secret`

* Store existing secrets in a list instead of a single secret

With this change `docker_secret` now supports the case where we store
multiple versions of a secret with the `_v123` postfix.

`absent` state implicitly handles removing these this way.

* When using `rolling_versions` don't automatically remove current secret

To make rolling updates actually work instead of failing on trying to
remove a secret that is attached to a service, use the
`versions_to_keep` parameter to remove old versions of the secret after
creating the new one. This way the secret with the new data is created
with a different name and can be attached to the service by its ID
without having to delete the previous one first which would fail if it
is already attached to a service.

* Add version numbers to newly created secrets

Attach the incremental version number to the secret name as a `_v123`
postfix where `123` is replaced with an incremental counter starting
from 1.
A label with the numeric version is also attached to the secret to ease
calculating the new version number upon change with the name
`ansible_version`.

* Return `secret_name` for docker secrets as well

* Add integration test for rolling secrets

* Update `docker_secret` documentation as per review comments

* Correctly return `docker_secret` version number as int

* Use template string for naming `docker_secrets` instead of concatenation

* Return the correct secret name on deletion failure

* Simplify `docker_secret` creation

* Add missing comma for `docker_secret` schema

* Only remove old docker secrets if `rolling_versions` is set

* Add check in `docker_secret` version parsing to handle NaNs

* Add newly created `docker_secret` to internal secret list to avoid additional deletions

* Add changelog fragment for `docker_secret` `rolling_versions` feature

* Update changelogs/fragments/270-rolling-secrets.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-02-12 08:29:49 +01:00

219 lines
5.0 KiB
YAML

---
- block:
- name: Make sure we're not already using Docker swarm
docker_swarm:
state: absent
force: true
- name: Create a Swarm cluster
docker_swarm:
state: present
advertise_addr: "{{ansible_default_ipv4.address}}"
- name: Parameter name should be required
docker_secret:
state: present
ignore_errors: yes
register: output
- name: assert failure when called with no name
assert:
that:
- 'output.failed'
- 'output.msg == "missing required arguments: name"'
- name: Test parameters
docker_secret:
name: foo
state: present
ignore_errors: yes
register: output
- name: assert failure when called with no data
assert:
that:
- 'output.failed'
- 'output.msg == "state is present but any of the following are missing: data, data_src"'
- name: Create secret
docker_secret:
name: db_password
data: opensesame!
state: present
register: output
- name: Create variable secret_id
set_fact:
secret_id: "{{ output.secret_id }}"
- name: Inspect secret
command: "docker secret inspect {{ secret_id }}"
register: inspect
ignore_errors: yes
- debug: var=inspect
- name: assert secret creation succeeded
assert:
that:
- "'db_password' in inspect.stdout"
- "'ansible_key' in inspect.stdout"
when: inspect is not failed
- assert:
that:
- "'is too new. Maximum supported API version is' in inspect.stderr"
when: inspect is failed
- name: Create secret again
docker_secret:
name: db_password
data: opensesame!
state: present
register: output
- name: assert create secret is idempotent
assert:
that:
- not output.changed
- name: Write secret into file
copy:
dest: "{{ remote_tmp_dir }}/data"
content: |-
opensesame!
- name: Create secret again (from file)
docker_secret:
name: db_password
data_src: "{{ remote_tmp_dir }}/data"
state: present
register: output
- name: assert create secret is idempotent
assert:
that:
- not output.changed
- name: Create secret again (base64)
docker_secret:
name: db_password
data: b3BlbnNlc2FtZSE=
data_is_b64: true
state: present
register: output
- name: assert create secret (base64) is idempotent
assert:
that:
- not output.changed
- name: Update secret
docker_secret:
name: db_password
data: newpassword!
state: present
register: output
- name: assert secret was updated
assert:
that:
- output.changed
- output.secret_id != secret_id
- name: Remove secret
docker_secret:
name: db_password
state: absent
- name: Check that secret is removed
command: "docker secret inspect {{ secret_id }}"
register: output
ignore_errors: yes
- name: assert secret was removed
assert:
that:
- output.failed
# Rolling update
- name: Create rolling secret
docker_secret:
name: rolling_password
data: opensesame!
rolling_versions: true
state: present
register: original_output
- name: Create variable secret_id
set_fact:
secret_id: "{{ original_output.secret_id }}"
- name: Inspect secret
command: "docker secret inspect {{ secret_id }}"
register: inspect
ignore_errors: yes
- debug: var=inspect
- name: assert secret creation succeeded
assert:
that:
- "'rolling_password' in inspect.stdout"
- "'ansible_key' in inspect.stdout"
- "'ansible_version' in inspect.stdout"
- original_output.secret_name == 'rolling_password_v1'
when: inspect is not failed
- assert:
that:
- "'is too new. Maximum supported API version is' in inspect.stderr"
when: inspect is failed
- name: Create secret again
docker_secret:
name: rolling_password
data: newpassword!
rolling_versions: true
state: present
register: new_output
- name: assert that new version is created
assert:
that:
- new_output.changed
- new_output.secret_id != original_output.secret_id
- new_output.secret_name != original_output.secret_name
- new_output.secret_name == 'rolling_password_v2'
- name: Remove rolling secrets
docker_secret:
name: rolling_password
rolling_versions: true
state: absent
- name: Check that secret is removed
command: "docker secret inspect {{ original_output.secret_id }}"
register: output
ignore_errors: yes
- name: assert secret was removed
assert:
that:
- output.failed
- name: Check that secret is removed
command: "docker secret inspect {{ new_output.secret_id }}"
register: output
ignore_errors: yes
- name: assert secret was removed
assert:
that:
- output.failed
always:
- name: Remove Swarm cluster
docker_swarm:
state: absent
force: true