Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions hooks/playbooks/barbican-secret-store-migrate/admin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
# Run barbican-secret-migrate in the API pod.
#
# That image has the admin CLI; openstackclient does not. The API pod is
# not logged in as project admin, so pass a token issued from
# openstackclient plus Keystone and Key Manager URLs.

- name: "Run barbican-secret-migrate ({{ cifmw_barbican_migrate_case }})"
when: not (cifmw_barbican_migrate_admin_dry_run | default(false) | bool)
ansible.builtin.command:
argv:
- oc
- -n
- "{{ cifmw_barbican_migrate_namespace }}"
- exec
- "{{ cifmw_barbican_migrate_api_pod }}"
- -c
- "{{ cifmw_barbican_migrate_api_container }}"
- --
- barbican-secret-migrate
- --os-auth-type
- v3token
- --os-token
- "{{ _os_token }}"
- --os-auth-url
- "{{ cifmw_barbican_migrate_keystone }}"
- --os-endpoint-override
- "{{ cifmw_barbican_migrate_v1 }}"
- --os-project-id
- "{{ _os_project_id }}"
- --secret-store-id
- "{{ cifmw_barbican_migrate_admin_store_id }}"
- --secret-id
- "{{ cifmw_barbican_migrate_admin_secret_id }}"
- --error-file
- /tmp/cifmw-barbican-secret-migrate-errors.jsonl
register: _migrate_admin
changed_when: false

- name: "Dry-run barbican-secret-migrate ({{ cifmw_barbican_migrate_case }})"
when: cifmw_barbican_migrate_admin_dry_run | default(false) | bool
ansible.builtin.command:
argv:
- oc
- -n
- "{{ cifmw_barbican_migrate_namespace }}"
- exec
- "{{ cifmw_barbican_migrate_api_pod }}"
- -c
- "{{ cifmw_barbican_migrate_api_container }}"
- --
- barbican-secret-migrate
- --os-auth-type
- v3token
- --os-token
- "{{ _os_token }}"
- --os-auth-url
- "{{ cifmw_barbican_migrate_keystone }}"
- --os-endpoint-override
- "{{ cifmw_barbican_migrate_v1 }}"
- --os-project-id
- "{{ _os_project_id }}"
- --secret-store-id
- "{{ cifmw_barbican_migrate_admin_store_id }}"
- --secret-id
- "{{ cifmw_barbican_migrate_admin_secret_id }}"
- --error-file
- /tmp/cifmw-barbican-secret-migrate-errors.jsonl
- --dry-run
register: _migrate_admin_dry
changed_when: false
93 changes: 93 additions & 0 deletions hooks/playbooks/barbican-secret-store-migrate/assert.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
# Assert a secret is on the expected Barbican backend.
#
# store_crypto (simple_crypto / p11_crypto): ciphertext is in encrypted_data;
# kek_data.plugin_name is the crypto plugin FQCN.
#
# KMIP and other secret-store plugins: payload is outside MariaDB;
# secret_store_metadata.plugin_name is the store plugin FQCN and there is
# no active encrypted_data row.
#
# Expects:
# cifmw_barbican_migrate_assert_label
# cifmw_barbican_migrate_assert_secret_id
# cifmw_barbican_migrate_assert_store (id, store_plugin, crypto_plugin)

- name: "{{ cifmw_barbican_migrate_assert_label }}: resolve expected backend"
ansible.builtin.set_fact:
_assert_is_store_crypto: "{{ _store.store_plugin == 'store_crypto' or _store.crypto_plugin in ['simple_crypto', 'p11_crypto'] }}"
_assert_expected_fqcn: "{{ _crypto_fqcn if (_store.store_plugin == 'store_crypto' or _store.crypto_plugin in ['simple_crypto', 'p11_crypto']) else _store_fqcn }}"
vars:
_store: "{{ cifmw_barbican_migrate_assert_store }}"
_crypto_fqcn: "{{ cifmw_barbican_migrate_crypto_fqcns[_store.crypto_plugin] | default('') }}"
_store_fqcn: "{{ cifmw_barbican_migrate_store_fqcns[_store.store_plugin] | default('') }}"

- name: "{{ cifmw_barbican_migrate_assert_label }}: require a known plugin FQCN"
ansible.builtin.assert:
that:
- _assert_expected_fqcn | length > 0
fail_msg: >-
{{ cifmw_barbican_migrate_assert_label }}: no FQCN mapping for
store_plugin={{ cifmw_barbican_migrate_assert_store.store_plugin }}
crypto_plugin={{ cifmw_barbican_migrate_assert_store.crypto_plugin }}.

- name: "{{ cifmw_barbican_migrate_assert_label }}: verify store_crypto backend"
when: _assert_is_store_crypto | bool
block:
- name: "{{ cifmw_barbican_migrate_assert_label }}: read kek_data.plugin_name"
ansible.builtin.include_tasks: sql.yml
vars:
cifmw_barbican_migrate_sql_desc: "{{ cifmw_barbican_migrate_assert_label }} kek plugin_name"
cifmw_barbican_migrate_sql: >-
SELECT k.plugin_name FROM encrypted_data e
JOIN kek_data k ON e.kek_id = k.id
WHERE e.secret_id='{{ cifmw_barbican_migrate_assert_secret_id }}'
AND e.deleted=0;

