Coverage for ocp_resources/virtual_machine_import.py: 0%
143 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-30 10:48 +0200
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-30 10:48 +0200
1# -*- coding: utf-8 -*-
4from ocp_resources.utils.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES
5from ocp_resources.resource import NamespacedResource
6from timeout_sampler import TimeoutExpiredError, TimeoutSampler
7from ocp_resources.virtual_machine import VirtualMachine
10def _map_mappings(mappings):
11 mappings_list = []
12 for mapping in mappings:
13 mapping_dict = {"target": {"name": mapping.target_name}}
14 if mapping.target_namespace:
15 mapping_dict["target"]["namespace"] = mapping.target_namespace
16 if mapping.target_type:
17 mapping_dict["type"] = mapping.target_type
18 if mapping.source_id:
19 mapping_dict.setdefault("source", {})["id"] = mapping.source_id
20 if mapping.source_name:
21 mapping_dict.setdefault("source", {})["name"] = mapping.source_name
22 if mapping.target_access_modes:
23 mapping_dict["accessMode"] = mapping.target_access_modes
24 if mapping.target_volume_mode:
25 mapping_dict["volumeMode"] = mapping.target_volume_mode
26 mappings_list.append(mapping_dict)
27 return mappings_list
30class VirtualMachineImport(NamespacedResource):
31 """
32 Virtual Machine Import object, inherited from NamespacedResource.
33 """
35 api_group = NamespacedResource.ApiGroup.V2V_KUBEVIRT_IO
37 class Condition(NamespacedResource.Condition):
38 SUCCEEDED = "Succeeded"
39 VALID = "Valid"
40 MAPPING_RULES_VERIFIED = "MappingRulesVerified"
41 PROCESSING = "Processing"
43 class ValidConditionReason:
44 """
45 Valid condition reason object
46 """
48 VALIDATION_COMPLETED = "ValidationCompleted"
49 SECRET_NOT_FOUND = "SecretNotFound" # pragma: allowlist secret
50 RESOURCE_MAPPING_NOT_FOUND = "ResourceMappingNotFound"
51 UNINITIALIZED_PROVIDER = "UninitializedProvider"
52 SOURCE_VM_NOT_FOUND = "SourceVMNotFound"
53 INCOMPLETE_MAPPING_RULES = "IncompleteMappingRules"
55 class MappingRulesConditionReason:
56 """
57 Mapping rules verified condition reason object
58 """
60 MAPPING_COMPLETED = "MappingRulesVerificationCompleted"
61 MAPPING_FAILED = "MappingRulesVerificationFailed"
62 MAPPING_REPORTED_WARNINGS = "MappingRulesVerificationReportedWarnings"
64 class ProcessingConditionReason:
65 """
66 Processing condition reason object
67 """
69 CREATING_TARGET_VM = "CreatingTargetVM"
70 COPYING_DISKS = "CopyingDisks"
71 COMPLETED = "ProcessingCompleted"
72 FAILED = "ProcessingFailed"
74 class SucceededConditionReason:
75 """
76 Succeeced cond reason object
77 """
79 VALIDATION_FAILED = "ValidationFailed"
80 VM_CREATION_FAILED = "VMCreationFailed"
81 DATAVOLUME_CREATION_FAILED = "DataVolumeCreationFailed"
82 VIRTUAL_MACHINE_READY = "VirtualMachineReady"
83 VIRTUAL_MACHINE_RUNNING = "VirtualMachineRunning"
84 VMTEMPLATE_MATCHING_FAILED = "VMTemplateMatchingFailed"
86 def __init__(
87 self,
88 name=None,
89 namespace=None,
90 provider_credentials_secret_name=None,
91 provider_type=None,
92 provider_credentials_secret_namespace=None,
93 client=None,
94 teardown=True,
95 vm_id=None,
96 vm_name=None,
97 cluster_id=None,
98 cluster_name=None,
99 target_vm_name=None,
100 start_vm=False,
101 provider_mappings=None,
102 resource_mapping_name=None,
103 resource_mapping_namespace=None,
104 warm=False,
105 finalize_date=None,
106 yaml_file=None,
107 delete_timeout=TIMEOUT_4MINUTES,
108 **kwargs,
109 ):
110 super().__init__(
111 name=name,
112 namespace=namespace,
113 client=client,
114 teardown=teardown,
115 yaml_file=yaml_file,
116 delete_timeout=delete_timeout,
117 **kwargs,
118 )
119 self.vm_id = vm_id
120 self.vm_name = vm_name
121 self.cluster_id = cluster_id
122 self.cluster_name = cluster_name
123 self.target_vm_name = target_vm_name
124 self.start_vm = start_vm
125 self.provider_credentials_secret_name = provider_credentials_secret_name
126 self.provider_credentials_secret_namespace = provider_credentials_secret_namespace
127 self.provider_mappings = provider_mappings
128 self.resource_mapping_name = resource_mapping_name
129 self.resource_mapping_namespace = resource_mapping_namespace
130 self.provider_type = provider_type
131 self.warm = warm
132 self.finalize_date = finalize_date
134 @property
135 def vm(self):
136 return VirtualMachine(
137 name=self.target_vm_name,
138 namespace=self.namespace,
139 client=self.client,
140 )
142 def to_dict(self) -> None:
143 super().to_dict()
144 if not self.kind_dict and not self.yaml_file:
145 spec = self.res.setdefault("spec", {})
147 secret = spec.setdefault("providerCredentialsSecret", {})
148 secret["name"] = self.provider_credentials_secret_name
150 if self.provider_credentials_secret_namespace:
151 secret["namespace"] = self.provider_credentials_secret_namespace
153 if self.resource_mapping_name:
154 spec.setdefault("resourceMapping", {})["name"] = self.resource_mapping_name
155 if self.resource_mapping_namespace:
156 spec.setdefault("resourceMapping", {})["namespace"] = self.resource_mapping_namespace
158 if self.target_vm_name:
159 spec["targetVmName"] = self.target_vm_name
161 if self.start_vm is not None:
162 spec["startVm"] = self.start_vm
164 if self.warm:
165 spec["warm"] = self.warm
166 if self.finalize_date:
167 spec["finalizeDate"] = self.finalize_date.strftime(format="%Y-%m-%dT%H:%M:%SZ")
169 provider_source = spec.setdefault("source", {}).setdefault(self.provider_type, {})
170 vm = provider_source.setdefault("vm", {})
171 if self.vm_id:
172 vm["id"] = self.vm_id
173 if self.vm_name:
174 vm["name"] = self.vm_name
176 if self.cluster_id:
177 vm.setdefault("cluster", {})["id"] = self.cluster_id
178 if self.cluster_name:
179 vm.setdefault("cluster", {})["name"] = self.cluster_name
181 if self.provider_mappings:
182 if self.provider_mappings.disk_mappings:
183 mappings = _map_mappings(mappings=self.provider_mappings.disk_mappings)
184 provider_source.setdefault("mappings", {}).setdefault("diskMappings", mappings)
186 if self.provider_mappings.network_mappings:
187 mappings = _map_mappings(mappings=self.provider_mappings.network_mappings)
188 provider_source.setdefault("mappings", {}).setdefault("networkMappings", mappings)
190 if self.provider_mappings.storage_mappings:
191 mappings = _map_mappings(mappings=self.provider_mappings.storage_mappings)
192 provider_source.setdefault("mappings", {}).setdefault("storageMappings", mappings)
194 def wait(
195 self,
196 timeout=600,
197 cond_reason=SucceededConditionReason.VIRTUAL_MACHINE_READY,
198 cond_status=Condition.Status.TRUE,
199 cond_type=Condition.SUCCEEDED,
200 ):
201 self.logger.info(f"Wait for {self.kind} {self.name} {cond_reason} condition to be {cond_status}")
202 samples = TimeoutSampler(
203 wait_timeout=timeout,
204 sleep=1,
205 exceptions_dict=PROTOCOL_ERROR_EXCEPTION_DICT,
206 func=self.api.get,
207 field_selector=f"metadata.name=={self.name}",
208 namespace=self.namespace,
209 )
210 last_condition = None
211 try:
212 for sample in samples:
213 if sample.items:
214 sample_status = sample.items[0].status
215 if sample_status:
216 current_conditions = sample_status.conditions
217 for cond in current_conditions:
218 last_condition = cond
219 if cond.type == cond_type and cond.status == cond_status and cond.reason == cond_reason:
220 msg = (
221 f"Status of {self.kind} {self.name} {cond.type} is "
222 f"{cond.status} ({cond.reason}: {cond.message})"
223 )
224 self.logger.info(msg)
225 return
226 except TimeoutExpiredError:
227 raise TimeoutExpiredError(
228 f"Last condition of {self.kind} {self.name} {last_condition.type} was"
229 f" {last_condition.status} ({last_condition.reason}:"
230 f" {last_condition.message})"
231 )
234class ResourceMapping(NamespacedResource):
235 """
236 ResourceMapping object.
237 """
239 api_group = NamespacedResource.ApiGroup.V2V_KUBEVIRT_IO
241 def __init__(
242 self,
243 name=None,
244 namespace=None,
245 mapping=None,
246 client=None,
247 teardown=True,
248 yaml_file=None,
249 **kwargs,
250 ):
251 super().__init__(
252 name=name,
253 namespace=namespace,
254 client=client,
255 teardown=teardown,
256 yaml_file=yaml_file,
257 **kwargs,
258 )
259 self.mapping = mapping
261 def to_dict(self) -> None:
262 super().to_dict()
263 if not self.kind_dict and not self.yaml_file:
264 for provider, mapping in self.mapping.items():
265 res_provider_section = self.res.setdefault("spec", {}).setdefault(provider, {})
266 if mapping.network_mappings is not None:
267 res_provider_section.setdefault(
268 "networkMappings",
269 _map_mappings(mappings=mapping.network_mappings),
270 )
271 if mapping.storage_mappings is not None:
272 res_provider_section.setdefault(
273 "storageMappings",
274 _map_mappings(mappings=mapping.storage_mappings),
275 )