diff --git a/README.md b/README.md index a242030..31e4065 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ See [CHANGELOG.md](CHANGELOG.md) for release history and changes. This collection includes the following roles for managing OpenShift Virtualization migrations: +* [aap_cleanup](roles/aap_cleanup/README.md) - Remove AAP resources seeded by the aap_seed role * [aap_deploy](roles/aap_deploy/README.md) - Deploys an instance of Ansible Automation Platform. * [aap_machine_credentials](roles/aap_machine_credentials/README.md) - Management of Machine Credentials. * [aap_seed](roles/aap_seed/README.md) - Populates an Ansible Automation Platform instance. @@ -50,6 +51,7 @@ This collection includes the following roles for managing OpenShift Virtualizati * [mtv_management](roles/mtv_management/README.md) - Management of the Migration Toolkit for Virtualization (MTV). * [mtv_migrate](roles/mtv_migrate/README.md) - Migration of Virtual Machines from Source to Destination. * [network_mgmt](roles/network_mgmt/README.md) - Management of network related components. +* [ocp_cleanup](roles/ocp_cleanup/README.md) - Remove OpenShift migration artifacts created during virtualization migration testing * [operator_management](roles/operator_management/README.md) - Management of OpenShift Operators. * [validate_migration](roles/validate_migration/README.md) - Verification of an Ansible for OpenShift Virtualization Migration environment. * [vm_backup_restore](roles/vm_backup_restore/README.md) - Virtual Machine backup and restore capabilities. diff --git a/extensions/molecule/cleanup_aap/molecule.yml b/extensions/molecule/cleanup_aap/molecule.yml new file mode 100644 index 0000000..b746204 --- /dev/null +++ b/extensions/molecule/cleanup_aap/molecule.yml @@ -0,0 +1,22 @@ +--- +platforms: + - name: na + +provisioner: + name: ansible + playbooks: + cleanup: ../utils/playbooks/noop.yml + converge: ../utils/playbooks/converge.yml + destroy: ../utils/playbooks/noop.yml + prepare: ../utils/playbooks/noop.yml + config_options: + defaults: + collections_path: ${ANSIBLE_COLLECTIONS_PATH} + +scenario: + test_sequence: + - prepare + - converge + destroy_sequence: + - destroy +... diff --git a/extensions/molecule/cleanup_ocp_artifacts/molecule.yml b/extensions/molecule/cleanup_ocp_artifacts/molecule.yml new file mode 100644 index 0000000..b746204 --- /dev/null +++ b/extensions/molecule/cleanup_ocp_artifacts/molecule.yml @@ -0,0 +1,22 @@ +--- +platforms: + - name: na + +provisioner: + name: ansible + playbooks: + cleanup: ../utils/playbooks/noop.yml + converge: ../utils/playbooks/converge.yml + destroy: ../utils/playbooks/noop.yml + prepare: ../utils/playbooks/noop.yml + config_options: + defaults: + collections_path: ${ANSIBLE_COLLECTIONS_PATH} + +scenario: + test_sequence: + - prepare + - converge + destroy_sequence: + - destroy +... diff --git a/playbooks/cleanup_all.yml b/playbooks/cleanup_all.yml new file mode 100644 index 0000000..22930dc --- /dev/null +++ b/playbooks/cleanup_all.yml @@ -0,0 +1,33 @@ +--- +- name: Cleanup OCP migration artifacts + hosts: localhost + connection: local + gather_facts: false + tasks: + - name: Run OCP cleanup + block: + - name: Include OCP cleanup role + ansible.builtin.include_role: + name: infra.openshift_virtualization_migration.ocp_cleanup + rescue: + - name: OCP cleanup failed + ansible.builtin.debug: + msg: "OCP migration artifact cleanup failed — continuing with AAP cleanup" + +- name: Cleanup Migration AAP + hosts: migration_aap + connection: local + gather_facts: false + tasks: + - name: Run Migration AAP cleanup + block: + - name: Include AAP cleanup role + ansible.builtin.include_role: + name: infra.openshift_virtualization_migration.aap_cleanup + vars: + aap_cleanup_job_history_purge: true + rescue: + - name: Migration AAP cleanup failed + ansible.builtin.debug: + msg: "Migration AAP cleanup failed" +... diff --git a/playbooks/cleanup_migration_aap.yml b/playbooks/cleanup_migration_aap.yml new file mode 100644 index 0000000..41537a1 --- /dev/null +++ b/playbooks/cleanup_migration_aap.yml @@ -0,0 +1,11 @@ +--- +- name: Remove seeded AAP content from Migration Factory instance + hosts: migration_aap + connection: local + gather_facts: false + + roles: + - role: infra.openshift_virtualization_migration.aap_cleanup + vars: + aap_cleanup_job_history_purge: true +... diff --git a/playbooks/cleanup_ocp_migration_artifacts.yml b/playbooks/cleanup_ocp_migration_artifacts.yml new file mode 100644 index 0000000..1a33a8a --- /dev/null +++ b/playbooks/cleanup_ocp_migration_artifacts.yml @@ -0,0 +1,9 @@ +--- +- name: Remove OpenShift migration artifacts + hosts: localhost + connection: local + gather_facts: false + + roles: + - role: infra.openshift_virtualization_migration.ocp_cleanup +... diff --git a/roles/aap_cleanup/README.md b/roles/aap_cleanup/README.md new file mode 100644 index 0000000..b4d56ac --- /dev/null +++ b/roles/aap_cleanup/README.md @@ -0,0 +1,293 @@ +# aap_cleanup + +Remove AAP resources seeded by the `aap_seed` role. Discovers resources via the AAP controller API and removes them in reverse dependency order using `infra.aap_configuration.dispatch` (or `infra.controller_configuration.dispatch` for AAP 2.4). + +## Requirements + +- AAP controller API access (hostname + credentials or token) +- `infra.aap_configuration` >= 3.4.1 (AAP 2.5+) or `infra.controller_configuration` >= 3.1.2 (AAP 2.4) + +## Role Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `aap_cleanup_controller_hostname` | env/var lookup | AAP controller hostname | +| `aap_cleanup_controller_username` | env/var lookup | AAP controller username | +| `aap_cleanup_controller_password` | env/var lookup | AAP controller password | +| `aap_cleanup_controller_token` | env/var lookup | AAP OAuth token (preferred over user/pass) | +| `aap_cleanup_controller_validate_certs` | env/var lookup | Validate TLS certificates | +| `aap_cleanup_aap_org_name` | `aap_org_name` | Organization to clean | +| `aap_cleanup_dry_run` | `false` | Query and report only, no deletions | +| `aap_cleanup_workflows_remove` | `true` | Remove workflow job templates | +| `aap_cleanup_job_templates_remove` | `true` | Remove job templates | +| `aap_cleanup_hosts_remove` | `true` | Remove hosts | +| `aap_cleanup_inventories_remove` | `true` | Remove inventories | +| `aap_cleanup_projects_remove` | `true` | Remove projects | +| `aap_cleanup_execution_environments_remove` | `true` | Remove execution environments | +| `aap_cleanup_credentials_remove` | `true` | Remove credentials | +| `aap_cleanup_credential_types_remove` | `true` | Remove custom credential types | +| `aap_cleanup_organization_remove` | `false` | Remove organization (destructive) | +| `aap_cleanup_job_history_purge` | `false` | Purge completed job history | +| `aap_cleanup_providers` | `[vmware, ovirt]` | Provider-specific resources to target | + +## Deletion Order + +Resources are removed in reverse creation order to respect dependencies: + +1. Workflow Job Templates +2. Job Templates +3. Hosts +4. Inventories +5. Projects +6. Execution Environments +7. Credentials +8. Credential Types +9. Organizations (optional) +10. Job History (optional) + +## Example Playbook + +```yaml +- hosts: localhost + roles: + - role: infra.openshift_virtualization_migration.aap_cleanup + vars: + aap_cleanup_dry_run: true # preview first +``` + +## aap_cleanup + +``` +Role belongs to infra/openshift_virtualization_migration +Namespace - infra +Collection - openshift_virtualization_migration +Version - 1.25.0 +Repository - https://github.com/redhat-cop/openshift_virtualization_migration +``` + +Description: Remove AAP resources seeded by the aap_seed role + +### Defaults + +**These are static variables with lower priority** + +#### File: defaults/main.yml + +| Var | Type | Value |Choices |Required | Title | +|--------------|--------------|-------------|-------------|-------------|-------------| +| [`aap_cleanup_aap_org_name`](defaults/main.yml#L27) | str | `{{ aap_org_name }}` | None | None | None | +| [`aap_cleanup_api_base`](defaults/main.yml#L30) | str | `` | None | None | None | +| [`aap_cleanup_cac_collection`](defaults/main.yml#L22) | str | `` | None | None | None | +| [`aap_cleanup_controller_configuration_async_retries`](defaults/main.yml#L55) | int | `60` | None | None | None | +| [`aap_cleanup_controller_hostname`](defaults/main.yml#L3) | str | `` | None | None | None | +| [`aap_cleanup_controller_password`](defaults/main.yml#L9) | str | `` | None | None | None | +| [`aap_cleanup_controller_token`](defaults/main.yml#L12) | str | `` | None | None | None | +| [`aap_cleanup_controller_username`](defaults/main.yml#L6) | str | `` | None | None | None | +| [`aap_cleanup_controller_validate_certs`](defaults/main.yml#L15) | str | `` | None | None | None | +| [`aap_cleanup_credential_types_remove`](defaults/main.yml#L44) | bool | `True` | None | None | None | +| [`aap_cleanup_credentials_remove`](defaults/main.yml#L43) | bool | `True` | None | None | None | +| [`aap_cleanup_dry_run`](defaults/main.yml#L52) | bool | `False` | None | None | None | +| [`aap_cleanup_execution_environments_remove`](defaults/main.yml#L42) | bool | `True` | None | None | None | +| [`aap_cleanup_hosts_remove`](defaults/main.yml#L39) | bool | `True` | None | None | None | +| [`aap_cleanup_inventories_remove`](defaults/main.yml#L40) | bool | `True` | None | None | None | +| [`aap_cleanup_job_history_purge`](defaults/main.yml#L46) | bool | `False` | None | None | None | +| [`aap_cleanup_job_templates_remove`](defaults/main.yml#L38) | bool | `True` | None | None | None | +| [`aap_cleanup_organization_remove`](defaults/main.yml#L45) | bool | `False` | None | None | None | +| [`aap_cleanup_projects_remove`](defaults/main.yml#L41) | bool | `True` | None | None | None | +| [`aap_cleanup_providers`](defaults/main.yml#L49) | str | `{{ cleanup_providers ¦ default(['vmware', 'ovirt']) }}` | None | None | None | +| [`aap_cleanup_secure_logging`](defaults/main.yml#L19) | str | `{{ secure_logging ¦ default(true) }}` | None | None | None | +| [`aap_cleanup_workflows_remove`](defaults/main.yml#L37) | bool | `True` | None | None | None | + +🖇️ Full descriptions for vars in defaults/main.yml +
+`aap_cleanup_aap_org_name`: None +
+`aap_cleanup_api_base`: None +
+`aap_cleanup_cac_collection`: None +
+`aap_cleanup_controller_configuration_async_retries`: None +
+`aap_cleanup_controller_hostname`: None +
+`aap_cleanup_controller_password`: None +
+`aap_cleanup_controller_token`: None +
+`aap_cleanup_controller_username`: None +
+`aap_cleanup_controller_validate_certs`: None +
+`aap_cleanup_credential_types_remove`: None +
+`aap_cleanup_credentials_remove`: None +
+`aap_cleanup_dry_run`: None +
+`aap_cleanup_execution_environments_remove`: None +
+`aap_cleanup_hosts_remove`: None +
+`aap_cleanup_inventories_remove`: None +
+`aap_cleanup_job_history_purge`: None +
+`aap_cleanup_job_templates_remove`: None +
+`aap_cleanup_organization_remove`: None +
+`aap_cleanup_projects_remove`: None +
+`aap_cleanup_providers`: None +
+`aap_cleanup_secure_logging`: None +
+`aap_cleanup_workflows_remove`: None +
+
+ +### Tasks + +#### File: tasks/main.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| Ensure AAP API credentials are set | `ansible.builtin.assert` | False | +| Build authentication headers | `ansible.builtin.set_fact` | False | +| Resolve organization ID | `ansible.builtin.uri` | False | +| Set organization ID | `ansible.builtin.set_fact` | True | +| Discover and remove AAP resources | `block` | True | +| Remove workflow job templates | `ansible.builtin.include_tasks` | True | +| Remove job templates | `ansible.builtin.include_tasks` | True | +| Remove hosts | `ansible.builtin.include_tasks` | True | +| Remove inventories | `ansible.builtin.include_tasks` | True | +| Remove projects | `ansible.builtin.include_tasks` | True | +| Remove execution environments | `ansible.builtin.include_tasks` | True | +| Remove credentials | `ansible.builtin.include_tasks` | True | +| Remove credential types | `ansible.builtin.include_tasks` | True | +| Remove organization | `ansible.builtin.include_tasks` | True | +| Purge job history | `ansible.builtin.include_tasks` | True | + +#### File: tasks/_build_absent_resources.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _build_absent_resources ¦ Query resources from AAP API — {{ _aap_cleanup_resource_type }} | `ansible.builtin.uri` | False | +| _build_absent_resources ¦ Filter out managed/built-in credential types | `ansible.builtin.set_fact` | True | +| _build_absent_resources ¦ Set results for non-filtered resources | `ansible.builtin.set_fact` | True | +| _build_absent_resources ¦ Report resources found — {{ _aap_cleanup_resource_type }} | `ansible.builtin.debug` | False | +| _build_absent_resources ¦ Display resources to remove | `ansible.builtin.debug` | True | +| _build_absent_resources ¦ Build and dispatch absent resources — {{ _aap_cleanup_resource_type }} | `block` | True | +| _build_absent_resources ¦ Build absent resource list — {{ _aap_cleanup_resource_type }} | `ansible.builtin.set_fact` | False | +| _build_absent_resources ¦ Set dispatch variable — {{ _aap_cleanup_dispatch_var }} | `ansible.builtin.set_fact` | False | +| _build_absent_resources ¦ Dispatch removal — {{ _aap_cleanup_resource_type }} | `ansible.builtin.include_role` | False | +| _build_absent_resources ¦ Clear dispatch variable — {{ _aap_cleanup_dispatch_var }} | `ansible.builtin.set_fact` | False | + +#### File: tasks/_cleanup_job_history.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _cleanup_job_history ¦ Query completed jobs | `ansible.builtin.uri` | False | +| _cleanup_job_history ¦ Report job history count | `ansible.builtin.debug` | False | +| _cleanup_job_history ¦ Delete completed jobs | `ansible.builtin.uri` | True | + +## Task Flow Graphs + +### Graph for _build_absent_resources.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Task| _build_absent_resources___Query_resources_from_AAP_API____aap_cleanup_resource_type0[ build absent resources query resources from aap
api aap cleanup resource type]:::task + _build_absent_resources___Query_resources_from_AAP_API____aap_cleanup_resource_type0-->|Task| _build_absent_resources___Filter_out_managed_built_in_credential_types1[ build absent resources filter out managed built
in credential types
When: **aap cleanup filter managed default false
bool**]:::task + _build_absent_resources___Filter_out_managed_built_in_credential_types1-->|Task| _build_absent_resources___Set_results_for_non_filtered_resources2[ build absent resources set results for non
filtered resources
When: **not aap cleanup filter managed default false
bool**]:::task + _build_absent_resources___Set_results_for_non_filtered_resources2-->|Task| _build_absent_resources___Report_resources_found____aap_cleanup_resource_type3[ build absent resources report resources found
aap cleanup resource type]:::task + _build_absent_resources___Report_resources_found____aap_cleanup_resource_type3-->|Task| _build_absent_resources___Display_resources_to_remove4[ build absent resources display resources to
remove
When: **aap cleanup filtered results length 0**]:::task + _build_absent_resources___Display_resources_to_remove4-->|Block Start| _build_absent_resources___Build_and_dispatch_absent_resources____aap_cleanup_resource_type5_block_start_0[[ build absent resources build and dispatch
absent resources aap cleanup resource type
When: **aap cleanup filtered results length 0 and not
aap cleanup dry run bool**]]:::block + _build_absent_resources___Build_and_dispatch_absent_resources____aap_cleanup_resource_type5_block_start_0-->|Task| _build_absent_resources___Build_absent_resource_list____aap_cleanup_resource_type0[ build absent resources build absent resource
list aap cleanup resource type]:::task + _build_absent_resources___Build_absent_resource_list____aap_cleanup_resource_type0-->|Task| _build_absent_resources___Set_dispatch_variable____aap_cleanup_dispatch_var1[ build absent resources set dispatch variable
aap cleanup dispatch var]:::task + _build_absent_resources___Set_dispatch_variable____aap_cleanup_dispatch_var1-->|Include role| _build_absent_resources___Dispatch_removal____aap_cleanup_resource_type____aap_cleanup_cac_collection____dispatch_2( build absent resources dispatch removal aap
cleanup resource type
include_role: aap cleanup cac collection dispatch):::includeRole + _build_absent_resources___Dispatch_removal____aap_cleanup_resource_type____aap_cleanup_cac_collection____dispatch_2-->|Task| _build_absent_resources___Clear_dispatch_variable____aap_cleanup_dispatch_var3[ build absent resources clear dispatch variable
aap cleanup dispatch var]:::task + _build_absent_resources___Clear_dispatch_variable____aap_cleanup_dispatch_var3-.->|End of Block| _build_absent_resources___Build_and_dispatch_absent_resources____aap_cleanup_resource_type5_block_start_0 + _build_absent_resources___Clear_dispatch_variable____aap_cleanup_dispatch_var3-->End +``` + +### Graph for _cleanup_job_history.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Task| _cleanup_job_history___Query_completed_jobs0[ cleanup job history query completed jobs]:::task + _cleanup_job_history___Query_completed_jobs0-->|Task| _cleanup_job_history___Report_job_history_count1[ cleanup job history report job history count]:::task + _cleanup_job_history___Report_job_history_count1-->|Task| _cleanup_job_history___Delete_completed_jobs2[ cleanup job history delete completed jobs
When: **aap cleanup jobs result json count 0 and not
aap cleanup dry run bool**]:::task + _cleanup_job_history___Delete_completed_jobs2-->End +``` + +### Graph for main.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Task| Ensure_AAP_API_credentials_are_set0[ensure aap api credentials are set]:::task + Ensure_AAP_API_credentials_are_set0-->|Task| Build_authentication_headers1[build authentication headers]:::task + Build_authentication_headers1-->|Task| Resolve_organization_ID2[resolve organization id]:::task + Resolve_organization_ID2-->|Task| Set_organization_ID3[set organization id
When: **aap cleanup org result json count 0**]:::task + Set_organization_ID3-->|Block Start| Discover_and_remove_AAP_resources4_block_start_0[[discover and remove aap resources
When: **aap cleanup org id is defined**]]:::block + Discover_and_remove_AAP_resources4_block_start_0-->|Include task| Remove_workflow_job_templates__build_absent_resources_yml_0[remove workflow job templates
When: **aap cleanup workflows remove bool**
include_task: build absent resources yml]:::includeTasks + Remove_workflow_job_templates__build_absent_resources_yml_0-->|Include task| Remove_job_templates__build_absent_resources_yml_1[remove job templates
When: **aap cleanup job templates remove bool**
include_task: build absent resources yml]:::includeTasks + Remove_job_templates__build_absent_resources_yml_1-->|Include task| Remove_hosts__build_absent_resources_yml_2[remove hosts
When: **aap cleanup hosts remove bool**
include_task: build absent resources yml]:::includeTasks + Remove_hosts__build_absent_resources_yml_2-->|Include task| Remove_inventories__build_absent_resources_yml_3[remove inventories
When: **aap cleanup inventories remove bool**
include_task: build absent resources yml]:::includeTasks + Remove_inventories__build_absent_resources_yml_3-->|Include task| Remove_projects__build_absent_resources_yml_4[remove projects
When: **aap cleanup projects remove bool**
include_task: build absent resources yml]:::includeTasks + Remove_projects__build_absent_resources_yml_4-->|Include task| Remove_execution_environments__build_absent_resources_yml_5[remove execution environments
When: **aap cleanup execution environments remove bool**
include_task: build absent resources yml]:::includeTasks + Remove_execution_environments__build_absent_resources_yml_5-->|Include task| Remove_credentials__build_absent_resources_yml_6[remove credentials
When: **aap cleanup credentials remove bool**
include_task: build absent resources yml]:::includeTasks + Remove_credentials__build_absent_resources_yml_6-->|Include task| Remove_credential_types__build_absent_resources_yml_7[remove credential types
When: **aap cleanup credential types remove bool**
include_task: build absent resources yml]:::includeTasks + Remove_credential_types__build_absent_resources_yml_7-->|Include task| Remove_organization__build_absent_resources_yml_8[remove organization
When: **aap cleanup organization remove bool**
include_task: build absent resources yml]:::includeTasks + Remove_organization__build_absent_resources_yml_8-->|Include task| Purge_job_history__cleanup_job_history_yml_9[purge job history
When: **aap cleanup job history purge bool**
include_task: cleanup job history yml]:::includeTasks + Purge_job_history__cleanup_job_history_yml_9-.->|End of Block| Discover_and_remove_AAP_resources4_block_start_0 + Purge_job_history__cleanup_job_history_yml_9-->End +``` + +## Author Information + +Red Hat + +## License + +GPL-3.0-or-later + +## Minimum Ansible Version + +2.15 + +## Platforms + +* **EL**: ['9'] + + \ No newline at end of file diff --git a/roles/aap_cleanup/defaults/main.yml b/roles/aap_cleanup/defaults/main.yml new file mode 100644 index 0000000..b66953e --- /dev/null +++ b/roles/aap_cleanup/defaults/main.yml @@ -0,0 +1,56 @@ +--- +# AAP Controller connection +aap_cleanup_controller_hostname: >- + {{ controller_hostname | default(aap_hostname) + | default(lookup('ansible.builtin.env', 'CONTROLLER_HOSTNAME')) }} +aap_cleanup_controller_username: >- + {{ controller_username | default(aap_username) + | default(lookup('ansible.builtin.env', 'CONTROLLER_USERNAME')) }} +aap_cleanup_controller_password: >- + {{ controller_password | default(aap_password) + | default(lookup('ansible.builtin.env', 'CONTROLLER_PASSWORD')) }} +aap_cleanup_controller_token: >- + {{ controller_oauthtoken | default(aap_token) + | default(lookup('ansible.builtin.env', 'CONTROLLER_TOKEN')) }} +aap_cleanup_controller_validate_certs: >- + {{ controller_validate_certs | default(aap_validate_certs) + | default(lookup('ansible.builtin.env', 'CONTROLLER_VERIFY_SSL')) + | default(true, true) | bool }} +aap_cleanup_secure_logging: "{{ secure_logging | default(true) }}" + +# AAP version-aware collection selection +aap_cleanup_cac_collection: >- + {{ 'infra.controller_configuration' if aap_version is defined and aap_version is version('2.5', '<') + else 'infra.aap_configuration' }} + +# Organization context +aap_cleanup_aap_org_name: "{{ aap_org_name }}" + +# API base path (AAP 2.5+ uses /api/controller/v2, 2.4 uses /api/v2) +aap_cleanup_api_base: >- + {{ '/api/controller/v2' + if aap_version is not defined + or (aap_version is defined and aap_version is version('2.5', '>=')) + else '/api/v2' }} + +# Scope toggles — which resource types to remove +aap_cleanup_workflows_remove: true +aap_cleanup_job_templates_remove: true +aap_cleanup_hosts_remove: true +aap_cleanup_inventories_remove: true +aap_cleanup_projects_remove: true +aap_cleanup_execution_environments_remove: true +aap_cleanup_credentials_remove: true +aap_cleanup_credential_types_remove: true +aap_cleanup_organization_remove: false +aap_cleanup_job_history_purge: false + +# Provider filtering +aap_cleanup_providers: "{{ cleanup_providers | default(['vmware', 'ovirt']) }}" + +# Dry-run mode — query and report only, no deletions +aap_cleanup_dry_run: false + +# Async configuration +aap_cleanup_controller_configuration_async_retries: 60 +... diff --git a/roles/aap_cleanup/meta/main.yml b/roles/aap_cleanup/meta/main.yml new file mode 100644 index 0000000..9035d8e --- /dev/null +++ b/roles/aap_cleanup/meta/main.yml @@ -0,0 +1,18 @@ +--- +galaxy_info: + author: Red Hat + description: Remove AAP resources seeded by the aap_seed role + license: GPL-3.0-or-later + min_ansible_version: "2.15" + platforms: + - name: EL + versions: + - "9" + galaxy_tags: + - aap + - cleanup + - migration + - openshift + - virtualization +dependencies: [] +... diff --git a/roles/aap_cleanup/tasks/_build_absent_resources.yml b/roles/aap_cleanup/tasks/_build_absent_resources.yml new file mode 100644 index 0000000..1b6c3f2 --- /dev/null +++ b/roles/aap_cleanup/tasks/_build_absent_resources.yml @@ -0,0 +1,76 @@ +--- +- name: "_build_absent_resources | Query resources from AAP API — {{ _aap_cleanup_resource_type }}" + ansible.builtin.uri: + url: >- + https://{{ aap_cleanup_controller_hostname }}{{ aap_cleanup_api_base }}/{{ _aap_cleanup_resource_type }}/?{{ + 'organization=' ~ _aap_cleanup_org_id ~ '&' if (_aap_cleanup_use_org_filter | default(true)) else '' + }}page_size=200 + method: GET + headers: "{{ _aap_cleanup_auth_headers }}" + user: "{{ aap_cleanup_controller_username if _aap_cleanup_force_basic_auth else omit }}" + password: "{{ aap_cleanup_controller_password if _aap_cleanup_force_basic_auth else omit }}" + force_basic_auth: "{{ _aap_cleanup_force_basic_auth }}" + validate_certs: "{{ aap_cleanup_controller_validate_certs }}" + body_format: json + status_code: [200] + register: _aap_cleanup_query_result + no_log: "{{ aap_cleanup_secure_logging }}" + +- name: "_build_absent_resources | Filter out managed/built-in credential types" + when: _aap_cleanup_filter_managed | default(false) | bool + ansible.builtin.set_fact: + _aap_cleanup_filtered_results: >- + {{ _aap_cleanup_query_result.json.results + | selectattr('managed', 'equalto', false) + | list }} + +- name: "_build_absent_resources | Set results for non-filtered resources" + when: not (_aap_cleanup_filter_managed | default(false) | bool) + ansible.builtin.set_fact: + _aap_cleanup_filtered_results: "{{ _aap_cleanup_query_result.json.results }}" + +- name: "_build_absent_resources | Report resources found — {{ _aap_cleanup_resource_type }}" + ansible.builtin.debug: + msg: >- + {{ _aap_cleanup_resource_type }}: found {{ _aap_cleanup_filtered_results | length }} resource(s) + {{ '— DRY RUN, skipping deletion' if aap_cleanup_dry_run else '— removing' }} + verbosity: 0 + +- name: "_build_absent_resources | Display resources to remove" + when: _aap_cleanup_filtered_results | length > 0 + ansible.builtin.debug: + msg: "{{ _aap_cleanup_filtered_results | map(attribute='name') | list }}" + verbosity: 0 + +- name: "_build_absent_resources | Build and dispatch absent resources — {{ _aap_cleanup_resource_type }}" + when: + - _aap_cleanup_filtered_results | length > 0 + - not (aap_cleanup_dry_run | bool) + block: + - name: "_build_absent_resources | Build absent resource list — {{ _aap_cleanup_resource_type }}" + ansible.builtin.set_fact: + _aap_cleanup_absent_list: >- + {{ _aap_cleanup_filtered_results | map('combine', {'state': 'absent'}) + | map('dict2items') + | map('selectattr', 'key', 'in', + ['name', 'organization', 'state'] + + (_aap_cleanup_extra_fields | default([]))) + | map('items2dict') + | list }} + + - name: "_build_absent_resources | Set dispatch variable — {{ _aap_cleanup_dispatch_var }}" + ansible.builtin.set_fact: + "{{ _aap_cleanup_dispatch_var }}": "{{ _aap_cleanup_absent_list }}" + controller_dependency_check: false # noqa: var-naming[no-role-prefix] + + - name: "_build_absent_resources | Dispatch removal — {{ _aap_cleanup_resource_type }}" + ansible.builtin.include_role: + name: "{{ aap_cleanup_cac_collection }}.dispatch" + vars: + controller_configuration_async_delay: 5 + aap_configuration_async_delay: 5 + + - name: "_build_absent_resources | Clear dispatch variable — {{ _aap_cleanup_dispatch_var }}" + ansible.builtin.set_fact: + "{{ _aap_cleanup_dispatch_var }}": [] +... diff --git a/roles/aap_cleanup/tasks/_cleanup_job_history.yml b/roles/aap_cleanup/tasks/_cleanup_job_history.yml new file mode 100644 index 0000000..3f5aa63 --- /dev/null +++ b/roles/aap_cleanup/tasks/_cleanup_job_history.yml @@ -0,0 +1,41 @@ +--- +- name: "_cleanup_job_history | Query completed jobs" + ansible.builtin.uri: + url: >- + https://{{ aap_cleanup_controller_hostname + }}{{ aap_cleanup_api_base }}/jobs/?status=successful&page_size=200&order_by=-finished + method: GET + headers: "{{ _aap_cleanup_auth_headers }}" + user: "{{ aap_cleanup_controller_username if _aap_cleanup_force_basic_auth else omit }}" + password: "{{ aap_cleanup_controller_password if _aap_cleanup_force_basic_auth else omit }}" + force_basic_auth: "{{ _aap_cleanup_force_basic_auth }}" + validate_certs: "{{ aap_cleanup_controller_validate_certs }}" + body_format: json + status_code: [200] + register: _aap_cleanup_jobs_result + no_log: "{{ aap_cleanup_secure_logging }}" + +- name: "_cleanup_job_history | Report job history count" + ansible.builtin.debug: + msg: >- + Job history: found {{ _aap_cleanup_jobs_result.json.count }} completed job(s) + {{ '— DRY RUN, skipping purge' if aap_cleanup_dry_run else '— purging' }} + +- name: "_cleanup_job_history | Delete completed jobs" + when: + - _aap_cleanup_jobs_result.json.count > 0 + - not (aap_cleanup_dry_run | bool) + ansible.builtin.uri: + url: "https://{{ aap_cleanup_controller_hostname }}{{ aap_cleanup_api_base }}/jobs/{{ item.id }}/" + method: DELETE + headers: "{{ _aap_cleanup_auth_headers }}" + user: "{{ aap_cleanup_controller_username if _aap_cleanup_force_basic_auth else omit }}" + password: "{{ aap_cleanup_controller_password if _aap_cleanup_force_basic_auth else omit }}" + force_basic_auth: "{{ _aap_cleanup_force_basic_auth }}" + validate_certs: "{{ aap_cleanup_controller_validate_certs }}" + status_code: [202, 204, 404] + loop: "{{ _aap_cleanup_jobs_result.json.results }}" + loop_control: + label: "{{ item.name | default(item.id) }} ({{ item.id }})" + no_log: "{{ aap_cleanup_secure_logging }}" +... diff --git a/roles/aap_cleanup/tasks/main.yml b/roles/aap_cleanup/tasks/main.yml new file mode 100644 index 0000000..2a2d29e --- /dev/null +++ b/roles/aap_cleanup/tasks/main.yml @@ -0,0 +1,133 @@ +--- +- name: Ensure AAP API credentials are set + ansible.builtin.assert: + that: + - aap_cleanup_controller_hostname | default("", true) | trim | length > 0 + - >- + (aap_cleanup_controller_username | default("", true) | trim | length > 0 and + aap_cleanup_controller_password | default("", true) | trim | length > 0) or + aap_cleanup_controller_token | default("", true) | trim | length > 0 + fail_msg: "AAP API credentials are not set. Check controller_hostname and username/password or token." + +- name: Build authentication headers + ansible.builtin.set_fact: + _aap_cleanup_auth_headers: >- + {{ {'Authorization': 'Bearer ' ~ aap_cleanup_controller_token} + if aap_cleanup_controller_token | default("", true) | trim | length > 0 + else {} }} + _aap_cleanup_force_basic_auth: >- + {{ aap_cleanup_controller_token | default("", true) | trim | length == 0 }} + no_log: "{{ aap_cleanup_secure_logging }}" + +- name: Resolve organization ID + ansible.builtin.uri: + url: >- + https://{{ aap_cleanup_controller_hostname }}{{ aap_cleanup_api_base + }}/organizations/?name={{ aap_cleanup_aap_org_name | urlencode }} + method: GET + headers: "{{ _aap_cleanup_auth_headers }}" + user: "{{ aap_cleanup_controller_username if _aap_cleanup_force_basic_auth else omit }}" + password: "{{ aap_cleanup_controller_password if _aap_cleanup_force_basic_auth else omit }}" + force_basic_auth: "{{ _aap_cleanup_force_basic_auth }}" + validate_certs: "{{ aap_cleanup_controller_validate_certs }}" + body_format: json + status_code: [200] + register: _aap_cleanup_org_result + no_log: "{{ aap_cleanup_secure_logging }}" + +- name: Set organization ID + ansible.builtin.set_fact: + _aap_cleanup_org_id: "{{ _aap_cleanup_org_result.json.results[0].id }}" + when: _aap_cleanup_org_result.json.count > 0 + +- name: Discover and remove AAP resources + when: _aap_cleanup_org_id is defined + block: + - name: Remove workflow job templates + ansible.builtin.include_tasks: + file: _build_absent_resources.yml + vars: + _aap_cleanup_resource_type: workflow_job_templates + _aap_cleanup_dispatch_var: controller_workflows + when: aap_cleanup_workflows_remove | bool + + - name: Remove job templates + ansible.builtin.include_tasks: + file: _build_absent_resources.yml + vars: + _aap_cleanup_resource_type: job_templates + _aap_cleanup_dispatch_var: controller_templates + when: aap_cleanup_job_templates_remove | bool + + - name: Remove hosts + ansible.builtin.include_tasks: + file: _build_absent_resources.yml + vars: + _aap_cleanup_resource_type: hosts + _aap_cleanup_dispatch_var: controller_hosts + _aap_cleanup_extra_fields: + - inventory + _aap_cleanup_use_org_filter: false + when: aap_cleanup_hosts_remove | bool + + - name: Remove inventories + ansible.builtin.include_tasks: + file: _build_absent_resources.yml + vars: + _aap_cleanup_resource_type: inventories + _aap_cleanup_dispatch_var: controller_inventories + when: aap_cleanup_inventories_remove | bool + + - name: Remove projects + ansible.builtin.include_tasks: + file: _build_absent_resources.yml + vars: + _aap_cleanup_resource_type: projects + _aap_cleanup_dispatch_var: controller_projects + when: aap_cleanup_projects_remove | bool + + - name: Remove execution environments + ansible.builtin.include_tasks: + file: _build_absent_resources.yml + vars: + _aap_cleanup_resource_type: execution_environments + _aap_cleanup_dispatch_var: controller_execution_environments + when: aap_cleanup_execution_environments_remove | bool + + - name: Remove credentials + ansible.builtin.include_tasks: + file: _build_absent_resources.yml + vars: + _aap_cleanup_resource_type: credentials + _aap_cleanup_dispatch_var: controller_credentials + _aap_cleanup_extra_fields: + - credential_type + when: aap_cleanup_credentials_remove | bool + + - name: Remove credential types + ansible.builtin.include_tasks: + file: _build_absent_resources.yml + vars: + _aap_cleanup_resource_type: credential_types + _aap_cleanup_dispatch_var: controller_credential_types + _aap_cleanup_filter_managed: true + _aap_cleanup_use_org_filter: false + when: aap_cleanup_credential_types_remove | bool + + - name: Remove organization + ansible.builtin.include_tasks: + file: _build_absent_resources.yml + vars: + _aap_cleanup_resource_type: organizations + _aap_cleanup_dispatch_var: >- + {{ 'controller_organizations' + if aap_version is defined and aap_version is version('2.5', '<') + else 'aap_organizations' }} + _aap_cleanup_use_org_filter: false + when: aap_cleanup_organization_remove | bool + + - name: Purge job history + ansible.builtin.include_tasks: + file: _cleanup_job_history.yml + when: aap_cleanup_job_history_purge | bool +... diff --git a/roles/ocp_cleanup/README.md b/roles/ocp_cleanup/README.md new file mode 100644 index 0000000..dbfc21a --- /dev/null +++ b/roles/ocp_cleanup/README.md @@ -0,0 +1,621 @@ +# ocp_cleanup + +Remove OpenShift cluster artifacts created during virtualization migration testing. Handles MTV CRDs, provider secrets, migrated VMs/PVCs, and optionally operator teardown. + +## Requirements + +- OpenShift cluster access (kubeconfig or API key) +- `kubernetes.core` >= 5.2.0 +- `redhat.openshift` >= 4.0.0 + +## Role Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `ocp_cleanup_openshift_host` | env lookup | OpenShift API host | +| `ocp_cleanup_openshift_api_key` | env lookup | OpenShift API key | +| `ocp_cleanup_openshift_verify_ssl` | `true` | Validate TLS certificates | +| `ocp_cleanup_mtv_namespace` | `openshift-mtv` | MTV operator namespace | +| `ocp_cleanup_dry_run` | `false` | Query and report only, no deletions | +| `ocp_cleanup_mtv_migrations_remove` | `true` | Remove Migration CRDs | +| `ocp_cleanup_mtv_plans_remove` | `true` | Remove Plan CRDs | +| `ocp_cleanup_mtv_maps_remove` | `true` | Remove NetworkMap/StorageMap CRDs | +| `ocp_cleanup_mtv_providers_remove` | `true` | Remove Provider CRDs | +| `ocp_cleanup_mtv_secrets_remove` | `true` | Remove provider/VDDK secrets | +| `ocp_cleanup_migrated_vms_remove` | `false` | Remove migrated VMs and PVCs (destructive) | +| `ocp_cleanup_target_namespaces_remove` | `false` | Remove target namespaces (destructive) | +| `ocp_cleanup_target_namespaces` | `[]` | List of target namespaces to clean | +| `ocp_cleanup_operators_remove` | `false` | Remove operators (slow to reinstall) | +| `ocp_cleanup_operators` | all 8 | Operator list to remove | +| `ocp_cleanup_providers` | `[vmware, ovirt]` | Provider types to target | + +## Deletion Order + +Resources are removed respecting Kubernetes finalizer dependencies: + +1. MTV Migrations +2. MTV Plans +3. NetworkMaps, StorageMaps +4. Providers +5. Provider/VDDK Secrets +6. Migrated VMs (optional) +7. PVCs (optional) +8. Target Namespaces (optional) +9. Operators: CRs → CSVs → Subscriptions → OperatorGroups → Namespaces (optional) + +## Example Playbook + +```yaml +- hosts: localhost + roles: + - role: infra.openshift_virtualization_migration.ocp_cleanup + vars: + ocp_cleanup_dry_run: true + ocp_cleanup_operators_remove: true +``` + +## ocp_cleanup + +``` +Role belongs to infra/openshift_virtualization_migration +Namespace - infra +Collection - openshift_virtualization_migration +Version - 1.25.0 +Repository - https://github.com/redhat-cop/openshift_virtualization_migration +``` + +Description: Remove OpenShift migration artifacts created during virtualization migration testing + +### Defaults + +**These are static variables with lower priority** + +#### File: defaults/main.yml + +| Var | Type | Value |Choices |Required | Title | +|--------------|--------------|-------------|-------------|-------------|-------------| +| [`ocp_cleanup_dry_run`](defaults/main.yml#L26) | bool | `False` | None | None | None | +| [`ocp_cleanup_migrated_vms_remove`](defaults/main.yml#L21) | bool | `False` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds`](defaults/main.yml#L95) | list | `[]` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.0`](defaults/main.yml#L96) | dict | `{}` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.0.api_version`](defaults/main.yml#L97) | str | `forklift.konveyor.io/v1beta1` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.0.kind`](defaults/main.yml#L96) | str | `Migration` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.1`](defaults/main.yml#L98) | dict | `{}` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.1.api_version`](defaults/main.yml#L99) | str | `forklift.konveyor.io/v1beta1` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.1.kind`](defaults/main.yml#L98) | str | `Plan` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.2`](defaults/main.yml#L100) | dict | `{}` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.2.api_version`](defaults/main.yml#L101) | str | `forklift.konveyor.io/v1beta1` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.2.kind`](defaults/main.yml#L100) | str | `NetworkMap` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.3`](defaults/main.yml#L102) | dict | `{}` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.3.api_version`](defaults/main.yml#L103) | str | `forklift.konveyor.io/v1beta1` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.3.kind`](defaults/main.yml#L102) | str | `StorageMap` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.4`](defaults/main.yml#L104) | dict | `{}` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.4.api_version`](defaults/main.yml#L105) | str | `forklift.konveyor.io/v1beta1` | None | None | None | +| [`ocp_cleanup_mtv_crd_kinds.4.kind`](defaults/main.yml#L104) | str | `Provider` | None | None | None | +| [`ocp_cleanup_mtv_maps_remove`](defaults/main.yml#L18) | bool | `True` | None | None | None | +| [`ocp_cleanup_mtv_migrations_remove`](defaults/main.yml#L16) | bool | `True` | None | None | None | +| [`ocp_cleanup_mtv_namespace`](defaults/main.yml#L10) | str | `{{ mtv_management_namespace ¦ default('openshift-mtv') }}` | None | None | None | +| [`ocp_cleanup_mtv_plans_remove`](defaults/main.yml#L17) | bool | `True` | None | None | None | +| [`ocp_cleanup_mtv_providers_remove`](defaults/main.yml#L19) | bool | `True` | None | None | None | +| [`ocp_cleanup_mtv_secrets_remove`](defaults/main.yml#L20) | bool | `True` | None | None | None | +| [`ocp_cleanup_openshift_api_key`](defaults/main.yml#L5) | str | `` | None | None | None | +| [`ocp_cleanup_openshift_host`](defaults/main.yml#L3) | str | `` | None | None | None | +| [`ocp_cleanup_openshift_verify_ssl`](defaults/main.yml#L7) | str | `{{ openshift_verify_ssl ¦ default(true) }}` | None | None | None | +| [`ocp_cleanup_operator_definitions`](defaults/main.yml#L40) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.acm`](defaults/main.yml#L57) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.acm.extra_resources`](defaults/main.yml#L61) | list | `[]` | None | None | None | +| [`ocp_cleanup_operator_definitions.acm.extra_resources.0`](defaults/main.yml#L62) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.acm.extra_resources.0.api_version`](defaults/main.yml#L62) | str | `operator.open-cluster-management.io/v1` | None | None | None | +| [`ocp_cleanup_operator_definitions.acm.extra_resources.0.kind`](defaults/main.yml#L63) | str | `MultiClusterHub` | None | None | None | +| [`ocp_cleanup_operator_definitions.acm.extra_resources.0.name`](defaults/main.yml#L64) | str | `multiclusterhub` | None | None | None | +| [`ocp_cleanup_operator_definitions.acm.namespace`](defaults/main.yml#L58) | str | `open-cluster-management` | None | None | None | +| [`ocp_cleanup_operator_definitions.acm.operatorgroup`](defaults/main.yml#L59) | str | `acm-operator` | None | None | None | +| [`ocp_cleanup_operator_definitions.acm.subscription`](defaults/main.yml#L60) | str | `advanced-cluster-management` | None | None | None | +| [`ocp_cleanup_operator_definitions.cnv`](defaults/main.yml#L49) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.cnv.extra_resources`](defaults/main.yml#L53) | list | `[]` | None | None | None | +| [`ocp_cleanup_operator_definitions.cnv.extra_resources.0`](defaults/main.yml#L54) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.cnv.extra_resources.0.api_version`](defaults/main.yml#L54) | str | `hco.kubevirt.io/v1beta1` | None | None | None | +| [`ocp_cleanup_operator_definitions.cnv.extra_resources.0.kind`](defaults/main.yml#L55) | str | `HyperConverged` | None | None | None | +| [`ocp_cleanup_operator_definitions.cnv.extra_resources.0.name`](defaults/main.yml#L56) | str | `kubevirt-hyperconverged` | None | None | None | +| [`ocp_cleanup_operator_definitions.cnv.namespace`](defaults/main.yml#L50) | str | `openshift-cnv` | None | None | None | +| [`ocp_cleanup_operator_definitions.cnv.operatorgroup`](defaults/main.yml#L51) | str | `kubevirt-hyperconverged-group` | None | None | None | +| [`ocp_cleanup_operator_definitions.cnv.subscription`](defaults/main.yml#L52) | str | `kubevirt-hyperconverged` | None | None | None | +| [`ocp_cleanup_operator_definitions.far`](defaults/main.yml#L70) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.far.extra_resources`](defaults/main.yml#L74) | list | `[]` | None | None | None | +| [`ocp_cleanup_operator_definitions.far.namespace`](defaults/main.yml#L71) | str | `openshift-workload-availability` | None | None | None | +| [`ocp_cleanup_operator_definitions.far.operatorgroup`](defaults/main.yml#L72) | str | `openshift-workload-availability-operator-group` | None | None | None | +| [`ocp_cleanup_operator_definitions.far.subscription`](defaults/main.yml#L73) | str | `fence-agents-remediation` | None | None | None | +| [`ocp_cleanup_operator_definitions.gitops`](defaults/main.yml#L88) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.gitops.extra_resources`](defaults/main.yml#L92) | list | `[]` | None | None | None | +| [`ocp_cleanup_operator_definitions.gitops.namespace`](defaults/main.yml#L89) | str | `openshift-gitops-operator` | None | None | None | +| [`ocp_cleanup_operator_definitions.gitops.operatorgroup`](defaults/main.yml#L90) | str | `openshift-gitops-operator-group` | None | None | None | +| [`ocp_cleanup_operator_definitions.gitops.subscription`](defaults/main.yml#L91) | str | `openshift-gitops-operator` | None | None | None | +| [`ocp_cleanup_operator_definitions.mtv`](defaults/main.yml#L41) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.mtv.extra_resources`](defaults/main.yml#L45) | list | `[]` | None | None | None | +| [`ocp_cleanup_operator_definitions.mtv.extra_resources.0`](defaults/main.yml#L46) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.mtv.extra_resources.0.api_version`](defaults/main.yml#L46) | str | `forklift.konveyor.io/v1beta1` | None | None | None | +| [`ocp_cleanup_operator_definitions.mtv.extra_resources.0.kind`](defaults/main.yml#L47) | str | `ForkliftController` | None | None | None | +| [`ocp_cleanup_operator_definitions.mtv.extra_resources.0.name`](defaults/main.yml#L48) | str | `forklift-controller` | None | None | None | +| [`ocp_cleanup_operator_definitions.mtv.namespace`](defaults/main.yml#L42) | str | `openshift-mtv` | None | None | None | +| [`ocp_cleanup_operator_definitions.mtv.operatorgroup`](defaults/main.yml#L43) | str | `migration` | None | None | None | +| [`ocp_cleanup_operator_definitions.mtv.subscription`](defaults/main.yml#L44) | str | `mtv-operator` | None | None | None | +| [`ocp_cleanup_operator_definitions.nho`](defaults/main.yml#L83) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.nho.extra_resources`](defaults/main.yml#L87) | list | `[]` | None | None | None | +| [`ocp_cleanup_operator_definitions.nho.namespace`](defaults/main.yml#L84) | str | `openshift-workload-availability` | None | None | None | +| [`ocp_cleanup_operator_definitions.nho.operatorgroup`](defaults/main.yml#L85) | str | `openshift-workload-availability-operator-group` | None | None | None | +| [`ocp_cleanup_operator_definitions.nho.subscription`](defaults/main.yml#L86) | str | `node-healthcheck-operator` | None | None | None | +| [`ocp_cleanup_operator_definitions.nmstate`](defaults/main.yml#L75) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.nmstate.extra_resources`](defaults/main.yml#L79) | list | `[]` | None | None | None | +| [`ocp_cleanup_operator_definitions.nmstate.extra_resources.0`](defaults/main.yml#L80) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.nmstate.extra_resources.0.api_version`](defaults/main.yml#L80) | str | `nmstate.io/v1` | None | None | None | +| [`ocp_cleanup_operator_definitions.nmstate.extra_resources.0.kind`](defaults/main.yml#L81) | str | `NMState` | None | None | None | +| [`ocp_cleanup_operator_definitions.nmstate.extra_resources.0.name`](defaults/main.yml#L82) | str | `nmstate` | None | None | None | +| [`ocp_cleanup_operator_definitions.nmstate.namespace`](defaults/main.yml#L76) | str | `openshift-nmstate` | None | None | None | +| [`ocp_cleanup_operator_definitions.nmstate.operatorgroup`](defaults/main.yml#L77) | str | `nmstate-operator-group` | None | None | None | +| [`ocp_cleanup_operator_definitions.nmstate.subscription`](defaults/main.yml#L78) | str | `kubernetes-nmstate-operator` | None | None | None | +| [`ocp_cleanup_operator_definitions.oadp`](defaults/main.yml#L65) | dict | `{}` | None | None | None | +| [`ocp_cleanup_operator_definitions.oadp.extra_resources`](defaults/main.yml#L69) | list | `[]` | None | None | None | +| [`ocp_cleanup_operator_definitions.oadp.namespace`](defaults/main.yml#L66) | str | `openshift-adp` | None | None | None | +| [`ocp_cleanup_operator_definitions.oadp.operatorgroup`](defaults/main.yml#L67) | str | `redhat-oadp-operator-group` | None | None | None | +| [`ocp_cleanup_operator_definitions.oadp.subscription`](defaults/main.yml#L68) | str | `redhat-oadp-operator` | None | None | None | +| [`ocp_cleanup_operators`](defaults/main.yml#L29) | list | `[]` | None | None | None | +| [`ocp_cleanup_operators.0`](defaults/main.yml#L30) | str | `mtv` | None | None | None | +| [`ocp_cleanup_operators.1`](defaults/main.yml#L31) | str | `cnv` | None | None | None | +| [`ocp_cleanup_operators.2`](defaults/main.yml#L32) | str | `acm` | None | None | None | +| [`ocp_cleanup_operators.3`](defaults/main.yml#L33) | str | `oadp` | None | None | None | +| [`ocp_cleanup_operators.4`](defaults/main.yml#L34) | str | `far` | None | None | None | +| [`ocp_cleanup_operators.5`](defaults/main.yml#L35) | str | `nmstate` | None | None | None | +| [`ocp_cleanup_operators.6`](defaults/main.yml#L36) | str | `nho` | None | None | None | +| [`ocp_cleanup_operators.7`](defaults/main.yml#L37) | str | `gitops` | None | None | None | +| [`ocp_cleanup_operators_remove`](defaults/main.yml#L23) | bool | `False` | None | None | None | +| [`ocp_cleanup_providers`](defaults/main.yml#L13) | str | `{{ cleanup_providers ¦ default(['vmware', 'ovirt']) }}` | None | None | None | +| [`ocp_cleanup_target_namespaces`](defaults/main.yml#L108) | list | `[]` | None | None | None | +| [`ocp_cleanup_target_namespaces_remove`](defaults/main.yml#L22) | bool | `False` | None | None | None | +| [`ocp_cleanup_wait_delay`](defaults/main.yml#L112) | int | `10` | None | None | None | +| [`ocp_cleanup_wait_retries`](defaults/main.yml#L111) | int | `60` | None | None | None | + +🖇️ Full descriptions for vars in defaults/main.yml +
+`ocp_cleanup_dry_run`: None +
+`ocp_cleanup_migrated_vms_remove`: None +
+`ocp_cleanup_mtv_crd_kinds`: None +
+`ocp_cleanup_mtv_crd_kinds.0`: None +
+`ocp_cleanup_mtv_crd_kinds.0.api_version`: None +
+`ocp_cleanup_mtv_crd_kinds.0.kind`: None +
+`ocp_cleanup_mtv_crd_kinds.1`: None +
+`ocp_cleanup_mtv_crd_kinds.1.api_version`: None +
+`ocp_cleanup_mtv_crd_kinds.1.kind`: None +
+`ocp_cleanup_mtv_crd_kinds.2`: None +
+`ocp_cleanup_mtv_crd_kinds.2.api_version`: None +
+`ocp_cleanup_mtv_crd_kinds.2.kind`: None +
+`ocp_cleanup_mtv_crd_kinds.3`: None +
+`ocp_cleanup_mtv_crd_kinds.3.api_version`: None +
+`ocp_cleanup_mtv_crd_kinds.3.kind`: None +
+`ocp_cleanup_mtv_crd_kinds.4`: None +
+`ocp_cleanup_mtv_crd_kinds.4.api_version`: None +
+`ocp_cleanup_mtv_crd_kinds.4.kind`: None +
+`ocp_cleanup_mtv_maps_remove`: None +
+`ocp_cleanup_mtv_migrations_remove`: None +
+`ocp_cleanup_mtv_namespace`: None +
+`ocp_cleanup_mtv_plans_remove`: None +
+`ocp_cleanup_mtv_providers_remove`: None +
+`ocp_cleanup_mtv_secrets_remove`: None +
+`ocp_cleanup_openshift_api_key`: None +
+`ocp_cleanup_openshift_host`: None +
+`ocp_cleanup_openshift_verify_ssl`: None +
+`ocp_cleanup_operator_definitions`: None +
+`ocp_cleanup_operator_definitions.acm`: None +
+`ocp_cleanup_operator_definitions.acm.extra_resources`: None +
+`ocp_cleanup_operator_definitions.acm.extra_resources.0`: None +
+`ocp_cleanup_operator_definitions.acm.extra_resources.0.api_version`: None +
+`ocp_cleanup_operator_definitions.acm.extra_resources.0.kind`: None +
+`ocp_cleanup_operator_definitions.acm.extra_resources.0.name`: None +
+`ocp_cleanup_operator_definitions.acm.namespace`: None +
+`ocp_cleanup_operator_definitions.acm.operatorgroup`: None +
+`ocp_cleanup_operator_definitions.acm.subscription`: None +
+`ocp_cleanup_operator_definitions.cnv`: None +
+`ocp_cleanup_operator_definitions.cnv.extra_resources`: None +
+`ocp_cleanup_operator_definitions.cnv.extra_resources.0`: None +
+`ocp_cleanup_operator_definitions.cnv.extra_resources.0.api_version`: None +
+`ocp_cleanup_operator_definitions.cnv.extra_resources.0.kind`: None +
+`ocp_cleanup_operator_definitions.cnv.extra_resources.0.name`: None +
+`ocp_cleanup_operator_definitions.cnv.namespace`: None +
+`ocp_cleanup_operator_definitions.cnv.operatorgroup`: None +
+`ocp_cleanup_operator_definitions.cnv.subscription`: None +
+`ocp_cleanup_operator_definitions.far`: None +
+`ocp_cleanup_operator_definitions.far.extra_resources`: None +
+`ocp_cleanup_operator_definitions.far.namespace`: None +
+`ocp_cleanup_operator_definitions.far.operatorgroup`: None +
+`ocp_cleanup_operator_definitions.far.subscription`: None +
+`ocp_cleanup_operator_definitions.gitops`: None +
+`ocp_cleanup_operator_definitions.gitops.extra_resources`: None +
+`ocp_cleanup_operator_definitions.gitops.namespace`: None +
+`ocp_cleanup_operator_definitions.gitops.operatorgroup`: None +
+`ocp_cleanup_operator_definitions.gitops.subscription`: None +
+`ocp_cleanup_operator_definitions.mtv`: None +
+`ocp_cleanup_operator_definitions.mtv.extra_resources`: None +
+`ocp_cleanup_operator_definitions.mtv.extra_resources.0`: None +
+`ocp_cleanup_operator_definitions.mtv.extra_resources.0.api_version`: None +
+`ocp_cleanup_operator_definitions.mtv.extra_resources.0.kind`: None +
+`ocp_cleanup_operator_definitions.mtv.extra_resources.0.name`: None +
+`ocp_cleanup_operator_definitions.mtv.namespace`: None +
+`ocp_cleanup_operator_definitions.mtv.operatorgroup`: None +
+`ocp_cleanup_operator_definitions.mtv.subscription`: None +
+`ocp_cleanup_operator_definitions.nho`: None +
+`ocp_cleanup_operator_definitions.nho.extra_resources`: None +
+`ocp_cleanup_operator_definitions.nho.namespace`: None +
+`ocp_cleanup_operator_definitions.nho.operatorgroup`: None +
+`ocp_cleanup_operator_definitions.nho.subscription`: None +
+`ocp_cleanup_operator_definitions.nmstate`: None +
+`ocp_cleanup_operator_definitions.nmstate.extra_resources`: None +
+`ocp_cleanup_operator_definitions.nmstate.extra_resources.0`: None +
+`ocp_cleanup_operator_definitions.nmstate.extra_resources.0.api_version`: None +
+`ocp_cleanup_operator_definitions.nmstate.extra_resources.0.kind`: None +
+`ocp_cleanup_operator_definitions.nmstate.extra_resources.0.name`: None +
+`ocp_cleanup_operator_definitions.nmstate.namespace`: None +
+`ocp_cleanup_operator_definitions.nmstate.operatorgroup`: None +
+`ocp_cleanup_operator_definitions.nmstate.subscription`: None +
+`ocp_cleanup_operator_definitions.oadp`: None +
+`ocp_cleanup_operator_definitions.oadp.extra_resources`: None +
+`ocp_cleanup_operator_definitions.oadp.namespace`: None +
+`ocp_cleanup_operator_definitions.oadp.operatorgroup`: None +
+`ocp_cleanup_operator_definitions.oadp.subscription`: None +
+`ocp_cleanup_operators`: None +
+`ocp_cleanup_operators.0`: None +
+`ocp_cleanup_operators.1`: None +
+`ocp_cleanup_operators.2`: None +
+`ocp_cleanup_operators.3`: None +
+`ocp_cleanup_operators.4`: None +
+`ocp_cleanup_operators.5`: None +
+`ocp_cleanup_operators.6`: None +
+`ocp_cleanup_operators.7`: None +
+`ocp_cleanup_operators_remove`: None +
+`ocp_cleanup_providers`: None +
+`ocp_cleanup_target_namespaces`: None +
+`ocp_cleanup_target_namespaces_remove`: None +
+`ocp_cleanup_wait_delay`: None +
+`ocp_cleanup_wait_retries`: None +
+
+ +### Tasks + +#### File: tasks/main.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| Remove MTV CRDs | `ansible.builtin.include_tasks` | True | +| Remove MTV secrets | `ansible.builtin.include_tasks` | True | +| Remove migrated VMs and PVCs | `ansible.builtin.include_tasks` | True | +| Remove target namespaces | `ansible.builtin.include_tasks` | True | +| Remove operators | `ansible.builtin.include_tasks` | True | + +#### File: tasks/_cleanup_migrated_vms.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _cleanup_migrated_vms ¦ Query migrated VirtualMachines across target namespaces | `kubernetes.core.k8s_info` | True | +| _cleanup_migrated_vms ¦ Flatten VM results | `ansible.builtin.set_fact` | False | +| _cleanup_migrated_vms ¦ Report VMs found | `ansible.builtin.debug` | False | +| _cleanup_migrated_vms ¦ Remove VirtualMachines | `redhat.openshift.k8s` | True | +| _cleanup_migrated_vms ¦ Query PVCs in target namespaces | `kubernetes.core.k8s_info` | True | +| _cleanup_migrated_vms ¦ Flatten PVC results | `ansible.builtin.set_fact` | False | +| _cleanup_migrated_vms ¦ Report PVCs found | `ansible.builtin.debug` | False | +| _cleanup_migrated_vms ¦ Remove PVCs | `redhat.openshift.k8s` | True | + +#### File: tasks/_cleanup_mtv_crds.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _cleanup_mtv_crds ¦ Query CRD resources — {{ _ocp_cleanup_crd.kind }} | `kubernetes.core.k8s_info` | False | +| _cleanup_mtv_crds ¦ Report CRD resources found — {{ _ocp_cleanup_crd.kind }} | `ansible.builtin.debug` | False | +| _cleanup_mtv_crds ¦ Display CRD resources — {{ _ocp_cleanup_crd.kind }} | `ansible.builtin.debug` | True | +| _cleanup_mtv_crds ¦ Remove CRD resources — {{ _ocp_cleanup_crd.kind }} | `redhat.openshift.k8s` | True | + +#### File: tasks/_cleanup_mtv_secrets.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _cleanup_mtv_secrets ¦ Query secrets in MTV namespace | `kubernetes.core.k8s_info` | False | +| _cleanup_mtv_secrets ¦ Filter provider and VDDK secrets | `ansible.builtin.set_fact` | True | +| _cleanup_mtv_secrets ¦ Report secrets found | `ansible.builtin.debug` | False | +| _cleanup_mtv_secrets ¦ Display secrets to remove | `ansible.builtin.debug` | True | +| _cleanup_mtv_secrets ¦ Remove provider and VDDK secrets | `redhat.openshift.k8s` | True | + +#### File: tasks/_cleanup_namespaces.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _cleanup_namespaces ¦ Report target namespaces | `ansible.builtin.debug` | False | +| _cleanup_namespaces ¦ Display target namespaces | `ansible.builtin.debug` | True | +| _cleanup_namespaces ¦ Remove target namespaces | `redhat.openshift.k8s` | True | + +#### File: tasks/_cleanup_operator_item.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _cleanup_operator_item ¦ Set operator definition — {{ _ocp_cleanup_operator_name }} | `ansible.builtin.set_fact` | False | +| _cleanup_operator_item ¦ Report operator — {{ _ocp_cleanup_operator_name }} | `ansible.builtin.debug` | False | +| _cleanup_operator_item ¦ Remove extra resources — {{ _ocp_cleanup_operator_name }} | `redhat.openshift.k8s` | True | +| _cleanup_operator_item ¦ Query CSVs — {{ _ocp_cleanup_operator_name }} | `kubernetes.core.k8s_info` | True | +| _cleanup_operator_item ¦ Remove CSVs — {{ _ocp_cleanup_operator_name }} | `redhat.openshift.k8s` | True | +| _cleanup_operator_item ¦ Remove Subscription — {{ _ocp_cleanup_operator_name }} | `redhat.openshift.k8s` | True | +| _cleanup_operator_item ¦ Remove OperatorGroup — {{ _ocp_cleanup_operator_name }} | `redhat.openshift.k8s` | True | +| _cleanup_operator_item ¦ Remove Namespace {{ _ocp_cleanup_op_def.namespace }} | `redhat.openshift.k8s` | True | + +#### File: tasks/_cleanup_operators.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _cleanup_operators ¦ Remove operators in reverse order | `ansible.builtin.include_tasks` | True | + +## Task Flow Graphs + +### Graph for _cleanup_migrated_vms.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Task| _cleanup_migrated_vms___Query_migrated_VirtualMachines_across_target_namespaces0[ cleanup migrated vms query migrated
virtualmachines across target namespaces
When: **ocp cleanup target namespaces length 0**]:::task + _cleanup_migrated_vms___Query_migrated_VirtualMachines_across_target_namespaces0-->|Task| _cleanup_migrated_vms___Flatten_VM_results1[ cleanup migrated vms flatten vm results]:::task + _cleanup_migrated_vms___Flatten_VM_results1-->|Task| _cleanup_migrated_vms___Report_VMs_found2[ cleanup migrated vms report vms found]:::task + _cleanup_migrated_vms___Report_VMs_found2-->|Task| _cleanup_migrated_vms___Remove_VirtualMachines3[ cleanup migrated vms remove virtualmachines
When: **ocp cleanup all vms length 0 and not ocp
cleanup dry run bool**]:::task + _cleanup_migrated_vms___Remove_VirtualMachines3-->|Task| _cleanup_migrated_vms___Query_PVCs_in_target_namespaces4[ cleanup migrated vms query pvcs in target
namespaces
When: **ocp cleanup target namespaces length 0**]:::task + _cleanup_migrated_vms___Query_PVCs_in_target_namespaces4-->|Task| _cleanup_migrated_vms___Flatten_PVC_results5[ cleanup migrated vms flatten pvc results]:::task + _cleanup_migrated_vms___Flatten_PVC_results5-->|Task| _cleanup_migrated_vms___Report_PVCs_found6[ cleanup migrated vms report pvcs found]:::task + _cleanup_migrated_vms___Report_PVCs_found6-->|Task| _cleanup_migrated_vms___Remove_PVCs7[ cleanup migrated vms remove pvcs
When: **ocp cleanup all pvcs length 0 and not ocp
cleanup dry run bool**]:::task + _cleanup_migrated_vms___Remove_PVCs7-->End +``` + +### Graph for _cleanup_mtv_crds.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Task| _cleanup_mtv_crds___Query_CRD_resources_______ocp_cleanup_crd_kind___0[ cleanup mtv crds query crd resources ocp
cleanup crd kind ]:::task + _cleanup_mtv_crds___Query_CRD_resources_______ocp_cleanup_crd_kind___0-->|Task| _cleanup_mtv_crds___Report_CRD_resources_found_______ocp_cleanup_crd_kind___1[ cleanup mtv crds report crd resources found
ocp cleanup crd kind ]:::task + _cleanup_mtv_crds___Report_CRD_resources_found_______ocp_cleanup_crd_kind___1-->|Task| _cleanup_mtv_crds___Display_CRD_resources_______ocp_cleanup_crd_kind___2[ cleanup mtv crds display crd resources
ocp cleanup crd kind
When: **ocp cleanup crd results is not failed and ocp
cleanup crd results resources default
length 0**]:::task + _cleanup_mtv_crds___Display_CRD_resources_______ocp_cleanup_crd_kind___2-->|Task| _cleanup_mtv_crds___Remove_CRD_resources_______ocp_cleanup_crd_kind___3[ cleanup mtv crds remove crd resources ocp
cleanup crd kind
When: **ocp cleanup crd results is not failed and ocp
cleanup crd results resources default
length 0 and not ocp cleanup dry run bool**]:::task + _cleanup_mtv_crds___Remove_CRD_resources_______ocp_cleanup_crd_kind___3-->End +``` + +### Graph for _cleanup_mtv_secrets.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Task| _cleanup_mtv_secrets___Query_secrets_in_MTV_namespace0[ cleanup mtv secrets query secrets in mtv
namespace]:::task + _cleanup_mtv_secrets___Query_secrets_in_MTV_namespace0-->|Task| _cleanup_mtv_secrets___Filter_provider_and_VDDK_secrets1[ cleanup mtv secrets filter provider and vddk
secrets
When: **ocp cleanup secrets result is not failed**]:::task + _cleanup_mtv_secrets___Filter_provider_and_VDDK_secrets1-->|Task| _cleanup_mtv_secrets___Report_secrets_found2[ cleanup mtv secrets report secrets found]:::task + _cleanup_mtv_secrets___Report_secrets_found2-->|Task| _cleanup_mtv_secrets___Display_secrets_to_remove3[ cleanup mtv secrets display secrets to remove
When: **ocp cleanup target secrets default
length 0**]:::task + _cleanup_mtv_secrets___Display_secrets_to_remove3-->|Task| _cleanup_mtv_secrets___Remove_provider_and_VDDK_secrets4[ cleanup mtv secrets remove provider and vddk
secrets
When: **ocp cleanup target secrets default
length 0 and not ocp cleanup dry run bool**]:::task + _cleanup_mtv_secrets___Remove_provider_and_VDDK_secrets4-->End +``` + +### Graph for _cleanup_namespaces.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Task| _cleanup_namespaces___Report_target_namespaces0[ cleanup namespaces report target namespaces]:::task + _cleanup_namespaces___Report_target_namespaces0-->|Task| _cleanup_namespaces___Display_target_namespaces1[ cleanup namespaces display target namespaces
When: **ocp cleanup target namespaces length 0**]:::task + _cleanup_namespaces___Display_target_namespaces1-->|Task| _cleanup_namespaces___Remove_target_namespaces2[ cleanup namespaces remove target namespaces
When: **ocp cleanup target namespaces length 0 and not
ocp cleanup dry run bool**]:::task + _cleanup_namespaces___Remove_target_namespaces2-->End +``` + +### Graph for _cleanup_operator_item.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Task| _cleanup_operator_item___Set_operator_definition____ocp_cleanup_operator_name0[ cleanup operator item set operator definition
ocp cleanup operator name]:::task + _cleanup_operator_item___Set_operator_definition____ocp_cleanup_operator_name0-->|Task| _cleanup_operator_item___Report_operator____ocp_cleanup_operator_name1[ cleanup operator item report operator ocp
cleanup operator name]:::task + _cleanup_operator_item___Report_operator____ocp_cleanup_operator_name1-->|Task| _cleanup_operator_item___Remove_extra_resources____ocp_cleanup_operator_name2[ cleanup operator item remove extra resources
ocp cleanup operator name
When: **ocp cleanup op def extra resources length 0
and not ocp cleanup dry run bool**]:::task + _cleanup_operator_item___Remove_extra_resources____ocp_cleanup_operator_name2-->|Task| _cleanup_operator_item___Query_CSVs____ocp_cleanup_operator_name3[ cleanup operator item query csvs ocp cleanup
operator name
When: **not ocp cleanup dry run bool**]:::task + _cleanup_operator_item___Query_CSVs____ocp_cleanup_operator_name3-->|Task| _cleanup_operator_item___Remove_CSVs____ocp_cleanup_operator_name4[ cleanup operator item remove csvs ocp
cleanup operator name
When: **not ocp cleanup dry run bool and ocp cleanup
csvs resources default length 0**]:::task + _cleanup_operator_item___Remove_CSVs____ocp_cleanup_operator_name4-->|Task| _cleanup_operator_item___Remove_Subscription____ocp_cleanup_operator_name5[ cleanup operator item remove subscription
ocp cleanup operator name
When: **not ocp cleanup dry run bool**]:::task + _cleanup_operator_item___Remove_Subscription____ocp_cleanup_operator_name5-->|Task| _cleanup_operator_item___Remove_OperatorGroup____ocp_cleanup_operator_name6[ cleanup operator item remove operatorgroup
ocp cleanup operator name
When: **not ocp cleanup dry run bool**]:::task + _cleanup_operator_item___Remove_OperatorGroup____ocp_cleanup_operator_name6-->|Task| _cleanup_operator_item___Remove_Namespace_____ocp_cleanup_op_def_namespace___7[ cleanup operator item remove namespace ocp
cleanup op def namespace
When: **not ocp cleanup dry run bool**]:::task + _cleanup_operator_item___Remove_Namespace_____ocp_cleanup_op_def_namespace___7-->End +``` + +### Graph for _cleanup_operators.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Include task| _cleanup_operators___Remove_operators_in_reverse_order__cleanup_operator_item_yml_0[ cleanup operators remove operators in reverse
order
When: **ocp cleanup operator name in ocp cleanup operator
definitions**
include_task: cleanup operator item yml]:::includeTasks + _cleanup_operators___Remove_operators_in_reverse_order__cleanup_operator_item_yml_0-->End +``` + +### Graph for main.yml + +```mermaid +flowchart TD +Start +classDef block stroke:#3498db,stroke-width:2px; +classDef task stroke:#4b76bb,stroke-width:2px; +classDef includeTasks stroke:#16a085,stroke-width:2px; +classDef importTasks stroke:#34495e,stroke-width:2px; +classDef includeRole stroke:#2980b9,stroke-width:2px; +classDef importRole stroke:#699ba7,stroke-width:2px; +classDef includeVars stroke:#8e44ad,stroke-width:2px; +classDef rescue stroke:#665352,stroke-width:2px; + + Start-->|Include task| Remove_MTV_CRDs__cleanup_mtv_crds_yml_0[remove mtv crds
When: **ocp cleanup mtv migrations remove bool and ocp
cleanup crd kind migration or ocp cleanup
mtv plans remove bool and ocp cleanup crd kind
plan or ocp cleanup mtv maps remove bool
and ocp cleanup crd kind in networkmap
storagemap or ocp cleanup mtv providers remove
bool and ocp cleanup crd kind provider**
include_task: cleanup mtv crds yml]:::includeTasks + Remove_MTV_CRDs__cleanup_mtv_crds_yml_0-->|Include task| Remove_MTV_secrets__cleanup_mtv_secrets_yml_1[remove mtv secrets
When: **ocp cleanup mtv secrets remove bool**
include_task: cleanup mtv secrets yml]:::includeTasks + Remove_MTV_secrets__cleanup_mtv_secrets_yml_1-->|Include task| Remove_migrated_VMs_and_PVCs__cleanup_migrated_vms_yml_2[remove migrated vms and pvcs
When: **ocp cleanup migrated vms remove bool**
include_task: cleanup migrated vms yml]:::includeTasks + Remove_migrated_VMs_and_PVCs__cleanup_migrated_vms_yml_2-->|Include task| Remove_target_namespaces__cleanup_namespaces_yml_3[remove target namespaces
When: **ocp cleanup target namespaces remove bool**
include_task: cleanup namespaces yml]:::includeTasks + Remove_target_namespaces__cleanup_namespaces_yml_3-->|Include task| Remove_operators__cleanup_operators_yml_4[remove operators
When: **ocp cleanup operators remove bool**
include_task: cleanup operators yml]:::includeTasks + Remove_operators__cleanup_operators_yml_4-->End +``` + +## Author Information + +Red Hat + +## License + +GPL-3.0-or-later + +## Minimum Ansible Version + +2.15 + +## Platforms + +* **EL**: ['9'] + + \ No newline at end of file diff --git a/roles/ocp_cleanup/defaults/main.yml b/roles/ocp_cleanup/defaults/main.yml new file mode 100644 index 0000000..28bda42 --- /dev/null +++ b/roles/ocp_cleanup/defaults/main.yml @@ -0,0 +1,113 @@ +--- +# OpenShift connection +ocp_cleanup_openshift_host: >- + {{ openshift_host | default(lookup('ansible.builtin.env', 'K8S_AUTH_HOST')) }} +ocp_cleanup_openshift_api_key: >- + {{ openshift_api_key | default(lookup('ansible.builtin.env', 'K8S_AUTH_API_KEY')) }} +ocp_cleanup_openshift_verify_ssl: "{{ openshift_verify_ssl | default(true) }}" + +# MTV namespace +ocp_cleanup_mtv_namespace: "{{ mtv_management_namespace | default('openshift-mtv') }}" + +# Provider filtering +ocp_cleanup_providers: "{{ cleanup_providers | default(['vmware', 'ovirt']) }}" + +# Scope toggles +ocp_cleanup_mtv_migrations_remove: true +ocp_cleanup_mtv_plans_remove: true +ocp_cleanup_mtv_maps_remove: true +ocp_cleanup_mtv_providers_remove: true +ocp_cleanup_mtv_secrets_remove: true +ocp_cleanup_migrated_vms_remove: false +ocp_cleanup_target_namespaces_remove: false +ocp_cleanup_operators_remove: false + +# Dry-run mode — query and report only, no deletions +ocp_cleanup_dry_run: false + +# Operator list — matches operator_management_default_operators +ocp_cleanup_operators: + - mtv + - cnv + - acm + - oadp + - far + - nmstate + - nho + - gitops + +# Operator definitions — mirrors operator_management defaults +ocp_cleanup_operator_definitions: + mtv: + namespace: openshift-mtv + operatorgroup: migration + subscription: mtv-operator + extra_resources: + - api_version: forklift.konveyor.io/v1beta1 + kind: ForkliftController + name: forklift-controller + cnv: + namespace: openshift-cnv + operatorgroup: kubevirt-hyperconverged-group + subscription: kubevirt-hyperconverged + extra_resources: + - api_version: hco.kubevirt.io/v1beta1 + kind: HyperConverged + name: kubevirt-hyperconverged + acm: + namespace: open-cluster-management + operatorgroup: acm-operator + subscription: advanced-cluster-management + extra_resources: + - api_version: operator.open-cluster-management.io/v1 + kind: MultiClusterHub + name: multiclusterhub + oadp: + namespace: openshift-adp + operatorgroup: redhat-oadp-operator-group + subscription: redhat-oadp-operator + extra_resources: [] + far: + namespace: openshift-workload-availability + operatorgroup: openshift-workload-availability-operator-group + subscription: fence-agents-remediation + extra_resources: [] + nmstate: + namespace: openshift-nmstate + operatorgroup: nmstate-operator-group + subscription: kubernetes-nmstate-operator + extra_resources: + - api_version: nmstate.io/v1 + kind: NMState + name: nmstate + nho: + namespace: openshift-workload-availability + operatorgroup: openshift-workload-availability-operator-group + subscription: node-healthcheck-operator + extra_resources: [] + gitops: + namespace: openshift-gitops-operator + operatorgroup: openshift-gitops-operator-group + subscription: openshift-gitops-operator + extra_resources: [] + +# MTV CRD kinds to clean (in dependency order) +ocp_cleanup_mtv_crd_kinds: + - kind: Migration + api_version: forklift.konveyor.io/v1beta1 + - kind: Plan + api_version: forklift.konveyor.io/v1beta1 + - kind: NetworkMap + api_version: forklift.konveyor.io/v1beta1 + - kind: StorageMap + api_version: forklift.konveyor.io/v1beta1 + - kind: Provider + api_version: forklift.konveyor.io/v1beta1 + +# Target namespaces for migrated VMs +ocp_cleanup_target_namespaces: [] + +# Wait/retry settings +ocp_cleanup_wait_retries: 60 +ocp_cleanup_wait_delay: 10 +... diff --git a/roles/ocp_cleanup/meta/main.yml b/roles/ocp_cleanup/meta/main.yml new file mode 100644 index 0000000..ca59b00 --- /dev/null +++ b/roles/ocp_cleanup/meta/main.yml @@ -0,0 +1,19 @@ +--- +galaxy_info: + author: Red Hat + description: Remove OpenShift migration artifacts created during virtualization migration testing + license: GPL-3.0-or-later + min_ansible_version: "2.15" + platforms: + - name: EL + versions: + - "9" + galaxy_tags: + - openshift + - cleanup + - migration + - virtualization + - mtv + - kubernetes +dependencies: [] +... diff --git a/roles/ocp_cleanup/tasks/_cleanup_migrated_vms.yml b/roles/ocp_cleanup/tasks/_cleanup_migrated_vms.yml new file mode 100644 index 0000000..eac8dee --- /dev/null +++ b/roles/ocp_cleanup/tasks/_cleanup_migrated_vms.yml @@ -0,0 +1,93 @@ +--- +- name: _cleanup_migrated_vms | Query migrated VirtualMachines across target namespaces + kubernetes.core.k8s_info: + api_version: kubevirt.io/v1 + kind: VirtualMachine + namespace: "{{ item }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + register: _ocp_cleanup_vms_result + loop: "{{ ocp_cleanup_target_namespaces }}" + failed_when: false + when: ocp_cleanup_target_namespaces | length > 0 + +- name: _cleanup_migrated_vms | Flatten VM results + ansible.builtin.set_fact: + _ocp_cleanup_all_vms: >- + {{ _ocp_cleanup_vms_result.results | default([]) + | selectattr('resources', 'defined') + | map(attribute='resources') + | flatten + | list }} + +- name: _cleanup_migrated_vms | Report VMs found + ansible.builtin.debug: + msg: >- + VirtualMachines: found {{ _ocp_cleanup_all_vms | length }} VM(s) + {{ '— DRY RUN, skipping deletion' if ocp_cleanup_dry_run else '— removing' }} + +- name: _cleanup_migrated_vms | Remove VirtualMachines + when: + - _ocp_cleanup_all_vms | length > 0 + - not (ocp_cleanup_dry_run | bool) + redhat.openshift.k8s: + state: absent + api_version: kubevirt.io/v1 + kind: VirtualMachine + name: "{{ item.metadata.name }}" + namespace: "{{ item.metadata.namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + wait: true + wait_timeout: "{{ ocp_cleanup_wait_retries * ocp_cleanup_wait_delay }}" + loop: "{{ _ocp_cleanup_all_vms }}" + loop_control: + label: "{{ item.metadata.namespace }}/{{ item.metadata.name }}" + +- name: _cleanup_migrated_vms | Query PVCs in target namespaces + kubernetes.core.k8s_info: + api_version: v1 + kind: PersistentVolumeClaim + namespace: "{{ item }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + register: _ocp_cleanup_pvcs_result + loop: "{{ ocp_cleanup_target_namespaces }}" + failed_when: false + when: ocp_cleanup_target_namespaces | length > 0 + +- name: _cleanup_migrated_vms | Flatten PVC results + ansible.builtin.set_fact: + _ocp_cleanup_all_pvcs: >- + {{ _ocp_cleanup_pvcs_result.results | default([]) + | selectattr('resources', 'defined') + | map(attribute='resources') + | flatten + | list }} + +- name: _cleanup_migrated_vms | Report PVCs found + ansible.builtin.debug: + msg: >- + PVCs: found {{ _ocp_cleanup_all_pvcs | length }} PVC(s) + {{ '— DRY RUN, skipping deletion' if ocp_cleanup_dry_run else '— removing' }} + +- name: _cleanup_migrated_vms | Remove PVCs + when: + - _ocp_cleanup_all_pvcs | length > 0 + - not (ocp_cleanup_dry_run | bool) + redhat.openshift.k8s: + state: absent + api_version: v1 + kind: PersistentVolumeClaim + name: "{{ item.metadata.name }}" + namespace: "{{ item.metadata.namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + loop: "{{ _ocp_cleanup_all_pvcs }}" + loop_control: + label: "{{ item.metadata.namespace }}/{{ item.metadata.name }}" +... diff --git a/roles/ocp_cleanup/tasks/_cleanup_mtv_crds.yml b/roles/ocp_cleanup/tasks/_cleanup_mtv_crds.yml new file mode 100644 index 0000000..ad93991 --- /dev/null +++ b/roles/ocp_cleanup/tasks/_cleanup_mtv_crds.yml @@ -0,0 +1,45 @@ +--- +- name: "_cleanup_mtv_crds | Query CRD resources — {{ _ocp_cleanup_crd.kind }}" + kubernetes.core.k8s_info: + api_version: "{{ _ocp_cleanup_crd.api_version }}" + kind: "{{ _ocp_cleanup_crd.kind }}" + namespace: "{{ ocp_cleanup_mtv_namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + register: _ocp_cleanup_crd_results + failed_when: false + +- name: "_cleanup_mtv_crds | Report CRD resources found — {{ _ocp_cleanup_crd.kind }}" + ansible.builtin.debug: + msg: >- + {{ _ocp_cleanup_crd.kind }}: found {{ (_ocp_cleanup_crd_results.resources | default([])) | length }} resource(s) + {{ '— DRY RUN, skipping deletion' if ocp_cleanup_dry_run else '— removing' }} + +- name: "_cleanup_mtv_crds | Display CRD resources — {{ _ocp_cleanup_crd.kind }}" + when: + - _ocp_cleanup_crd_results is not failed + - _ocp_cleanup_crd_results.resources | default([]) | length > 0 + ansible.builtin.debug: + msg: "{{ _ocp_cleanup_crd_results.resources | map(attribute='metadata') | map(attribute='name') | list }}" + +- name: "_cleanup_mtv_crds | Remove CRD resources — {{ _ocp_cleanup_crd.kind }}" + when: + - _ocp_cleanup_crd_results is not failed + - _ocp_cleanup_crd_results.resources | default([]) | length > 0 + - not (ocp_cleanup_dry_run | bool) + redhat.openshift.k8s: + state: absent + api_version: "{{ _ocp_cleanup_crd.api_version }}" + kind: "{{ _ocp_cleanup_crd.kind }}" + name: "{{ item.metadata.name }}" + namespace: "{{ item.metadata.namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + wait: true + wait_timeout: "{{ ocp_cleanup_wait_retries * ocp_cleanup_wait_delay }}" + loop: "{{ _ocp_cleanup_crd_results.resources }}" + loop_control: + label: "{{ item.metadata.name }}" +... diff --git a/roles/ocp_cleanup/tasks/_cleanup_mtv_secrets.yml b/roles/ocp_cleanup/tasks/_cleanup_mtv_secrets.yml new file mode 100644 index 0000000..7febb72 --- /dev/null +++ b/roles/ocp_cleanup/tasks/_cleanup_mtv_secrets.yml @@ -0,0 +1,49 @@ +--- +- name: _cleanup_mtv_secrets | Query secrets in MTV namespace + kubernetes.core.k8s_info: + api_version: v1 + kind: Secret + namespace: "{{ ocp_cleanup_mtv_namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + register: _ocp_cleanup_secrets_result + failed_when: false + +- name: _cleanup_mtv_secrets | Filter provider and VDDK secrets + when: _ocp_cleanup_secrets_result is not failed + ansible.builtin.set_fact: + _ocp_cleanup_target_secrets: >- + {{ _ocp_cleanup_secrets_result.resources | default([]) + | selectattr('type', 'equalto', 'Opaque') + | rejectattr('metadata.name', 'match', '^(default-token|builder-token|deployer-token|sh\.helm)') + | list }} + +- name: _cleanup_mtv_secrets | Report secrets found + ansible.builtin.debug: + msg: >- + Secrets: found {{ (_ocp_cleanup_target_secrets | default([])) | length }} migration secret(s) + {{ '— DRY RUN, skipping deletion' if ocp_cleanup_dry_run else '— removing' }} + +- name: _cleanup_mtv_secrets | Display secrets to remove + when: (_ocp_cleanup_target_secrets | default([])) | length > 0 + ansible.builtin.debug: + msg: "{{ _ocp_cleanup_target_secrets | map(attribute='metadata') | map(attribute='name') | list }}" + +- name: _cleanup_mtv_secrets | Remove provider and VDDK secrets + when: + - (_ocp_cleanup_target_secrets | default([])) | length > 0 + - not (ocp_cleanup_dry_run | bool) + redhat.openshift.k8s: + state: absent + api_version: v1 + kind: Secret + name: "{{ item.metadata.name }}" + namespace: "{{ ocp_cleanup_mtv_namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + loop: "{{ _ocp_cleanup_target_secrets }}" + loop_control: + label: "{{ item.metadata.name }}" +... diff --git a/roles/ocp_cleanup/tasks/_cleanup_namespaces.yml b/roles/ocp_cleanup/tasks/_cleanup_namespaces.yml new file mode 100644 index 0000000..9e41e56 --- /dev/null +++ b/roles/ocp_cleanup/tasks/_cleanup_namespaces.yml @@ -0,0 +1,31 @@ +--- +- name: _cleanup_namespaces | Report target namespaces + ansible.builtin.debug: + msg: >- + Target namespaces: {{ ocp_cleanup_target_namespaces | length }} namespace(s) to remove + {{ '— DRY RUN, skipping deletion' if ocp_cleanup_dry_run else '— removing' }} + +- name: _cleanup_namespaces | Display target namespaces + when: ocp_cleanup_target_namespaces | length > 0 + ansible.builtin.debug: + msg: "{{ ocp_cleanup_target_namespaces }}" + +- name: _cleanup_namespaces | Remove target namespaces + when: + - ocp_cleanup_target_namespaces | length > 0 + - not (ocp_cleanup_dry_run | bool) + redhat.openshift.k8s: + state: absent + api_version: v1 + kind: Namespace + name: "{{ item }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + wait: true + wait_timeout: "{{ ocp_cleanup_wait_retries * ocp_cleanup_wait_delay }}" + loop: "{{ ocp_cleanup_target_namespaces }}" + loop_control: + label: "{{ item }}" + failed_when: false +... diff --git a/roles/ocp_cleanup/tasks/_cleanup_operator_item.yml b/roles/ocp_cleanup/tasks/_cleanup_operator_item.yml new file mode 100644 index 0000000..76778b5 --- /dev/null +++ b/roles/ocp_cleanup/tasks/_cleanup_operator_item.yml @@ -0,0 +1,101 @@ +--- +- name: "_cleanup_operator_item | Set operator definition — {{ _ocp_cleanup_operator_name }}" + ansible.builtin.set_fact: + _ocp_cleanup_op_def: "{{ ocp_cleanup_operator_definitions[_ocp_cleanup_operator_name] }}" + +- name: "_cleanup_operator_item | Report operator — {{ _ocp_cleanup_operator_name }}" + ansible.builtin.debug: + msg: >- + Operator {{ _ocp_cleanup_operator_name }}: namespace={{ _ocp_cleanup_op_def.namespace }} + {{ '— DRY RUN, skipping removal' if ocp_cleanup_dry_run else '— removing' }} + +- name: "_cleanup_operator_item | Remove extra resources — {{ _ocp_cleanup_operator_name }}" + when: + - _ocp_cleanup_op_def.extra_resources | length > 0 + - not (ocp_cleanup_dry_run | bool) + redhat.openshift.k8s: + state: absent + api_version: "{{ item.api_version }}" + kind: "{{ item.kind }}" + name: "{{ item.name }}" + namespace: "{{ _ocp_cleanup_op_def.namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + wait: true + wait_timeout: "{{ ocp_cleanup_wait_retries * ocp_cleanup_wait_delay }}" + loop: "{{ _ocp_cleanup_op_def.extra_resources }}" + loop_control: + label: "{{ item.kind }}/{{ item.name }}" + failed_when: false + +- name: "_cleanup_operator_item | Query CSVs — {{ _ocp_cleanup_operator_name }}" + when: not (ocp_cleanup_dry_run | bool) + kubernetes.core.k8s_info: + api_version: operators.coreos.com/v1alpha1 + kind: ClusterServiceVersion + namespace: "{{ _ocp_cleanup_op_def.namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + register: _ocp_cleanup_csvs + failed_when: false + +- name: "_cleanup_operator_item | Remove CSVs — {{ _ocp_cleanup_operator_name }}" + when: + - not (ocp_cleanup_dry_run | bool) + - _ocp_cleanup_csvs.resources | default([]) | length > 0 + redhat.openshift.k8s: + state: absent + api_version: operators.coreos.com/v1alpha1 + kind: ClusterServiceVersion + name: "{{ item.metadata.name }}" + namespace: "{{ _ocp_cleanup_op_def.namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + loop: "{{ _ocp_cleanup_csvs.resources | default([]) }}" + loop_control: + label: "{{ item.metadata.name }}" + failed_when: false + +- name: "_cleanup_operator_item | Remove Subscription — {{ _ocp_cleanup_operator_name }}" + when: not (ocp_cleanup_dry_run | bool) + redhat.openshift.k8s: + state: absent + api_version: operators.coreos.com/v1alpha1 + kind: Subscription + name: "{{ _ocp_cleanup_op_def.subscription }}" + namespace: "{{ _ocp_cleanup_op_def.namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + failed_when: false + +- name: "_cleanup_operator_item | Remove OperatorGroup — {{ _ocp_cleanup_operator_name }}" + when: not (ocp_cleanup_dry_run | bool) + redhat.openshift.k8s: + state: absent + api_version: operators.coreos.com/v1 + kind: OperatorGroup + name: "{{ _ocp_cleanup_op_def.operatorgroup }}" + namespace: "{{ _ocp_cleanup_op_def.namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + failed_when: false + +- name: "_cleanup_operator_item | Remove Namespace {{ _ocp_cleanup_op_def.namespace }}" + when: not (ocp_cleanup_dry_run | bool) + redhat.openshift.k8s: + state: absent + api_version: v1 + kind: Namespace + name: "{{ _ocp_cleanup_op_def.namespace }}" + host: "{{ ocp_cleanup_openshift_host | default(omit) }}" + api_key: "{{ ocp_cleanup_openshift_api_key | default(omit) }}" + validate_certs: "{{ ocp_cleanup_openshift_verify_ssl }}" + wait: true + wait_timeout: "{{ ocp_cleanup_wait_retries * ocp_cleanup_wait_delay }}" + failed_when: false +... diff --git a/roles/ocp_cleanup/tasks/_cleanup_operators.yml b/roles/ocp_cleanup/tasks/_cleanup_operators.yml new file mode 100644 index 0000000..ce3d877 --- /dev/null +++ b/roles/ocp_cleanup/tasks/_cleanup_operators.yml @@ -0,0 +1,10 @@ +--- +- name: _cleanup_operators | Remove operators in reverse order + ansible.builtin.include_tasks: + file: _cleanup_operator_item.yml + loop: "{{ ocp_cleanup_operators | reverse | list }}" + loop_control: + loop_var: _ocp_cleanup_operator_name + label: "{{ _ocp_cleanup_operator_name }}" + when: _ocp_cleanup_operator_name in ocp_cleanup_operator_definitions +... diff --git a/roles/ocp_cleanup/tasks/main.yml b/roles/ocp_cleanup/tasks/main.yml new file mode 100644 index 0000000..ce61fa5 --- /dev/null +++ b/roles/ocp_cleanup/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: Remove MTV CRDs + ansible.builtin.include_tasks: + file: _cleanup_mtv_crds.yml + loop: "{{ ocp_cleanup_mtv_crd_kinds }}" + loop_control: + loop_var: _ocp_cleanup_crd + label: "{{ _ocp_cleanup_crd.kind }}" + when: >- + (ocp_cleanup_mtv_migrations_remove | bool and _ocp_cleanup_crd.kind == 'Migration') or + (ocp_cleanup_mtv_plans_remove | bool and _ocp_cleanup_crd.kind == 'Plan') or + (ocp_cleanup_mtv_maps_remove | bool and _ocp_cleanup_crd.kind in ['NetworkMap', 'StorageMap']) or + (ocp_cleanup_mtv_providers_remove | bool and _ocp_cleanup_crd.kind == 'Provider') + +- name: Remove MTV secrets + ansible.builtin.include_tasks: + file: _cleanup_mtv_secrets.yml + when: ocp_cleanup_mtv_secrets_remove | bool + +- name: Remove migrated VMs and PVCs + ansible.builtin.include_tasks: + file: _cleanup_migrated_vms.yml + when: ocp_cleanup_migrated_vms_remove | bool + +- name: Remove target namespaces + ansible.builtin.include_tasks: + file: _cleanup_namespaces.yml + when: ocp_cleanup_target_namespaces_remove | bool + +- name: Remove operators + ansible.builtin.include_tasks: + file: _cleanup_operators.yml + when: ocp_cleanup_operators_remove | bool +... diff --git a/tests/integration/targets/cleanup_aap/defaults/main.yml b/tests/integration/targets/cleanup_aap/defaults/main.yml new file mode 100644 index 0000000..15063e2 --- /dev/null +++ b/tests/integration/targets/cleanup_aap/defaults/main.yml @@ -0,0 +1,3 @@ +--- +test_aap_cleanup_dry_run: true +... diff --git a/tests/integration/targets/cleanup_aap/tasks/main.yml b/tests/integration/targets/cleanup_aap/tasks/main.yml new file mode 100644 index 0000000..6d632ae --- /dev/null +++ b/tests/integration/targets/cleanup_aap/tasks/main.yml @@ -0,0 +1,13 @@ +--- +- name: Verify aap_cleanup role is available in collection + ansible.builtin.command: + cmd: ansible-doc --type role infra.openshift_virtualization_migration.aap_cleanup --json + register: _cleanup_aap_doc + changed_when: false + +- name: Assert aap_cleanup role documentation is accessible + ansible.builtin.assert: + that: + - _cleanup_aap_doc.rc == 0 + fail_msg: "aap_cleanup role not found in installed collection" +... diff --git a/tests/integration/targets/cleanup_ocp/defaults/main.yml b/tests/integration/targets/cleanup_ocp/defaults/main.yml new file mode 100644 index 0000000..8ba4918 --- /dev/null +++ b/tests/integration/targets/cleanup_ocp/defaults/main.yml @@ -0,0 +1,3 @@ +--- +test_ocp_cleanup_dry_run: true +... diff --git a/tests/integration/targets/cleanup_ocp/tasks/main.yml b/tests/integration/targets/cleanup_ocp/tasks/main.yml new file mode 100644 index 0000000..93dcafc --- /dev/null +++ b/tests/integration/targets/cleanup_ocp/tasks/main.yml @@ -0,0 +1,13 @@ +--- +- name: Verify ocp_cleanup role is available in collection + ansible.builtin.command: + cmd: ansible-doc --type role infra.openshift_virtualization_migration.ocp_cleanup --json + register: _cleanup_ocp_doc + changed_when: false + +- name: Assert ocp_cleanup role documentation is accessible + ansible.builtin.assert: + that: + - _cleanup_ocp_doc.rc == 0 + fail_msg: "ocp_cleanup role not found in installed collection" +...