diff --git a/playbooks/validate_migration.yml b/playbooks/validate_migration.yml new file mode 100644 index 0000000..cd6ff85 --- /dev/null +++ b/playbooks/validate_migration.yml @@ -0,0 +1,11 @@ +--- + +- name: Validate Migration + hosts: localhost + connection: local + gather_facts: false + tasks: + - name: Invoke Validate Migration + ansible.builtin.include_role: + name: infra.openshift_virtualization_migration.validate_migration +... diff --git a/roles/validate_migration/README.md b/roles/validate_migration/README.md index e894f69..cd2e9f5 100644 --- a/roles/validate_migration/README.md +++ b/roles/validate_migration/README.md @@ -26,8 +26,10 @@ Description: Verification of an Ansible for OpenShift Virtualization Migration e | Var | Type | Value |Choices |Required | Title | |--------------|--------------|-------------|-------------|-------------|-------------| +| [`validate_migration_check_vm_running`](defaults/main.yml#L44) | bool | `True` | None | False | Check VM Running Status | | [`validate_migration_cluster_name`](defaults/main.yml#L20) | str | `cluster01` | None | None | None | | [`validate_migration_debug`](defaults/main.yml#L18) | bool | `True` | None | None | None | +| [`validate_migration_expected_dv_phase`](defaults/main.yml#L52) | str | `Succeeded` | None | False | Expected DataVolume Phase | | [`validate_migration_expected_provisioners`](defaults/main.yml#L3) | list | `[]` | None | None | None | | [`validate_migration_expected_provisioners.0`](defaults/main.yml#L4) | str | `kubernetes.io/aws-ebs` | None | None | None | | [`validate_migration_expected_provisioners.1`](defaults/main.yml#L5) | str | `kubernetes.io/azure-disk` | None | None | None | @@ -40,14 +42,24 @@ Description: Verification of an Ansible for OpenShift Virtualization Migration e | [`validate_migration_expected_provisioners.7`](defaults/main.yml#L11) | str | `openshift-storage.cephfs.csi.ceph.com` | None | None | None | | [`validate_migration_expected_provisioners.8`](defaults/main.yml#L12) | str | `openshift-storage.rbd.csi.ceph.com` | None | None | None | | [`validate_migration_expected_provisioners.9`](defaults/main.yml#L13) | str | `kubernetes.io/rbd` | None | None | None | +| [`validate_migration_expected_vm_phase`](defaults/main.yml#L48) | str | `Running` | None | False | Expected VM Phase | +| [`validate_migration_kubevirt_api_version`](defaults/main.yml#L56) | str | `kubevirt.io/v1` | None | False | KubeVirt API Version | | [`validate_migration_namespace`](defaults/main.yml#L16) | str | `openshift-mtv` | None | None | None | +| [`validate_migration_post_enabled`](defaults/main.yml#L32) | bool | `False` | None | False | Enable Post-Migration Validation | +| [`validate_migration_post_label_selectors`](defaults/main.yml#L40) | list | `[]` | None | False | Post-Migration Label Selectors | +| [`validate_migration_post_namespace`](defaults/main.yml#L36) | str | `` | None | False | Post-Migration Target Namespace | +| [`validate_migration_pre_enabled`](defaults/main.yml#L26) | bool | `True` | None | False | Enable Pre-Migration Validation | 🖇️ Full descriptions for vars in defaults/main.yml
+`validate_migration_check_vm_running`: Verify VirtualMachineInstances are running +
`validate_migration_cluster_name`: None
`validate_migration_debug`: None
+`validate_migration_expected_dv_phase`: Expected DataVolume phase +
`validate_migration_expected_provisioners`: None
`validate_migration_expected_provisioners.0`: None @@ -72,8 +84,20 @@ Description: Verification of an Ansible for OpenShift Virtualization Migration e
`validate_migration_expected_provisioners.9`: None
+`validate_migration_expected_vm_phase`: Expected VirtualMachineInstance phase +
+`validate_migration_kubevirt_api_version`: KubeVirt API Version +
`validate_migration_namespace`: None
+`validate_migration_post_enabled`: Enable post-migration validation checks +
+`validate_migration_post_label_selectors`: Label selectors to filter VMs for validation +
+`validate_migration_post_namespace`: Namespace containing migrated VMs to validate +
+`validate_migration_pre_enabled`: Enable pre-migration infrastructure validation checks +

### Tasks @@ -82,10 +106,39 @@ Description: Verification of an Ansible for OpenShift Virtualization Migration e | Name | Module | Has Conditions | | ---- | ------ | --------- | -| Include ocp_version tasks | `ansible.builtin.include_tasks` | False | -| Include ocp_operators tasks | `ansible.builtin.include_tasks` | False | -| Include ocp_storage_support tasks | `ansible.builtin.include_tasks` | False | -| Include vmware_firewall_rules tasks | `ansible.builtin.include_tasks` | False | +| Include ocp_version tasks | `ansible.builtin.include_tasks` | True | +| Include ocp_operators tasks | `ansible.builtin.include_tasks` | True | +| Include ocp_storage_support tasks | `ansible.builtin.include_tasks` | True | +| Include vmware_firewall_rules tasks | `ansible.builtin.include_tasks` | True | +| Include post-migration VM validation | `ansible.builtin.include_tasks` | True | +| Include post-migration data volume validation | `ansible.builtin.include_tasks` | True | +| Include post-migration network validation | `ansible.builtin.include_tasks` | True | +| Include post-migration relationship validation | `ansible.builtin.include_tasks` | True | + +#### File: tasks/_validate_vm.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _validate_vm ¦ Verify VM Has Required Spec Fields | `ansible.builtin.assert` | False | +| _validate_vm ¦ Verify VM Has CPU Configuration | `ansible.builtin.assert` | False | +| _validate_vm ¦ Verify VM Has Memory Configuration | `ansible.builtin.assert` | False | +| _validate_vm ¦ Verify VM Has Volumes Defined | `ansible.builtin.assert` | False | +| _validate_vm ¦ Verify VM Has Network Interfaces | `ansible.builtin.assert` | False | +| _validate_vm ¦ Collect VirtualMachineInstance Status | `kubernetes.core.k8s_info` | True | +| _validate_vm ¦ Verify VMI Is Running | `ansible.builtin.assert` | True | +| _validate_vm ¦ Record Successful Validation | `ansible.builtin.set_fact` | False | + +#### File: tasks/_validate_vm_volumes.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| _validate_vm_volumes ¦ Extract DataVolume References from VM | `ansible.builtin.set_fact` | False | +| _validate_vm_volumes ¦ Verify Referenced DataVolumes Exist | `block` | True | +| _validate_vm_volumes ¦ Query Referenced DataVolumes | `kubernetes.core.k8s_info` | False | +| _validate_vm_volumes ¦ Track Missing DataVolumes | `ansible.builtin.set_fact` | True | +| _validate_vm_volumes ¦ Verify Referenced PVCs Exist | `block` | True | +| _validate_vm_volumes ¦ Query Referenced PVCs | `kubernetes.core.k8s_info` | False | +| _validate_vm_volumes ¦ Verify PVC Bindings | `ansible.builtin.assert` | False | #### File: tasks/ocp_operators.yml @@ -118,6 +171,54 @@ Description: Verification of an Ansible for OpenShift Virtualization Migration e | ocp_version ¦ Get OCP version and check if it's 4.12 or higher | `kubernetes.core.k8s_info` | False | | ocp_version ¦ Print OCP version | `ansible.builtin.debug` | False | +#### File: tasks/post_migration_data_volumes.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| post_migration_data_volumes ¦ Collect DataVolumes in Target Namespace | `kubernetes.core.k8s_info` | False | +| post_migration_data_volumes ¦ Verify DataVolumes Exist | `ansible.builtin.assert` | False | +| post_migration_data_volumes ¦ Verify DataVolume Status Is Succeeded | `ansible.builtin.assert` | False | +| post_migration_data_volumes ¦ Collect PVCs in Target Namespace | `kubernetes.core.k8s_info` | False | +| post_migration_data_volumes ¦ Verify PVCs Are Bound | `ansible.builtin.assert` | False | +| post_migration_data_volumes ¦ Verify DataVolume Storage Sizes | `ansible.builtin.debug` | False | +| post_migration_data_volumes ¦ Report Data Volume Summary | `ansible.builtin.debug` | False | + +#### File: tasks/post_migration_networks.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| post_migration_networks ¦ Collect VirtualMachines for Network Validation | `kubernetes.core.k8s_info` | False | +| post_migration_networks ¦ Validate VM Network Interfaces | `ansible.builtin.assert` | False | +| post_migration_networks ¦ Verify Network-Interface Count Match | `ansible.builtin.assert` | False | +| post_migration_networks ¦ Collect NetworkAttachmentDefinitions | `kubernetes.core.k8s_info` | False | +| post_migration_networks ¦ Report Network Attachment Definitions | `ansible.builtin.debug` | True | +| post_migration_networks ¦ Collect NetworkPolicies | `kubernetes.core.k8s_info` | False | +| post_migration_networks ¦ Report Network Policies | `ansible.builtin.debug` | False | +| post_migration_networks ¦ Report Network Validation Summary | `ansible.builtin.debug` | False | + +#### File: tasks/post_migration_relationships.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| post_migration_relationships ¦ Collect VMs for Relationship Validation | `kubernetes.core.k8s_info` | False | +| post_migration_relationships ¦ Collect DataVolumes for Relationship Validation | `kubernetes.core.k8s_info` | False | +| post_migration_relationships ¦ Initialize Relationship Tracking | `ansible.builtin.set_fact` | False | +| post_migration_relationships ¦ Verify VM Volume References Exist | `ansible.builtin.include_tasks` | False | +| post_migration_relationships ¦ Check for Orphaned DataVolumes | `ansible.builtin.set_fact` | True | +| post_migration_relationships ¦ Warn About Orphaned DataVolumes | `ansible.builtin.debug` | True | +| post_migration_relationships ¦ Report Missing DataVolumes | `ansible.builtin.debug` | True | +| post_migration_relationships ¦ Report Relationship Summary | `ansible.builtin.debug` | False | + +#### File: tasks/post_migration_vms.yml + +| Name | Module | Has Conditions | +| ---- | ------ | --------- | +| post_migration_vms ¦ Initialize VM Validation Results | `ansible.builtin.set_fact` | False | +| post_migration_vms ¦ Collect VirtualMachines in Target Namespace | `kubernetes.core.k8s_info` | False | +| post_migration_vms ¦ Verify VirtualMachines Exist | `ansible.builtin.assert` | False | +| post_migration_vms ¦ Validate Each VirtualMachine | `ansible.builtin.include_tasks` | False | +| post_migration_vms ¦ Report VM Validation Summary | `ansible.builtin.debug` | False | + #### File: tasks/vmware_firewall_rules.yml | Name | Module | Has Conditions | @@ -128,6 +229,57 @@ Description: Verification of an Ansible for OpenShift Virtualization Migration e ## Task Flow Graphs +### Graph for _validate_vm.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| _validate_vm___Verify_VM_Has_Required_Spec_Fields0[ validate vm verify vm has required spec fields]:::task + _validate_vm___Verify_VM_Has_Required_Spec_Fields0-->|Task| _validate_vm___Verify_VM_Has_CPU_Configuration1[ validate vm verify vm has cpu configuration]:::task + _validate_vm___Verify_VM_Has_CPU_Configuration1-->|Task| _validate_vm___Verify_VM_Has_Memory_Configuration2[ validate vm verify vm has memory configuration]:::task + _validate_vm___Verify_VM_Has_Memory_Configuration2-->|Task| _validate_vm___Verify_VM_Has_Volumes_Defined3[ validate vm verify vm has volumes defined]:::task + _validate_vm___Verify_VM_Has_Volumes_Defined3-->|Task| _validate_vm___Verify_VM_Has_Network_Interfaces4[ validate vm verify vm has network interfaces]:::task + _validate_vm___Verify_VM_Has_Network_Interfaces4-->|Task| _validate_vm___Collect_VirtualMachineInstance_Status5[ validate vm collect virtualmachineinstance
status
When: **validate migration check vm running bool**]:::task + _validate_vm___Collect_VirtualMachineInstance_Status5-->|Task| _validate_vm___Verify_VMI_Is_Running6[ validate vm verify vmi is running
When: **validate migration check vm running bool**]:::task + _validate_vm___Verify_VMI_Is_Running6-->|Task| _validate_vm___Record_Successful_Validation7[ validate vm record successful validation]:::task + _validate_vm___Record_Successful_Validation7-->End +``` + +### Graph for _validate_vm_volumes.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| _validate_vm_volumes___Extract_DataVolume_References_from_VM0[ validate vm volumes extract datavolume
references from vm]:::task + _validate_vm_volumes___Extract_DataVolume_References_from_VM0-->|Block Start| _validate_vm_volumes___Verify_Referenced_DataVolumes_Exist1_block_start_0[[ validate vm volumes verify referenced
datavolumes exist
When: **validate migration vm dv names length 0**]]:::block + _validate_vm_volumes___Verify_Referenced_DataVolumes_Exist1_block_start_0-->|Task| _validate_vm_volumes___Query_Referenced_DataVolumes0[ validate vm volumes query referenced
datavolumes]:::task + _validate_vm_volumes___Query_Referenced_DataVolumes0-->|Task| _validate_vm_volumes___Track_Missing_DataVolumes1[ validate vm volumes track missing datavolumes
When: **validate migration dv ref result resources
length 0**]:::task + _validate_vm_volumes___Track_Missing_DataVolumes1-.->|End of Block| _validate_vm_volumes___Verify_Referenced_DataVolumes_Exist1_block_start_0 + _validate_vm_volumes___Track_Missing_DataVolumes1-->|Block Start| _validate_vm_volumes___Verify_Referenced_PVCs_Exist2_block_start_0[[ validate vm volumes verify referenced pvcs
exist
When: **validate migration vm pvc names length 0**]]:::block + _validate_vm_volumes___Verify_Referenced_PVCs_Exist2_block_start_0-->|Task| _validate_vm_volumes___Query_Referenced_PVCs0[ validate vm volumes query referenced pvcs]:::task + _validate_vm_volumes___Query_Referenced_PVCs0-->|Task| _validate_vm_volumes___Verify_PVC_Bindings1[ validate vm volumes verify pvc bindings]:::task + _validate_vm_volumes___Verify_PVC_Bindings1-.->|End of Block| _validate_vm_volumes___Verify_Referenced_PVCs_Exist2_block_start_0 + _validate_vm_volumes___Verify_PVC_Bindings1-->End +``` + ### Graph for main.yml ```mermaid @@ -142,11 +294,15 @@ classDef importRole stroke:#699ba7,stroke-width:2px; classDef includeVars stroke:#8e44ad,stroke-width:2px; classDef rescue stroke:#665352,stroke-width:2px; - Start-->|Include task| Include_ocp_version_tasks_ocp_version_yml_0[include ocp version tasks
include_task: ocp version yml]:::includeTasks - Include_ocp_version_tasks_ocp_version_yml_0-->|Include task| Include_ocp_operators_tasks_ocp_operators_yml_1[include ocp operators tasks
include_task: ocp operators yml]:::includeTasks - Include_ocp_operators_tasks_ocp_operators_yml_1-->|Include task| Include_ocp_storage_support_tasks_ocp_storage_support_yml_2[include ocp storage support tasks
include_task: ocp storage support yml]:::includeTasks - Include_ocp_storage_support_tasks_ocp_storage_support_yml_2-->|Include task| Include_vmware_firewall_rules_tasks_vmware_firewall_rules_yml_3[include vmware firewall rules tasks
include_task: vmware firewall rules yml]:::includeTasks - Include_vmware_firewall_rules_tasks_vmware_firewall_rules_yml_3-->End + Start-->|Include task| Include_ocp_version_tasks_ocp_version_yml_0[include ocp version tasks
When: **validate migration pre enabled bool**
include_task: ocp version yml]:::includeTasks + Include_ocp_version_tasks_ocp_version_yml_0-->|Include task| Include_ocp_operators_tasks_ocp_operators_yml_1[include ocp operators tasks
When: **validate migration pre enabled bool**
include_task: ocp operators yml]:::includeTasks + Include_ocp_operators_tasks_ocp_operators_yml_1-->|Include task| Include_ocp_storage_support_tasks_ocp_storage_support_yml_2[include ocp storage support tasks
When: **validate migration pre enabled bool**
include_task: ocp storage support yml]:::includeTasks + Include_ocp_storage_support_tasks_ocp_storage_support_yml_2-->|Include task| Include_vmware_firewall_rules_tasks_vmware_firewall_rules_yml_3[include vmware firewall rules tasks
When: **validate migration pre enabled bool**
include_task: vmware firewall rules yml]:::includeTasks + Include_vmware_firewall_rules_tasks_vmware_firewall_rules_yml_3-->|Include task| Include_post_migration_VM_validation_post_migration_vms_yml_4[include post migration vm validation
When: **validate migration post enabled bool**
include_task: post migration vms yml]:::includeTasks + Include_post_migration_VM_validation_post_migration_vms_yml_4-->|Include task| Include_post_migration_data_volume_validation_post_migration_data_volumes_yml_5[include post migration data volume validation
When: **validate migration post enabled bool**
include_task: post migration data volumes yml]:::includeTasks + Include_post_migration_data_volume_validation_post_migration_data_volumes_yml_5-->|Include task| Include_post_migration_network_validation_post_migration_networks_yml_6[include post migration network validation
When: **validate migration post enabled bool**
include_task: post migration networks yml]:::includeTasks + Include_post_migration_network_validation_post_migration_networks_yml_6-->|Include task| Include_post_migration_relationship_validation_post_migration_relationships_yml_7[include post migration relationship validation
When: **validate migration post enabled bool**
include_task: post migration relationships yml]:::includeTasks + Include_post_migration_relationship_validation_post_migration_relationships_yml_7-->End ``` ### Graph for ocp_operators.yml @@ -228,6 +384,102 @@ classDef rescue stroke:#665352,stroke-width:2px; ocp_version___Print_OCP_version1-->End ``` +### Graph for post_migration_data_volumes.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| post_migration_data_volumes___Collect_DataVolumes_in_Target_Namespace0[post migration data volumes collect datavolumes
in target namespace]:::task + post_migration_data_volumes___Collect_DataVolumes_in_Target_Namespace0-->|Task| post_migration_data_volumes___Verify_DataVolumes_Exist1[post migration data volumes verify datavolumes
exist]:::task + post_migration_data_volumes___Verify_DataVolumes_Exist1-->|Task| post_migration_data_volumes___Verify_DataVolume_Status_Is_Succeeded2[post migration data volumes verify datavolume
status is succeeded]:::task + post_migration_data_volumes___Verify_DataVolume_Status_Is_Succeeded2-->|Task| post_migration_data_volumes___Collect_PVCs_in_Target_Namespace3[post migration data volumes collect pvcs in
target namespace]:::task + post_migration_data_volumes___Collect_PVCs_in_Target_Namespace3-->|Task| post_migration_data_volumes___Verify_PVCs_Are_Bound4[post migration data volumes verify pvcs are
bound]:::task + post_migration_data_volumes___Verify_PVCs_Are_Bound4-->|Task| post_migration_data_volumes___Verify_DataVolume_Storage_Sizes5[post migration data volumes verify datavolume
storage sizes]:::task + post_migration_data_volumes___Verify_DataVolume_Storage_Sizes5-->|Task| post_migration_data_volumes___Report_Data_Volume_Summary6[post migration data volumes report data volume
summary]:::task + post_migration_data_volumes___Report_Data_Volume_Summary6-->End +``` + +### Graph for post_migration_networks.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| post_migration_networks___Collect_VirtualMachines_for_Network_Validation0[post migration networks collect virtualmachines
for network validation]:::task + post_migration_networks___Collect_VirtualMachines_for_Network_Validation0-->|Task| post_migration_networks___Validate_VM_Network_Interfaces1[post migration networks validate vm network
interfaces]:::task + post_migration_networks___Validate_VM_Network_Interfaces1-->|Task| post_migration_networks___Verify_Network_Interface_Count_Match2[post migration networks verify network interface
count match]:::task + post_migration_networks___Verify_Network_Interface_Count_Match2-->|Task| post_migration_networks___Collect_NetworkAttachmentDefinitions3[post migration networks collect
networkattachmentdefinitions]:::task + post_migration_networks___Collect_NetworkAttachmentDefinitions3-->|Task| post_migration_networks___Report_Network_Attachment_Definitions4[post migration networks report network
attachment definitions
When: **validate migration nad list resources is defined**]:::task + post_migration_networks___Report_Network_Attachment_Definitions4-->|Task| post_migration_networks___Collect_NetworkPolicies5[post migration networks collect networkpolicies]:::task + post_migration_networks___Collect_NetworkPolicies5-->|Task| post_migration_networks___Report_Network_Policies6[post migration networks report network policies]:::task + post_migration_networks___Report_Network_Policies6-->|Task| post_migration_networks___Report_Network_Validation_Summary7[post migration networks report network
validation summary]:::task + post_migration_networks___Report_Network_Validation_Summary7-->End +``` + +### Graph for post_migration_relationships.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| post_migration_relationships___Collect_VMs_for_Relationship_Validation0[post migration relationships collect vms for
relationship validation]:::task + post_migration_relationships___Collect_VMs_for_Relationship_Validation0-->|Task| post_migration_relationships___Collect_DataVolumes_for_Relationship_Validation1[post migration relationships collect datavolumes
for relationship validation]:::task + post_migration_relationships___Collect_DataVolumes_for_Relationship_Validation1-->|Task| post_migration_relationships___Initialize_Relationship_Tracking2[post migration relationships initialize
relationship tracking]:::task + post_migration_relationships___Initialize_Relationship_Tracking2-->|Include task| post_migration_relationships___Verify_VM_Volume_References_Exist__validate_vm_volumes_yml_3[post migration relationships verify vm volume
references exist
include_task: validate vm volumes yml]:::includeTasks + post_migration_relationships___Verify_VM_Volume_References_Exist__validate_vm_volumes_yml_3-->|Task| post_migration_relationships___Check_for_Orphaned_DataVolumes4[post migration relationships check for orphaned
datavolumes
When: **validate migration rel dv metadata ownerreferences
default length 0**]:::task + post_migration_relationships___Check_for_Orphaned_DataVolumes4-->|Task| post_migration_relationships___Warn_About_Orphaned_DataVolumes5[post migration relationships warn about orphaned
datavolumes
When: **validate migration orphaned dvs length 0**]:::task + post_migration_relationships___Warn_About_Orphaned_DataVolumes5-->|Task| post_migration_relationships___Report_Missing_DataVolumes6[post migration relationships report missing
datavolumes
When: **validate migration missing dvs length 0**]:::task + post_migration_relationships___Report_Missing_DataVolumes6-->|Task| post_migration_relationships___Report_Relationship_Summary7[post migration relationships report relationship
summary]:::task + post_migration_relationships___Report_Relationship_Summary7-->End +``` + +### Graph for post_migration_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| post_migration_vms___Initialize_VM_Validation_Results0[post migration vms initialize vm validation
results]:::task + post_migration_vms___Initialize_VM_Validation_Results0-->|Task| post_migration_vms___Collect_VirtualMachines_in_Target_Namespace1[post migration vms collect virtualmachines in
target namespace]:::task + post_migration_vms___Collect_VirtualMachines_in_Target_Namespace1-->|Task| post_migration_vms___Verify_VirtualMachines_Exist2[post migration vms verify virtualmachines exist]:::task + post_migration_vms___Verify_VirtualMachines_Exist2-->|Include task| post_migration_vms___Validate_Each_VirtualMachine__validate_vm_yml_3[post migration vms validate each virtualmachine
include_task: validate vm yml]:::includeTasks + post_migration_vms___Validate_Each_VirtualMachine__validate_vm_yml_3-->|Task| post_migration_vms___Report_VM_Validation_Summary4[post migration vms report vm validation summary]:::task + post_migration_vms___Report_VM_Validation_Summary4-->End +``` + ### Graph for vmware_firewall_rules.yml ```mermaid diff --git a/roles/validate_migration/defaults/main.yml b/roles/validate_migration/defaults/main.yml index da560fb..5b3b296 100644 --- a/roles/validate_migration/defaults/main.yml +++ b/roles/validate_migration/defaults/main.yml @@ -18,4 +18,40 @@ validate_migration_namespace: openshift-mtv validate_migration_debug: true validate_migration_cluster_name: cluster01 + +# Pre-migration infrastructure validation settings +# title: Enable Pre-Migration Validation +# required: False +# description: Enable pre-migration infrastructure validation checks +validate_migration_pre_enabled: true + +# Post-migration validation settings +# title: Enable Post-Migration Validation +# required: False +# description: Enable post-migration validation checks +validate_migration_post_enabled: false +# title: Post-Migration Target Namespace +# required: False +# description: Namespace containing migrated VMs to validate +validate_migration_post_namespace: "" +# title: Post-Migration Label Selectors +# required: False +# description: Label selectors to filter VMs for validation +validate_migration_post_label_selectors: [] +# title: Check VM Running Status +# required: False +# description: Verify VirtualMachineInstances are running +validate_migration_check_vm_running: true +# title: Expected VM Phase +# required: False +# description: Expected VirtualMachineInstance phase +validate_migration_expected_vm_phase: "Running" +# title: Expected DataVolume Phase +# required: False +# description: Expected DataVolume phase +validate_migration_expected_dv_phase: "Succeeded" +# title: KubeVirt API Version +# required: False +# description: KubeVirt API Version +validate_migration_kubevirt_api_version: kubevirt.io/v1 ... diff --git a/roles/validate_migration/tasks/_validate_vm.yml b/roles/validate_migration/tasks/_validate_vm.yml new file mode 100644 index 0000000..acea773 --- /dev/null +++ b/roles/validate_migration/tasks/_validate_vm.yml @@ -0,0 +1,88 @@ +--- + +- name: _validate_vm | Verify VM Has Required Spec Fields + ansible.builtin.assert: + that: + - validate_migration_vm.spec is defined + - validate_migration_vm.spec.template is defined + - validate_migration_vm.spec.template.spec is defined + - validate_migration_vm.spec.template.spec.domain is defined + fail_msg: >- + VirtualMachine '{{ validate_migration_vm.metadata.name }}' is missing + required spec fields + quiet: true + +- name: _validate_vm | Verify VM Has CPU Configuration + ansible.builtin.assert: + that: + - >- + (validate_migration_vm.spec.template.spec.domain.cpu is defined) or + (validate_migration_vm.spec.instancetype is defined) + fail_msg: >- + VirtualMachine '{{ validate_migration_vm.metadata.name }}' has no CPU + configuration or instance type + quiet: true + +- name: _validate_vm | Verify VM Has Memory Configuration + ansible.builtin.assert: + that: + - >- + (validate_migration_vm.spec.template.spec.domain.resources is defined) or + (validate_migration_vm.spec.instancetype is defined) + fail_msg: >- + VirtualMachine '{{ validate_migration_vm.metadata.name }}' has no memory + configuration or instance type + quiet: true + +- name: _validate_vm | Verify VM Has Volumes Defined + ansible.builtin.assert: + that: + - validate_migration_vm.spec.template.spec.volumes | default([]) | length > 0 + fail_msg: >- + VirtualMachine '{{ validate_migration_vm.metadata.name }}' has no volumes + defined + quiet: true + +- name: _validate_vm | Verify VM Has Network Interfaces + ansible.builtin.assert: + that: + - >- + validate_migration_vm.spec.template.spec.domain.devices.interfaces + | default([]) | length > 0 + fail_msg: >- + VirtualMachine '{{ validate_migration_vm.metadata.name }}' has no network + interfaces defined + quiet: true + +- name: _validate_vm | Collect VirtualMachineInstance Status + when: validate_migration_check_vm_running | bool + kubernetes.core.k8s_info: + api_version: "{{ validate_migration_kubevirt_api_version }}" + kind: VirtualMachineInstance + namespace: "{{ validate_migration_vm.metadata.namespace }}" + name: "{{ validate_migration_vm.metadata.name }}" + register: validate_migration_vmi + +- name: _validate_vm | Verify VMI Is Running + when: validate_migration_check_vm_running | bool + ansible.builtin.assert: + that: + - validate_migration_vmi.resources | length > 0 + - validate_migration_vmi.resources[0].status.phase == validate_migration_expected_vm_phase + fail_msg: >- + VirtualMachineInstance '{{ validate_migration_vm.metadata.name }}' is not + in '{{ validate_migration_expected_vm_phase }}' phase + quiet: true + +- name: _validate_vm | Record Successful Validation + ansible.builtin.set_fact: + validate_migration_vm_results: >- + {{ validate_migration_vm_results + [ + { + 'name': validate_migration_vm.metadata.name, + 'namespace': validate_migration_vm.metadata.namespace, + 'status': 'passed' + } + ] }} + +... diff --git a/roles/validate_migration/tasks/_validate_vm_volumes.yml b/roles/validate_migration/tasks/_validate_vm_volumes.yml new file mode 100644 index 0000000..c6b53d9 --- /dev/null +++ b/roles/validate_migration/tasks/_validate_vm_volumes.yml @@ -0,0 +1,70 @@ +--- + +- name: _validate_vm_volumes | Extract DataVolume References from VM + ansible.builtin.set_fact: + validate_migration_vm_dv_names: >- + {{ validate_migration_rel_vm.spec.template.spec.volumes | default([]) + | selectattr('dataVolume', 'defined') + | map(attribute='dataVolume.name') + | list }} + validate_migration_vm_pvc_names: >- + {{ validate_migration_rel_vm.spec.template.spec.volumes | default([]) + | selectattr('persistentVolumeClaim', 'defined') + | map(attribute='persistentVolumeClaim.claimName') + | list }} + +- name: _validate_vm_volumes | Verify Referenced DataVolumes Exist + when: validate_migration_vm_dv_names | length > 0 + block: + - name: _validate_vm_volumes | Query Referenced DataVolumes + kubernetes.core.k8s_info: + api_version: cdi.kubevirt.io/v1beta1 + kind: DataVolume + namespace: "{{ validate_migration_rel_vm.metadata.namespace }}" + name: "{{ validate_migration_dv_ref_name }}" + register: validate_migration_dv_ref_query + loop: "{{ validate_migration_vm_dv_names }}" + loop_control: + loop_var: validate_migration_dv_ref_name + label: "{{ validate_migration_dv_ref_name }}" + + - name: _validate_vm_volumes | Track Missing DataVolumes + ansible.builtin.set_fact: + validate_migration_missing_dvs: >- + {{ validate_migration_missing_dvs + + [validate_migration_dv_ref_result.validate_migration_dv_ref_name] }} + when: validate_migration_dv_ref_result.resources | length == 0 + loop: "{{ validate_migration_dv_ref_query.results }}" + loop_control: + loop_var: validate_migration_dv_ref_result + label: "{{ validate_migration_dv_ref_result.validate_migration_dv_ref_name }}" + +- name: _validate_vm_volumes | Verify Referenced PVCs Exist + when: validate_migration_vm_pvc_names | length > 0 + block: + - name: _validate_vm_volumes | Query Referenced PVCs + kubernetes.core.k8s_info: + api_version: v1 + kind: PersistentVolumeClaim + namespace: "{{ validate_migration_rel_vm.metadata.namespace }}" + name: "{{ validate_migration_pvc_ref_name }}" + register: validate_migration_pvc_ref_query + loop: "{{ validate_migration_vm_pvc_names }}" + loop_control: + loop_var: validate_migration_pvc_ref_name + label: "{{ validate_migration_pvc_ref_name }}" + + - name: _validate_vm_volumes | Verify PVC Bindings + ansible.builtin.assert: + that: + - validate_migration_pvc_ref_result.resources | length > 0 + fail_msg: >- + PVC '{{ validate_migration_pvc_ref_result.validate_migration_pvc_ref_name }}' + referenced by VM '{{ validate_migration_rel_vm.metadata.name }}' not found + quiet: true + loop: "{{ validate_migration_pvc_ref_query.results }}" + loop_control: + loop_var: validate_migration_pvc_ref_result + label: "{{ validate_migration_pvc_ref_result.validate_migration_pvc_ref_name }}" + +... diff --git a/roles/validate_migration/tasks/main.yml b/roles/validate_migration/tasks/main.yml index 4d1e097..5b4b670 100644 --- a/roles/validate_migration/tasks/main.yml +++ b/roles/validate_migration/tasks/main.yml @@ -1,11 +1,34 @@ --- # tasks file for validation + +# Pre-migration infrastructure validation - name: Include ocp_version tasks + when: validate_migration_pre_enabled | bool ansible.builtin.include_tasks: ocp_version.yml - name: Include ocp_operators tasks + when: validate_migration_pre_enabled | bool ansible.builtin.include_tasks: ocp_operators.yml - name: Include ocp_storage_support tasks + when: validate_migration_pre_enabled | bool ansible.builtin.include_tasks: ocp_storage_support.yml - name: Include vmware_firewall_rules tasks + when: validate_migration_pre_enabled | bool ansible.builtin.include_tasks: vmware_firewall_rules.yml + +# Post-migration validation +- name: Include post-migration VM validation + when: validate_migration_post_enabled | bool + ansible.builtin.include_tasks: post_migration_vms.yml + +- name: Include post-migration data volume validation + when: validate_migration_post_enabled | bool + ansible.builtin.include_tasks: post_migration_data_volumes.yml + +- name: Include post-migration network validation + when: validate_migration_post_enabled | bool + ansible.builtin.include_tasks: post_migration_networks.yml + +- name: Include post-migration relationship validation + when: validate_migration_post_enabled | bool + ansible.builtin.include_tasks: post_migration_relationships.yml ... diff --git a/roles/validate_migration/tasks/post_migration_data_volumes.yml b/roles/validate_migration/tasks/post_migration_data_volumes.yml new file mode 100644 index 0000000..361c546 --- /dev/null +++ b/roles/validate_migration/tasks/post_migration_data_volumes.yml @@ -0,0 +1,72 @@ +--- + +- name: post_migration_data_volumes | Collect DataVolumes in Target Namespace + kubernetes.core.k8s_info: + api_version: cdi.kubevirt.io/v1beta1 + kind: DataVolume + namespace: "{{ validate_migration_post_namespace }}" + register: validate_migration_dv_list + +- name: post_migration_data_volumes | Verify DataVolumes Exist + ansible.builtin.assert: + that: + - validate_migration_dv_list.resources | length > 0 + fail_msg: >- + No DataVolumes found in namespace '{{ validate_migration_post_namespace }}' + quiet: true + +- name: post_migration_data_volumes | Verify DataVolume Status Is Succeeded + ansible.builtin.assert: + that: + - validate_migration_dv.status.phase | default('') == validate_migration_expected_dv_phase + fail_msg: >- + DataVolume '{{ validate_migration_dv.metadata.name }}' phase is + '{{ validate_migration_dv.status.phase | default("Unknown") }}' + (expected '{{ validate_migration_expected_dv_phase }}') + quiet: true + loop: "{{ validate_migration_dv_list.resources }}" + loop_control: + loop_var: validate_migration_dv + label: "{{ validate_migration_dv.metadata.name }}" + +- name: post_migration_data_volumes | Collect PVCs in Target Namespace + kubernetes.core.k8s_info: + api_version: v1 + kind: PersistentVolumeClaim + namespace: "{{ validate_migration_post_namespace }}" + register: validate_migration_pvc_list + +- name: post_migration_data_volumes | Verify PVCs Are Bound + ansible.builtin.assert: + that: + - validate_migration_pvc.status.phase == 'Bound' + fail_msg: >- + PVC '{{ validate_migration_pvc.metadata.name }}' is not Bound + (status: {{ validate_migration_pvc.status.phase | default('Unknown') }}) + quiet: true + loop: "{{ validate_migration_pvc_list.resources }}" + loop_control: + loop_var: validate_migration_pvc + label: "{{ validate_migration_pvc.metadata.name }}" + +- name: post_migration_data_volumes | Verify DataVolume Storage Sizes + ansible.builtin.debug: + msg: >- + DataVolume '{{ validate_migration_dv.metadata.name }}' + size: {{ validate_migration_dv.spec.pvc.resources.requests.storage + | default(validate_migration_dv.spec.storage.resources.requests.storage + | default('N/A')) }} + status: {{ validate_migration_dv.status.phase | default('Unknown') }} + loop: "{{ validate_migration_dv_list.resources }}" + loop_control: + loop_var: validate_migration_dv + label: "{{ validate_migration_dv.metadata.name }}" + +- name: post_migration_data_volumes | Report Data Volume Summary + ansible.builtin.debug: + msg: >- + Data Volume Validation Complete: + {{ validate_migration_dv_list.resources | length }} DataVolumes, + {{ validate_migration_pvc_list.resources | length }} PVCs checked + +... diff --git a/roles/validate_migration/tasks/post_migration_networks.yml b/roles/validate_migration/tasks/post_migration_networks.yml new file mode 100644 index 0000000..eabddf8 --- /dev/null +++ b/roles/validate_migration/tasks/post_migration_networks.yml @@ -0,0 +1,83 @@ +--- + +- name: post_migration_networks | Collect VirtualMachines for Network Validation + kubernetes.core.k8s_info: + api_version: "{{ validate_migration_kubevirt_api_version }}" + kind: VirtualMachine + namespace: "{{ validate_migration_post_namespace }}" + label_selectors: "{{ validate_migration_post_label_selectors | default(omit) }}" + register: validate_migration_net_vm_list + +- name: post_migration_networks | Validate VM Network Interfaces + ansible.builtin.assert: + that: + - >- + validate_migration_net_vm.spec.template.spec.domain.devices.interfaces + | default([]) | length > 0 + - >- + validate_migration_net_vm.spec.template.spec.networks + | default([]) | length > 0 + fail_msg: >- + VirtualMachine '{{ validate_migration_net_vm.metadata.name }}' has + incomplete network configuration + quiet: true + loop: "{{ validate_migration_net_vm_list.resources }}" + loop_control: + loop_var: validate_migration_net_vm + label: "{{ validate_migration_net_vm.metadata.name }}" + +- name: post_migration_networks | Verify Network-Interface Count Match + ansible.builtin.assert: + that: + - >- + (validate_migration_net_vm.spec.template.spec.domain.devices.interfaces | default([]) | length) + == + (validate_migration_net_vm.spec.template.spec.networks | default([]) | length) + fail_msg: >- + VirtualMachine '{{ validate_migration_net_vm.metadata.name }}' has + mismatched interface/network count + quiet: true + loop: "{{ validate_migration_net_vm_list.resources }}" + loop_control: + loop_var: validate_migration_net_vm + label: "{{ validate_migration_net_vm.metadata.name }}" + +- name: post_migration_networks | Collect NetworkAttachmentDefinitions + kubernetes.core.k8s_info: + api_version: k8s.cni.cncf.io/v1 + kind: NetworkAttachmentDefinition + namespace: "{{ validate_migration_post_namespace }}" + register: validate_migration_nad_list + failed_when: false + +- name: post_migration_networks | Report Network Attachment Definitions + when: validate_migration_nad_list.resources is defined + ansible.builtin.debug: + msg: >- + Found {{ validate_migration_nad_list.resources | length }} + NetworkAttachmentDefinition(s) in namespace + '{{ validate_migration_post_namespace }}' + +- name: post_migration_networks | Collect NetworkPolicies + kubernetes.core.k8s_info: + api_version: networking.k8s.io/v1 + kind: NetworkPolicy + namespace: "{{ validate_migration_post_namespace }}" + register: validate_migration_netpol_list + failed_when: false + +- name: post_migration_networks | Report Network Policies + ansible.builtin.debug: + msg: >- + Found {{ validate_migration_netpol_list.resources | default([]) | length }} + NetworkPolicy(ies) in namespace '{{ validate_migration_post_namespace }}' + +- name: post_migration_networks | Report Network Validation Summary + ansible.builtin.debug: + msg: >- + Network Validation Complete: + {{ validate_migration_net_vm_list.resources | length }} VMs checked, + {{ validate_migration_nad_list.resources | default([]) | length }} NADs, + {{ validate_migration_netpol_list.resources | default([]) | length }} NetworkPolicies + +... diff --git a/roles/validate_migration/tasks/post_migration_relationships.yml b/roles/validate_migration/tasks/post_migration_relationships.yml new file mode 100644 index 0000000..1cb02ce --- /dev/null +++ b/roles/validate_migration/tasks/post_migration_relationships.yml @@ -0,0 +1,67 @@ +--- + +- name: post_migration_relationships | Collect VMs for Relationship Validation + kubernetes.core.k8s_info: + api_version: "{{ validate_migration_kubevirt_api_version }}" + kind: VirtualMachine + namespace: "{{ validate_migration_post_namespace }}" + label_selectors: "{{ validate_migration_post_label_selectors | default(omit) }}" + register: validate_migration_rel_vm_list + +- name: post_migration_relationships | Collect DataVolumes for Relationship Validation + kubernetes.core.k8s_info: + api_version: cdi.kubevirt.io/v1beta1 + kind: DataVolume + namespace: "{{ validate_migration_post_namespace }}" + register: validate_migration_rel_dv_list + +- name: post_migration_relationships | Initialize Relationship Tracking + ansible.builtin.set_fact: + validate_migration_orphaned_dvs: [] + validate_migration_missing_dvs: [] + +- name: post_migration_relationships | Verify VM Volume References Exist + ansible.builtin.include_tasks: + file: _validate_vm_volumes.yml + loop: "{{ validate_migration_rel_vm_list.resources }}" + loop_control: + loop_var: validate_migration_rel_vm + label: "{{ validate_migration_rel_vm.metadata.name }}" + +- name: post_migration_relationships | Check for Orphaned DataVolumes + ansible.builtin.set_fact: + validate_migration_orphaned_dvs: >- + {{ validate_migration_orphaned_dvs + [validate_migration_rel_dv.metadata.name] }} + when: >- + validate_migration_rel_dv.metadata.ownerReferences | default([]) | length == 0 + loop: "{{ validate_migration_rel_dv_list.resources }}" + loop_control: + loop_var: validate_migration_rel_dv + label: "{{ validate_migration_rel_dv.metadata.name }}" + +- name: post_migration_relationships | Warn About Orphaned DataVolumes + when: validate_migration_orphaned_dvs | length > 0 + ansible.builtin.debug: + msg: >- + WARNING: {{ validate_migration_orphaned_dvs | length }} orphaned + DataVolume(s) found without owner references: + {{ validate_migration_orphaned_dvs | join(', ') }} + +- name: post_migration_relationships | Report Missing DataVolumes + when: validate_migration_missing_dvs | length > 0 + ansible.builtin.debug: + msg: >- + WARNING: {{ validate_migration_missing_dvs | length }} DataVolume(s) + referenced by VMs but not found: + {{ validate_migration_missing_dvs | join(', ') }} + +- name: post_migration_relationships | Report Relationship Summary + ansible.builtin.debug: + msg: >- + Relationship Validation Complete: + {{ validate_migration_rel_vm_list.resources | length }} VMs, + {{ validate_migration_rel_dv_list.resources | length }} DataVolumes, + {{ validate_migration_orphaned_dvs | length }} orphaned DVs, + {{ validate_migration_missing_dvs | length }} missing DVs + +... diff --git a/roles/validate_migration/tasks/post_migration_vms.yml b/roles/validate_migration/tasks/post_migration_vms.yml new file mode 100644 index 0000000..6db789d --- /dev/null +++ b/roles/validate_migration/tasks/post_migration_vms.yml @@ -0,0 +1,38 @@ +--- + +- name: post_migration_vms | Initialize VM Validation Results + ansible.builtin.set_fact: + validate_migration_vm_results: [] + +- name: post_migration_vms | Collect VirtualMachines in Target Namespace + kubernetes.core.k8s_info: + api_version: "{{ validate_migration_kubevirt_api_version }}" + kind: VirtualMachine + namespace: "{{ validate_migration_post_namespace }}" + label_selectors: "{{ validate_migration_post_label_selectors | default(omit) }}" + register: validate_migration_vm_list + +- name: post_migration_vms | Verify VirtualMachines Exist + ansible.builtin.assert: + that: + - validate_migration_vm_list.resources | length > 0 + fail_msg: >- + No VirtualMachines found in namespace '{{ validate_migration_post_namespace }}' + quiet: true + +- name: post_migration_vms | Validate Each VirtualMachine + ansible.builtin.include_tasks: + file: _validate_vm.yml + loop: "{{ validate_migration_vm_list.resources }}" + loop_control: + loop_var: validate_migration_vm + label: >- + {{ validate_migration_vm.metadata.namespace }}/{{ validate_migration_vm.metadata.name }} + +- name: post_migration_vms | Report VM Validation Summary + ansible.builtin.debug: + msg: >- + VM Validation Complete: {{ validate_migration_vm_list.resources | length }} VMs checked + in namespace '{{ validate_migration_post_namespace }}' + +...