- name: "{{ cifmw_barbican_migrate_assert_label }}: assert kek_data.plugin_name"
ansible.builtin.assert:
that:
- cifmw_barbican_migrate_sql_result.stdout | trim == _assert_expected_fqcn
fail_msg: >-
{{ cifmw_barbican_migrate_assert_label }}: expected kek_data.plugin_name
'{{ _assert_expected_fqcn }}' for crypto_plugin
'{{ cifmw_barbican_migrate_assert_store.crypto_plugin }}', got
'{{ cifmw_barbican_migrate_sql_result.stdout | trim }}'.

- name: "{{ cifmw_barbican_migrate_assert_label }}: verify secret-store plugin backend"
when: not (_assert_is_store_crypto | bool)
block:
- name: "{{ cifmw_barbican_migrate_assert_label }}: read secret_store_metadata.plugin_name"
ansible.builtin.include_tasks: sql.yml
vars:
cifmw_barbican_migrate_sql_desc: "{{ cifmw_barbican_migrate_assert_label }} store plugin_name"
cifmw_barbican_migrate_sql: >-
SELECT value FROM secret_store_metadata
WHERE secret_id='{{ cifmw_barbican_migrate_assert_secret_id }}'
AND `key`='plugin_name' AND deleted=0;

- name: "{{ cifmw_barbican_migrate_assert_label }}: save store plugin_name"
ansible.builtin.set_fact:
_assert_meta_plugin_name: "{{ cifmw_barbican_migrate_sql_result.stdout | trim }}"

- name: "{{ cifmw_barbican_migrate_assert_label }}: count leftover ciphertext"
ansible.builtin.include_tasks: sql.yml
vars:
cifmw_barbican_migrate_sql_desc: "{{ cifmw_barbican_migrate_assert_label }} encrypted_data count"
cifmw_barbican_migrate_sql: >-
SELECT COUNT(*) FROM encrypted_data
WHERE secret_id='{{ cifmw_barbican_migrate_assert_secret_id }}'
AND deleted=0;

- name: "{{ cifmw_barbican_migrate_assert_label }}: assert metadata plugin and no ciphertext"
ansible.builtin.assert:
that:
- _assert_meta_plugin_name == _assert_expected_fqcn
- cifmw_barbican_migrate_sql_result.stdout | trim == "0"
fail_msg: >-
{{ cifmw_barbican_migrate_assert_label }}: expected
secret_store_metadata.plugin_name '{{ _assert_expected_fqcn }}'
and no active encrypted_data for store_plugin
'{{ cifmw_barbican_migrate_assert_store.store_plugin }}'.
plugin_name='{{ _assert_meta_plugin_name }}'
encrypted_data_count='{{ cifmw_barbican_migrate_sql_result.stdout | trim }}'.
83 changes: 83 additions & 0 deletions hooks/playbooks/barbican-secret-store-migrate/metaonly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
# Metadata-only secrets have no payload and must fail migrate (HTTP 409).

- name: Metadata-only migrate must conflict
block:
- name: Create metadata-only secret
ansible.builtin.command:
argv:
- oc
- -n
- "{{ cifmw_barbican_migrate_namespace }}"
- exec
- "{{ cifmw_barbican_migrate_osc_pod }}"
- --
- openstack
- secret
- store
- --name
- ci-migrate-metaonly
- -f
- value
- -c
- Secret href
register: _meta_create
changed_when: false
no_log: true

- name: Parse metadata-only secret
ansible.builtin.set_fact:
_meta_secret_href: "{{ _meta_create.stdout | trim }}"

- name: Migrate metadata-only secret (expect conflict)
ansible.builtin.command:
argv:
- oc
- -n
- "{{ cifmw_barbican_migrate_namespace }}"
- exec
- "{{ cifmw_barbican_migrate_osc_pod }}"
- --
- openstack
- secret
- migrate
- "{{ _meta_secret_href }}"
- --secret-store
- "{{ _store_other.id }}"
register: _meta_migrate
changed_when: false
failed_when: false

- name: Assert metadata-only migrate failed
ansible.builtin.assert:
that:
- _meta_migrate.rc != 0
- >-
('409' in (_meta_migrate.stderr | default('')))
or ('Conflict' in (_meta_migrate.stderr | default('')))
or ('no stored payload' in (_meta_migrate.stderr | default('')))
or ('409' in (_meta_migrate.stdout | default('')))
or ('Conflict' in (_meta_migrate.stdout | default('')))
or ('no stored payload' in (_meta_migrate.stdout | default('')))
fail_msg: >-
Metadata-only migrate should fail with HTTP 409 / Conflict.
rc={{ _meta_migrate.rc }}
stderr={{ _meta_migrate.stderr | default('') }}
always:
- name: Delete metadata-only secret
when: _meta_secret_href is defined
ansible.builtin.command:
argv:
- oc
- -n
- "{{ cifmw_barbican_migrate_namespace }}"
- exec
- "{{ cifmw_barbican_migrate_osc_pod }}"
- --
- openstack
- secret
- delete
- "{{ _meta_secret_href }}"
changed_when: false
failed_when: false
no_log: true
Loading
Loading