diff --git a/ocp_resources/benchmark.py b/ocp_resources/benchmark.py index e90ec1b9ac..448eddd16d 100644 --- a/ocp_resources/benchmark.py +++ b/ocp_resources/benchmark.py @@ -1,6 +1,6 @@ from typing import Any, Optional -from ocp_resources.constants import NOT_FOUND_ERROR_EXCEPTION_DICT, TIMEOUT_30SEC +from ocp_resources.utils.constants import NOT_FOUND_ERROR_EXCEPTION_DICT, TIMEOUT_30SEC from ocp_resources.resource import NamespacedResource from timeout_sampler import TimeoutSampler diff --git a/ocp_resources/cdi_config.py b/ocp_resources/cdi_config.py index f29e1c4f81..78083aa636 100644 --- a/ocp_resources/cdi_config.py +++ b/ocp_resources/cdi_config.py @@ -1,7 +1,7 @@ # Generated using https://github.com/RedHatQE/openshift-python-wrapper/blob/main/scripts/resource/README.md from typing import Any, Dict, List, Optional -from ocp_resources.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES +from ocp_resources.utils.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES from ocp_resources.resource import Resource from timeout_sampler import TimeoutSampler diff --git a/ocp_resources/daemonset.py b/ocp_resources/daemonset.py index 21856d9cc8..3b872d9264 100644 --- a/ocp_resources/daemonset.py +++ b/ocp_resources/daemonset.py @@ -1,6 +1,6 @@ import kubernetes -from ocp_resources.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES +from ocp_resources.utils.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource from timeout_sampler import TimeoutSampler diff --git a/ocp_resources/datavolume.py b/ocp_resources/datavolume.py index d088a7510e..f5edea66a5 100644 --- a/ocp_resources/datavolume.py +++ b/ocp_resources/datavolume.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import ( +from ocp_resources.utils.constants import ( TIMEOUT_1MINUTE, TIMEOUT_2MINUTES, TIMEOUT_4MINUTES, diff --git a/ocp_resources/deployment.py b/ocp_resources/deployment.py index 74ed3b93bd..76c7dcaf27 100644 --- a/ocp_resources/deployment.py +++ b/ocp_resources/deployment.py @@ -3,7 +3,7 @@ from typing import Any, Dict, Optional from timeout_sampler import TimeoutSampler, TimeoutWatch -from ocp_resources.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES +from ocp_resources.utils.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource, MissingRequiredArgumentError diff --git a/ocp_resources/endpoint_slice.py b/ocp_resources/endpoint_slice.py index ae740be341..889f794221 100644 --- a/ocp_resources/endpoint_slice.py +++ b/ocp_resources/endpoint_slice.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import MissingRequiredArgumentError, NamespacedResource diff --git a/ocp_resources/endpoints.py b/ocp_resources/endpoints.py index 3f698aa1ab..0d829c7592 100644 --- a/ocp_resources/endpoints.py +++ b/ocp_resources/endpoints.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import MissingRequiredArgumentError, NamespacedResource diff --git a/ocp_resources/forklift_controller.py b/ocp_resources/forklift_controller.py index 2dfd1ece24..165fc2c23f 100644 --- a/ocp_resources/forklift_controller.py +++ b/ocp_resources/forklift_controller.py @@ -1,8 +1,7 @@ -from ocp_resources.mtv import MTV from ocp_resources.resource import NamespacedResource -class ForkliftController(NamespacedResource, MTV): +class ForkliftController(NamespacedResource): """ Migration Toolkit For Virtualization (MTV) ForkliftController Resource """ diff --git a/ocp_resources/hook.py b/ocp_resources/hook.py index 5bdafd467b..473d4c6351 100644 --- a/ocp_resources/hook.py +++ b/ocp_resources/hook.py @@ -1,9 +1,8 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES -from ocp_resources.mtv import MTV +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource -class Hook(NamespacedResource, MTV): +class Hook(NamespacedResource): """ Migration Tool for Virtualization (MTV) Plan's Hook Resource. """ diff --git a/ocp_resources/host.py b/ocp_resources/host.py index 78dc45a46c..43b4f6c29a 100644 --- a/ocp_resources/host.py +++ b/ocp_resources/host.py @@ -1,9 +1,8 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES -from ocp_resources.mtv import MTV +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource -class Host(NamespacedResource, MTV): +class Host(NamespacedResource): """ Migration Toolkit For Virtualization (MTV) Host resource. """ @@ -41,7 +40,6 @@ def __init__( self.provider_namespace = provider_namespace self.secret_name = secret_name or f"{self.name}-secret" self.secret_namespace = secret_namespace or self.namespace - self.condition_message_ready = self.ConditionMessage.HOST_READY def to_dict(self) -> None: super().to_dict() diff --git a/ocp_resources/hostpath_provisioner.py b/ocp_resources/hostpath_provisioner.py index e4bb7ca212..76fa0dbd5b 100644 --- a/ocp_resources/hostpath_provisioner.py +++ b/ocp_resources/hostpath_provisioner.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import Resource diff --git a/ocp_resources/hyperconverged.py b/ocp_resources/hyperconverged.py index 0a776bbd0f..58d1e56f4b 100644 --- a/ocp_resources/hyperconverged.py +++ b/ocp_resources/hyperconverged.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/image_stream.py b/ocp_resources/image_stream.py index d1dad30f78..db923ca663 100644 --- a/ocp_resources/image_stream.py +++ b/ocp_resources/image_stream.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/job.py b/ocp_resources/job.py index a5c338fc21..c7b0634ce3 100644 --- a/ocp_resources/job.py +++ b/ocp_resources/job.py @@ -1,6 +1,6 @@ import kubernetes -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/lease.py b/ocp_resources/lease.py index f92fa40e99..ac12ff3aa7 100644 --- a/ocp_resources/lease.py +++ b/ocp_resources/lease.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/machine_health_check.py b/ocp_resources/machine_health_check.py index 583e078ec7..1b8c8c3ab6 100644 --- a/ocp_resources/machine_health_check.py +++ b/ocp_resources/machine_health_check.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/machine_set.py b/ocp_resources/machine_set.py index 0101794639..bbc071b8a4 100644 --- a/ocp_resources/machine_set.py +++ b/ocp_resources/machine_set.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource from timeout_sampler import TimeoutExpiredError, TimeoutSampler diff --git a/ocp_resources/migration.py b/ocp_resources/migration.py index 3471376fbd..eaa62daf17 100644 --- a/ocp_resources/migration.py +++ b/ocp_resources/migration.py @@ -1,9 +1,8 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES -from ocp_resources.mtv import MTV +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource -class Migration(NamespacedResource, MTV): +class Migration(NamespacedResource): """ Migration Toolkit For Virtualization (MTV) Migration object. @@ -41,7 +40,6 @@ def __init__( self.plan_name = plan_name self.plan_namespace = plan_namespace self.cut_over = cut_over - self.condition_message_succeeded = self.ConditionMessage.MIGRATION_SUCCEEDED def to_dict(self) -> None: super().to_dict() diff --git a/ocp_resources/mtv.py b/ocp_resources/mtv.py deleted file mode 100644 index 9ae10b1e9d..0000000000 --- a/ocp_resources/mtv.py +++ /dev/null @@ -1,151 +0,0 @@ -from timeout_sampler import TimeoutExpiredError, TimeoutSampler - - -def _get_status_condition_log_message(**status_condition): - log_msg = "Waiting For: \n" - for status_condition_name, status_condition in status_condition.items(): - log_msg += f"{status_condition_name}->{status_condition} \n" if status_condition else "" - - return log_msg - - -class MTV: - """ - Abstract Class for all Migration ToolKit For Virtualization (MTV) Resources: - Provider - Plan - Migration - StorageMap - NetworkMap - Host - ForkliftController - """ - - def __init__(self): - self.api = None - self.name = None - self.namespace = None - self.kind = None - self.Condition = None - self.Status = None - - self.condition_message_ready = None - self.condition_message_succeeded = None - self.mapping = None - self.source_provider_name = None - self.source_provider_namespace = None - self.destination_provider_name = None - self.destination_provider_namespace = None - - if self.__class__.__name__ == "MTV": - raise TypeError("MTV is not a Resource. Please Use one of its successors.") - - class ConditionMessage: - PROVIDER_READY = "The provider is ready." - NETWORK_MAP_READY = "The network map is ready." - STORAGE_MAP_READY = "The storage map is ready." - PLAN_READY = "The migration plan is ready." - PLAN_SUCCEEDED = "The plan execution has SUCCEEDED." - PLAN_FAILED = "The plan execution has FAILED." - MIGRATION_READY = "The migration is ready." - MIGRATION_RUNNING = "The migration is RUNNING" - MIGRATION_SUCCEEDED = "The migration has SUCCEEDED." - HOST_READY = "The host is ready." - - class ConditionCategory: - CRITICAL = "Critical" - - class ConditionType: - SUCCEEDED = "Succeeded" - FAILED = "Failed" - TARGET_NAME_NOT_VALID = "TargetNameNotValid" - VM_ALREADY_EXISTS = "VMAlreadyExists" - - class ProviderType: - VSPHERE = "vsphere" - OPENSHIFT = "openshift" - RHV = "ovirt" - OVA = "ova" - - def wait_for_resource_status( - self, - condition_status, - condition_type, - condition_message=None, - condition_reason=None, - condition_category=None, - wait_timeout=600, - ): - """ - Wait for MTV Resource Status Conditions. - """ - - self.logger.info( - _get_status_condition_log_message( - condition_status=condition_status, - condition_type=condition_type, - condition_message=condition_message, - condition_reason=condition_reason, - condition_category=condition_category, - ) - ) - - samples = TimeoutSampler( - wait_timeout=wait_timeout, - sleep=1, - func=self.api.get, - field_selector=f"metadata.name=={self.name}", - namespace=self.namespace, - ) - last_condition = None - try: - for sample in samples: - current_conditions = ( - sample.items[0].status.get("conditions") if sample.items and sample.items[0].status else [] - ) - for condition in current_conditions: - last_condition = condition - valid_status_type = condition_status == condition.status and condition_type == condition.type - valid_message = condition_message == condition.message or condition_message is None - valid_reason = condition_reason == condition.reason or condition_reason is None - valid_category = condition_category == condition.category or condition_category is None - if all([valid_status_type, valid_message, valid_reason, valid_category]): - return - - except TimeoutExpiredError: - self.logger.error(msg=(f"Last Status Condition of {self.kind} {self.name} was: {last_condition}")) - raise - - def wait_for_condition_ready(self, wait_timeout=360): - self.wait_for_resource_status( - condition_message=self.condition_message_ready, - condition_status=self.Condition.Status.TRUE, - condition_type=self.Condition.READY, - wait_timeout=wait_timeout, - ) - - def wait_for_condition_succeeded(self, wait_timeout=600): - self.wait_for_resource_status( - condition_type=self.Status.SUCCEEDED, - condition_message=self.condition_message_succeeded, - condition_status=self.Condition.Status.TRUE, - wait_timeout=wait_timeout, - ) - - @property - def map_to_dict(self): - return { - "spec": { - "map": self.mapping, - "provider": { - "source": { - "name": self.source_provider_name, - "namespace": self.source_provider_namespace, - }, - "destination": { - "name": self.destination_provider_name, - "namespace": self.destination_provider_namespace, - }, - }, - } - } diff --git a/ocp_resources/network_map.py b/ocp_resources/network_map.py index 17379e2bcb..99c68c83b6 100644 --- a/ocp_resources/network_map.py +++ b/ocp_resources/network_map.py @@ -1,9 +1,8 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES -from ocp_resources.mtv import MTV +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource -class NetworkMap(NamespacedResource, MTV): +class NetworkMap(NamespacedResource): """ Migration Toolkit For Virtualization (MTV) NetworkMap object. @@ -56,7 +55,24 @@ def __init__( self.source_provider_namespace = source_provider_namespace self.destination_provider_name = destination_provider_name self.destination_provider_namespace = destination_provider_namespace - self.condition_message_ready = self.ConditionMessage.NETWORK_MAP_READY + + @property + def map_to_dict(self): + return { + "spec": { + "map": self.mapping, + "provider": { + "source": { + "name": self.source_provider_name, + "namespace": self.source_provider_namespace, + }, + "destination": { + "name": self.destination_provider_name, + "namespace": self.destination_provider_namespace, + }, + }, + } + } def to_dict(self) -> None: super().to_dict() diff --git a/ocp_resources/node_maintenance.py b/ocp_resources/node_maintenance.py index 576334b394..cf691cdafa 100644 --- a/ocp_resources/node_maintenance.py +++ b/ocp_resources/node_maintenance.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import Resource diff --git a/ocp_resources/node_network_configuration_policy.py b/ocp_resources/node_network_configuration_policy.py index 052b0e18b1..800c3daeb3 100644 --- a/ocp_resources/node_network_configuration_policy.py +++ b/ocp_resources/node_network_configuration_policy.py @@ -2,7 +2,7 @@ from kubernetes.dynamic.exceptions import ConflictError -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.exceptions import NNCPConfigurationFailed from ocp_resources.node import Node from ocp_resources.node_network_configuration_enactment import ( diff --git a/ocp_resources/node_network_state.py b/ocp_resources/node_network_state.py index c30356f1a1..638db77c52 100644 --- a/ocp_resources/node_network_state.py +++ b/ocp_resources/node_network_state.py @@ -2,7 +2,7 @@ from kubernetes.dynamic.exceptions import ConflictError -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import Resource from timeout_sampler import TimeoutSampler diff --git a/ocp_resources/ocs_initialization.py b/ocp_resources/ocs_initialization.py index d501fe88bf..bda5b0d96a 100644 --- a/ocp_resources/ocs_initialization.py +++ b/ocp_resources/ocs_initialization.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/operator_group.py b/ocp_resources/operator_group.py index 4a8d694325..1217fe143d 100644 --- a/ocp_resources/operator_group.py +++ b/ocp_resources/operator_group.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/operator_source.py b/ocp_resources/operator_source.py index 34265940ee..230bd8f07f 100644 --- a/ocp_resources/operator_source.py +++ b/ocp_resources/operator_source.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/persistent_volume_claim.py b/ocp_resources/persistent_volume_claim.py index efb0f4ebfd..e2aeafc349 100644 --- a/ocp_resources/persistent_volume_claim.py +++ b/ocp_resources/persistent_volume_claim.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/plan.py b/ocp_resources/plan.py index a2b2351a23..0384e26c4a 100644 --- a/ocp_resources/plan.py +++ b/ocp_resources/plan.py @@ -1,10 +1,9 @@ from __future__ import annotations from typing import Any -from ocp_resources.mtv import MTV from ocp_resources.resource import NamespacedResource -class Plan(NamespacedResource, MTV): +class Plan(NamespacedResource): """ Migration Tool for Virtualization (MTV) Plan Resource. @@ -60,8 +59,6 @@ def __init__( self.after_hook_name = after_hook_name self.after_hook_namespace = after_hook_namespace self.target_namespace = target_namespace or self.namespace - self.condition_message_ready = self.ConditionMessage.PLAN_READY - self.condition_message_succeeded = self.ConditionMessage.PLAN_SUCCEEDED self.hooks_array = [] if self.pre_hook_name and self.pre_hook_namespace: diff --git a/ocp_resources/pod.py b/ocp_resources/pod.py index 877fbf3ebe..35f13add8f 100644 --- a/ocp_resources/pod.py +++ b/ocp_resources/pod.py @@ -7,7 +7,7 @@ import kubernetes from timeout_sampler import TimeoutWatch -from ocp_resources.constants import TIMEOUT_5SEC +from ocp_resources.utils.constants import TIMEOUT_5SEC from ocp_resources.exceptions import ExecOnPodError from ocp_resources.node import Node diff --git a/ocp_resources/pod_disruption_budget.py b/ocp_resources/pod_disruption_budget.py index d27d62334f..98c92ef9a0 100644 --- a/ocp_resources/pod_disruption_budget.py +++ b/ocp_resources/pod_disruption_budget.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/priority_class.py b/ocp_resources/priority_class.py index b26c6082bc..33f7e4051c 100644 --- a/ocp_resources/priority_class.py +++ b/ocp_resources/priority_class.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import Resource diff --git a/ocp_resources/provider.py b/ocp_resources/provider.py index 7c056ef9f6..e33f610bbe 100644 --- a/ocp_resources/provider.py +++ b/ocp_resources/provider.py @@ -1,9 +1,8 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES -from ocp_resources.mtv import MTV +from __future__ import annotations from ocp_resources.resource import NamespacedResource -class Provider(NamespacedResource, MTV): +class Provider(NamespacedResource): """ Migration Toolkit For Virtualization (MTV) Provider object. """ @@ -12,33 +11,18 @@ class Provider(NamespacedResource, MTV): def __init__( self, - name=None, - namespace=None, - provider_type=None, - url=None, - secret_name=None, - secret_namespace=None, - vddk_init_image=None, - client=None, - teardown=True, - yaml_file=None, - delete_timeout=TIMEOUT_4MINUTES, + provider_type: str | None = None, + url: str | None = None, + secret_name: str | None = None, + secret_namespace: str | None = None, + vddk_init_image: str | None = None, **kwargs, ): - super().__init__( - name=name, - namespace=namespace, - client=client, - teardown=teardown, - yaml_file=yaml_file, - delete_timeout=delete_timeout, - **kwargs, - ) + super().__init__(**kwargs) self.provider_type = provider_type self.url = url self.secret_name = secret_name self.secret_namespace = secret_namespace - self.condition_message_ready = self.ConditionMessage.PROVIDER_READY self.vddk_init_image = vddk_init_image def to_dict(self) -> None: diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index f1038c4892..149e4f9e4f 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -13,7 +13,7 @@ from io import StringIO from signal import SIGINT, signal from types import TracebackType -from typing import Optional, Any, Dict, List +from typing import Any import kubernetes from kubernetes.dynamic import DynamicClient, ResourceInstance @@ -31,7 +31,7 @@ from simple_logger.logger import get_logger, logging from urllib3.exceptions import MaxRetryError -from ocp_resources.constants import ( +from ocp_resources.utils.constants import ( DEFAULT_CLUSTER_RETRY_EXCEPTIONS, NOT_FOUND_ERROR_EXCEPTION_DICT, PROTOCOL_ERROR_EXCEPTION_DICT, @@ -48,14 +48,15 @@ TimeoutWatch, ) from ocp_resources.exceptions import MissingRequiredArgumentError, MissingResourceResError -from ocp_resources.utils import skip_existing_resource_creation_teardown +from ocp_resources.utils.resource_constants import ResourceConstants +from ocp_resources.utils.utils import skip_existing_resource_creation_teardown LOGGER = get_logger(name=__name__) MAX_SUPPORTED_API_VERSION = "v2" -def _find_supported_resource(dyn_client: DynamicClient, api_group: str, kind: str) -> Optional[ResourceField]: +def _find_supported_resource(dyn_client: DynamicClient, api_group: str, kind: str) -> ResourceField | None: results = dyn_client.resources.search(group=api_group, kind=kind) sorted_results = sorted(results, key=lambda result: KubeAPIVersion(result.api_version), reverse=True) for result in sorted_results: @@ -77,7 +78,7 @@ def _get_api_version(dyn_client: DynamicClient, api_group: str, kind: str) -> st def get_client( - config_file: str = "", config_dict: Dict[str, Any] | None = None, context: str = "", **kwargs: Any + config_file: str = "", config_dict: dict[str, Any] | None = None, context: str = "", **kwargs: Any ) -> DynamicClient: """ Get a kubernetes client. @@ -127,7 +128,7 @@ def get_client( ) -def sub_resource_level(current_class: Any, owner_class: Any, parent_class: Any) -> Optional[str]: +def sub_resource_level(current_class: Any, owner_class: Any, parent_class: Any) -> str | None: # return the name of the last class in MRO list that is not one of base # classes; otherwise return None for class_iterator in reversed([ @@ -140,7 +141,7 @@ def sub_resource_level(current_class: Any, owner_class: Any, parent_class: Any) return None -def replace_key_with_hashed_value(resource_dict: Dict[Any, Any], key_name: str) -> Dict[Any, Any]: +def replace_key_with_hashed_value(resource_dict: dict[Any, Any], key_name: str) -> dict[Any, Any]: """ Recursively search a nested dictionary for a given key and changes its value to "******" if found. @@ -162,7 +163,7 @@ def replace_key_with_hashed_value(resource_dict: Dict[Any, Any], key_name: str) } } } - 2. List path: + 2. list path: A key to be hashed can be found in a dictionary that is in list somewhere in a dictionary, e.g. "a>b[]>c", would hash the value associated with key "c", where dictionary format is: input = { @@ -187,7 +188,7 @@ def replace_key_with_hashed_value(resource_dict: Dict[Any, Any], key_name: str) key_name: The key path to find. Returns: - Dict[Any, Any]: A copy of the input dictionary with the specified key's value replaced with "*******". + dict[Any, Any]: A copy of the input dictionary with the specified key's value replaced with "*******". """ result = copy.deepcopy(resource_dict) @@ -224,7 +225,7 @@ class KubeAPIVersion(Version): def __init__(self, vstring: str): self.vstring = vstring - self.version: List[str | Any] = [] + self.version: list[str | Any] = [] super().__init__(version=vstring) def parse(self, vstring: str): @@ -237,6 +238,7 @@ def parse(self, vstring: str): if len(components) not in (2, 4) or components[0] != "v" or not isinstance(components[1], int): raise ValueError(errmsg) + if len(components) == 4 and (components[2] not in ("alpha", "beta") or not isinstance(components[3], int)): raise ValueError(errmsg) @@ -275,7 +277,7 @@ def __get__(self, obj: Any, owner: Any) -> Any: return self.func(owner) -class Resource: +class Resource(ResourceConstants): """ Base class for API resources """ @@ -285,66 +287,6 @@ class Resource: singular_name: str = "" timeout_seconds: int = TIMEOUT_1MINUTE - class Status: - SUCCEEDED: str = "Succeeded" - FAILED: str = "Failed" - DELETING: str = "Deleting" - DEPLOYED: str = "Deployed" - PENDING: str = "Pending" - COMPLETED: str = "Completed" - RUNNING: str = "Running" - READY: str = "Ready" - TERMINATING: str = "Terminating" - ERROR: str = "Error" - COMPLETE: str = "Complete" - DEPLOYING: str = "Deploying" - SCHEDULING_DISABLED = "Ready,SchedulingDisabled" - CRASH_LOOPBACK_OFF = "CrashLoopBackOff" - IMAGE_PULL_BACK_OFF = "ImagePullBackOff" - ERR_IMAGE_PULL = "ErrImagePull" - ACTIVE = "Active" - - class Condition: - UPGRADEABLE: str = "Upgradeable" - AVAILABLE: str = "Available" - DEGRADED: str = "Degraded" - PROGRESSING: str = "Progressing" - CREATED: str = "Created" - RECONCILE_COMPLETE: str = "ReconcileComplete" - READY: str = "Ready" - FAILING: str = "Failing" - - class Status: - TRUE: str = "True" - FALSE: str = "False" - UNKNOWN: str = "Unknown" - - class Phase: - INSTALL_READY: str = "InstallReady" - SUCCEEDED: str = "Succeeded" - - class Reason: - ALL_REQUIREMENTS_MET: str = "AllRequirementsMet" - INSTALL_SUCCEEDED: str = "InstallSucceeded" - NETWORK_ATTACHMENT_DEFINITION_READY: str = "NetworkAttachmentDefinitionReady" - SYNC_ERROR: str = "SyncError" - - class Type: - NETWORK_READY: str = "NetworkReady" - SUCCESSFUL: str = "Successful" - RUNNING: str = "Running" - - class Type: - CLUSTER_IP = "ClusterIP" - NODE_PORT = "NodePort" - LOAD_BALANCER = "LoadBalancer" - - class Interface: - class State: - UP: str = "up" - DOWN: str = "down" - ABSENT: str = "absent" - class ApiGroup: AAQ_KUBEVIRT_IO: str = "aaq.kubevirt.io" ADMISSIONREGISTRATION_K8S_IO: str = "admissionregistration.k8s.io" @@ -459,18 +401,18 @@ def __init__( yaml_file: str = "", delete_timeout: int = TIMEOUT_4MINUTES, dry_run: bool = False, - node_selector: Dict[str, Any] | None = None, - node_selector_labels: Dict[str, str] | None = None, + node_selector: dict[str, Any] | None = None, + node_selector_labels: dict[str, str] | None = None, config_file: str = "", - config_dict: Dict[str, Any] | None = None, + config_dict: dict[str, Any] | None = None, context: str = "", - label: Dict[str, str] | None = None, - annotations: Dict[str, str] | None = None, + label: dict[str, str] | None = None, + annotations: dict[str, str] | None = None, timeout_seconds: int = TIMEOUT_1MINUTE, api_group: str = "", hash_log_data: bool = True, ensure_exists: bool = False, - kind_dict: Dict[Any, Any] | None = None, + kind_dict: dict[Any, Any] | None = None, wait_for_resource: bool = False, ): """ @@ -493,7 +435,7 @@ def __init__( context (str): Context name for connecting to remote cluster. timeout_seconds (int): timeout for a get api call, call out be terminated after this many seconds label (dict): Resource labels - annotations (Dict[str, str] | None): Resource annotations + annotations (dict[str, str] | None): Resource annotations api_group (str): Resource API group; will overwrite API group definition in resource class hash_log_data (bool): Hash resource content based on resource keys_to_hash property (example: Secret resource) @@ -544,7 +486,7 @@ def __init__( self.namespace: str = "" self.node_selector_spec = self._prepare_node_selector_spec() - self.res: Dict[Any, Any] = self.kind_dict or {} + self.res: dict[Any, Any] = self.kind_dict or {} self.yaml_file_contents: str = "" self.initial_resource_version: str = "" self.logger = self._set_logger() @@ -570,11 +512,11 @@ def _set_logger(self) -> logging.Logger: filename=log_file, ) - def _prepare_node_selector_spec(self) -> Dict[str, str]: + def _prepare_node_selector_spec(self) -> dict[str, str]: return self.node_selector or self.node_selector_labels or {} @ClassProperty - def kind(cls) -> Optional[str]: # noqa: N805 + def kind(cls) -> str | None: return sub_resource_level(cls, NamespacedResource, Resource) def _base_body(self) -> None: @@ -674,7 +616,7 @@ def deploy(self, wait: bool = False) -> Any: self.create(wait=wait) return self - def clean_up(self, wait: bool = True, timeout: Optional[int] = None) -> bool: + def clean_up(self, wait: bool = True, timeout: int | None = None) -> bool: """ For debug, export SKIP_RESOURCE_TEARDOWN to skip resource teardown. Spaces are important in the export dict @@ -728,7 +670,7 @@ def _prepare_resources( **get_kwargs, ).get(*args, **kwargs, timeout_seconds=cls.timeout_seconds) - def _prepare_singular_name_kwargs(self, **kwargs: Any) -> Dict[str, Any]: + def _prepare_singular_name_kwargs(self, **kwargs: Any) -> dict[str, Any]: kwargs = kwargs if kwargs else {} if self.singular_name: kwargs["singular_name"] = self.singular_name @@ -816,7 +758,7 @@ def wait_deleted(self, timeout: int = TIMEOUT_4MINUTES) -> bool: return False @property - def exists(self) -> Optional[ResourceInstance]: + def exists(self) -> ResourceInstance | None: """ Whether self exists on the server """ @@ -879,7 +821,7 @@ def wait_for_status( self.logger.error(f"Status of {self.kind} {self.name} is {current_status}") raise - def create(self, wait: bool = False) -> Optional[ResourceInstance]: + def create(self, wait: bool = False) -> ResourceInstance | None: """ Create resource. @@ -907,7 +849,7 @@ def create(self, wait: bool = False) -> Optional[ResourceInstance]: self.wait() return resource_ - def delete(self, wait: bool = False, timeout: int = TIMEOUT_4MINUTES, body: Dict[str, Any] | None = None) -> bool: + def delete(self, wait: bool = False, timeout: int = TIMEOUT_4MINUTES, body: dict[str, Any] | None = None) -> bool: self.logger.info(f"Delete {self.kind} {self.name}") if self.exists: @@ -946,7 +888,7 @@ def status(self) -> str: self.logger.info(f"Get {self.kind} {self.name} status") return self.instance.status.phase - def update(self, resource_dict: Dict[str, Any]) -> None: + def update(self, resource_dict: dict[str, Any]) -> None: """ Update resource with resource dict @@ -962,7 +904,7 @@ def update(self, resource_dict: Dict[str, Any]) -> None: content_type="application/merge-patch+json", ) - def update_replace(self, resource_dict: Dict[str, Any]) -> None: + def update_replace(self, resource_dict: dict[str, Any]) -> None: """ Replace resource metadata. Use this to remove existing field. (update() will only update existing fields) @@ -975,7 +917,7 @@ def update_replace(self, resource_dict: Dict[str, Any]) -> None: @staticmethod def retry_cluster_exceptions( func, - exceptions_dict: Dict[type[Exception], List[str]] = DEFAULT_CLUSTER_RETRY_EXCEPTIONS, + exceptions_dict: dict[type[Exception], list[str]] = DEFAULT_CLUSTER_RETRY_EXCEPTIONS, timeout: int = TIMEOUT_10SEC, sleep_time: int = 1, **kwargs: Any, @@ -1004,7 +946,7 @@ def get( config_file: str = "", context: str = "", singular_name: str = "", - exceptions_dict: Dict[type[Exception], List[str]] = DEFAULT_CLUSTER_RETRY_EXCEPTIONS, + exceptions_dict: dict[type[Exception], list[str]] = DEFAULT_CLUSTER_RETRY_EXCEPTIONS, raw: bool = False, dyn_client: DynamicClient | None = None, *args: Any, @@ -1053,7 +995,7 @@ def instance(self) -> ResourceInstance: openshift.dynamic.client.ResourceInstance """ - def _instance() -> Optional[ResourceInstance]: + def _instance() -> ResourceInstance | None: return self.api.get(name=self.name) return self.retry_cluster_exceptions(func=_instance) @@ -1068,7 +1010,7 @@ def labels(self) -> ResourceField: """ return self.instance.get("metadata", {})["labels"] - def watcher(self, timeout: int, resource_version: str = "") -> Generator[Dict[str, Any], None, None]: + def watcher(self, timeout: int, resource_version: str = "") -> Generator[dict[str, Any], None, None]: """ Get resource for a given timeout. @@ -1123,7 +1065,7 @@ def wait_for_condition(self, condition: str, status: str, timeout: int = 300) -> if cond["type"] == condition and cond["status"] == status: return - def api_request(self, method: str, action: str, url: str, **params: Any) -> Dict[str, Any]: + def api_request(self, method: str, action: str, url: str, **params: Any) -> dict[str, Any]: """ Handle API requests to resource. @@ -1217,7 +1159,7 @@ def get_all_cluster_resources( client: DynamicClient | None = None, config_file: str = "", context: str = "", - config_dict: Dict[str, Any] | None = None, + config_dict: dict[str, Any] | None = None, *args: Any, **kwargs: Any, ) -> Generator[ResourceField, None, None]: @@ -1264,7 +1206,7 @@ def to_yaml(self) -> str: return resource_yaml @property - def keys_to_hash(self) -> List[str]: + def keys_to_hash(self) -> list[str]: """ Resource attributes list to hash in the logs. @@ -1276,7 +1218,7 @@ def keys_to_hash(self) -> List[str]: """ return [] - def hash_resource_dict(self, resource_dict: Dict[Any, Any]) -> Dict[Any, Any]: + def hash_resource_dict(self, resource_dict: dict[Any, Any]) -> dict[Any, Any]: if not isinstance(resource_dict, dict): raise ValueError("Expected a dictionary as the first argument") @@ -1357,7 +1299,7 @@ def get( config_file: str = "", context: str = "", singular_name: str = "", - exceptions_dict: Dict[type[Exception], List[str]] = DEFAULT_CLUSTER_RETRY_EXCEPTIONS, + exceptions_dict: dict[type[Exception], list[str]] = DEFAULT_CLUSTER_RETRY_EXCEPTIONS, raw: bool = False, dyn_client: DynamicClient | None = None, *args: Any, @@ -1435,7 +1377,7 @@ def to_dict(self) -> None: class ResourceEditor: def __init__( - self, patches: Dict[Any, Any], action: str = "update", user_backups: Dict[Any, Any] | None = None + self, patches: dict[Any, Any], action: str = "update", user_backups: dict[Any, Any] | None = None ) -> None: """ Args: @@ -1463,16 +1405,16 @@ def __init__( self._patches = self._dictify_resourcefield(res=patches) self.action = action self.user_backups = user_backups - self._backups: Dict[Any, Any] = {} + self._backups: dict[Any, Any] = {} @property - def backups(self) -> Dict[Any, Any]: + def backups(self) -> dict[Any, Any]: """Returns a dict {: } The backup dict kept for each resource edited""" return self._backups @property - def patches(self) -> Dict[Any, Any]: + def patches(self) -> dict[Any, Any]: """Returns the patches dict provided in the constructor""" return self._patches @@ -1556,7 +1498,7 @@ def _dictify_resourcefield(res: Any) -> Any: return res @staticmethod - def _create_backup(original: Dict[Any, Any], patch: Dict[Any, Any]) -> Dict[Any, Any]: + def _create_backup(original: dict[Any, Any], patch: dict[Any, Any]) -> dict[Any, Any]: """ Args: original (dict*): source of values to back up if necessary @@ -1575,7 +1517,7 @@ def _create_backup(original: Dict[Any, Any], patch: Dict[Any, Any]) -> Dict[Any, # when both are dicts, get the diff (recursively if need be) if isinstance(original, dict) and isinstance(patch, dict): - diff_dict: Dict[Any, Any] = {} + diff_dict: dict[Any, Any] = {} for key, value in patch.items(): if key not in original: diff_dict[key] = None @@ -1597,7 +1539,7 @@ def _create_backup(original: Dict[Any, Any], patch: Dict[Any, Any]) -> Dict[Any, return None @staticmethod - def _apply_patches(patches: Dict[Any, Any], action_text: str, action: str) -> None: + def _apply_patches(patches: dict[Any, Any], action_text: str, action: str) -> None: """ Updates provided Resource objects with provided yaml patches @@ -1635,8 +1577,8 @@ def _apply_patches(patches: Dict[Any, Any], action_text: str, action: str) -> No resource.update_replace(resource_dict=patch) # replace the resource metadata - def _apply_patches_sampler(self, patches: Dict[Any, Any], action_text: str, action: str) -> ResourceInstance: - exceptions_dict: Dict[type[Exception], List[str]] = {ConflictError: []} + def _apply_patches_sampler(self, patches: dict[Any, Any], action_text: str, action: str) -> ResourceInstance: + exceptions_dict: dict[type[Exception], list[str]] = {ConflictError: []} exceptions_dict.update(DEFAULT_CLUSTER_RETRY_EXCEPTIONS) return Resource.retry_cluster_exceptions( func=self._apply_patches, diff --git a/ocp_resources/role.py b/ocp_resources/role.py index 65b3c2a500..8ba9e92f82 100644 --- a/ocp_resources/role.py +++ b/ocp_resources/role.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # API reference: # https://docs.openshift.com/container-platform/4.11/rest_api/rbac_apis/role-rbac-authorization-k8s-io-v1.html -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import MissingRequiredArgumentError, NamespacedResource diff --git a/ocp_resources/role_binding.py b/ocp_resources/role_binding.py index 6a7dd8aa68..f69f2c9cb8 100644 --- a/ocp_resources/role_binding.py +++ b/ocp_resources/role_binding.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/route.py b/ocp_resources/route.py index 15ced74a49..978db80569 100644 --- a/ocp_resources/route.py +++ b/ocp_resources/route.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/secret.py b/ocp_resources/secret.py index 8d84308bd2..2efde0d33b 100644 --- a/ocp_resources/secret.py +++ b/ocp_resources/secret.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/sriov_network.py b/ocp_resources/sriov_network.py index 8e9b3fd7bf..9035a34629 100644 --- a/ocp_resources/sriov_network.py +++ b/ocp_resources/sriov_network.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/sriov_network_node_policy.py b/ocp_resources/sriov_network_node_policy.py index 72bd4bf68d..90e913c603 100644 --- a/ocp_resources/sriov_network_node_policy.py +++ b/ocp_resources/sriov_network_node_policy.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/storage_map.py b/ocp_resources/storage_map.py index b257b06738..cab91ff9ec 100644 --- a/ocp_resources/storage_map.py +++ b/ocp_resources/storage_map.py @@ -1,9 +1,8 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES -from ocp_resources.mtv import MTV +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource -class StorageMap(NamespacedResource, MTV): +class StorageMap(NamespacedResource): """ Migration Toolkit For Virtualization (MTV) StorageMap object. @@ -59,7 +58,24 @@ def __init__( self.source_provider_namespace = source_provider_namespace self.destination_provider_name = destination_provider_name self.destination_provider_namespace = destination_provider_namespace - self.condition_message_ready = self.ConditionMessage.STORAGE_MAP_READY + + @property + def map_to_dict(self): + return { + "spec": { + "map": self.mapping, + "provider": { + "source": { + "name": self.source_provider_name, + "namespace": self.source_provider_namespace, + }, + "destination": { + "name": self.destination_provider_name, + "namespace": self.destination_provider_namespace, + }, + }, + } + } def to_dict(self) -> None: super().to_dict() diff --git a/ocp_resources/subscription.py b/ocp_resources/subscription.py index d9fae1fa78..c2e6f6be5d 100644 --- a/ocp_resources/subscription.py +++ b/ocp_resources/subscription.py @@ -1,4 +1,4 @@ -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/upload_token_request.py b/ocp_resources/upload_token_request.py index ce9082dd89..8983cd63e2 100644 --- a/ocp_resources/upload_token_request.py +++ b/ocp_resources/upload_token_request.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from ocp_resources.constants import TIMEOUT_4MINUTES +from ocp_resources.utils.constants import TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/constants.py b/ocp_resources/utils/constants.py similarity index 100% rename from ocp_resources/constants.py rename to ocp_resources/utils/constants.py diff --git a/ocp_resources/utils/resource_constants.py b/ocp_resources/utils/resource_constants.py new file mode 100644 index 0000000000..503f6c6c85 --- /dev/null +++ b/ocp_resources/utils/resource_constants.py @@ -0,0 +1,66 @@ +class ResourceConstants: + class Status: + SUCCEEDED: str = "Succeeded" + FAILED: str = "Failed" + DELETING: str = "Deleting" + DEPLOYED: str = "Deployed" + PENDING: str = "Pending" + COMPLETED: str = "Completed" + RUNNING: str = "Running" + READY: str = "Ready" + TERMINATING: str = "Terminating" + ERROR: str = "Error" + COMPLETE: str = "Complete" + DEPLOYING: str = "Deploying" + SCHEDULING_DISABLED = "Ready,SchedulingDisabled" + CRASH_LOOPBACK_OFF = "CrashLoopBackOff" + IMAGE_PULL_BACK_OFF = "ImagePullBackOff" + ERR_IMAGE_PULL = "ErrImagePull" + ACTIVE = "Active" + + class Condition: + UPGRADEABLE: str = "Upgradeable" + AVAILABLE: str = "Available" + DEGRADED: str = "Degraded" + PROGRESSING: str = "Progressing" + CREATED: str = "Created" + RECONCILE_COMPLETE: str = "ReconcileComplete" + READY: str = "Ready" + FAILING: str = "Failing" + + class Status: + TRUE: str = "True" + FALSE: str = "False" + UNKNOWN: str = "Unknown" + + class Phase: + INSTALL_READY: str = "InstallReady" + SUCCEEDED: str = "Succeeded" + + class Reason: + ALL_REQUIREMENTS_MET: str = "AllRequirementsMet" + INSTALL_SUCCEEDED: str = "InstallSucceeded" + NETWORK_ATTACHMENT_DEFINITION_READY: str = "NetworkAttachmentDefinitionReady" + SYNC_ERROR: str = "SyncError" + + class Type: + NETWORK_READY: str = "NetworkReady" + SUCCESSFUL: str = "Successful" + RUNNING: str = "Running" + + class Type: + CLUSTER_IP = "ClusterIP" + NODE_PORT = "NodePort" + LOAD_BALANCER = "LoadBalancer" + + class Interface: + class State: + UP: str = "up" + DOWN: str = "down" + ABSENT: str = "absent" + + class ProviderType: + VSPHERE = "vsphere" + OPENSHIFT = "openshift" + RHV = "ovirt" + OVA = "ova" diff --git a/ocp_resources/utils.py b/ocp_resources/utils/utils.py similarity index 100% rename from ocp_resources/utils.py rename to ocp_resources/utils/utils.py diff --git a/ocp_resources/virtual_machine.py b/ocp_resources/virtual_machine.py index 8e714aba99..0602a0906f 100644 --- a/ocp_resources/virtual_machine.py +++ b/ocp_resources/virtual_machine.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from ocp_resources.constants import ( +from ocp_resources.utils.constants import ( DEFAULT_CLUSTER_RETRY_EXCEPTIONS, PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES, diff --git a/ocp_resources/virtual_machine_export.py b/ocp_resources/virtual_machine_export.py index 1cd52c8785..6d7627b3bf 100644 --- a/ocp_resources/virtual_machine_export.py +++ b/ocp_resources/virtual_machine_export.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from ocp_resources.constants import TIMEOUT_1MINUTE +from ocp_resources.utils.constants import TIMEOUT_1MINUTE from ocp_resources.persistent_volume_claim import PersistentVolumeClaim from ocp_resources.resource import MissingRequiredArgumentError, NamespacedResource from ocp_resources.virtual_machine import VirtualMachine diff --git a/ocp_resources/virtual_machine_import.py b/ocp_resources/virtual_machine_import.py index 309e06a4ec..5905172e79 100644 --- a/ocp_resources/virtual_machine_import.py +++ b/ocp_resources/virtual_machine_import.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from ocp_resources.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES +from ocp_resources.utils.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource from timeout_sampler import TimeoutExpiredError, TimeoutSampler from ocp_resources.virtual_machine import VirtualMachine diff --git a/ocp_resources/virtual_machine_instance.py b/ocp_resources/virtual_machine_instance.py index fdf1e1b710..e67e7f61ac 100644 --- a/ocp_resources/virtual_machine_instance.py +++ b/ocp_resources/virtual_machine_instance.py @@ -3,7 +3,7 @@ import xmltodict from kubernetes.dynamic.exceptions import ResourceNotFoundError -from ocp_resources.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES +from ocp_resources.utils.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES from ocp_resources.node import Node from ocp_resources.pod import Pod from ocp_resources.resource import NamespacedResource diff --git a/ocp_resources/virtual_machine_restore.py b/ocp_resources/virtual_machine_restore.py index a01f414900..f269b18f15 100644 --- a/ocp_resources/virtual_machine_restore.py +++ b/ocp_resources/virtual_machine_restore.py @@ -2,7 +2,7 @@ from kubernetes.dynamic.exceptions import ResourceNotFoundError -from ocp_resources.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES +from ocp_resources.utils.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource from timeout_sampler import TimeoutSampler, TimeoutWatch from ocp_resources.virtual_machine import VirtualMachine diff --git a/ocp_resources/virtual_machine_snapshot.py b/ocp_resources/virtual_machine_snapshot.py index 49eb6fbfdb..ee5f97abab 100644 --- a/ocp_resources/virtual_machine_snapshot.py +++ b/ocp_resources/virtual_machine_snapshot.py @@ -2,7 +2,7 @@ from kubernetes.dynamic.exceptions import ResourceNotFoundError -from ocp_resources.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES +from ocp_resources.utils.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES from ocp_resources.resource import NamespacedResource from timeout_sampler import TimeoutSampler, TimeoutWatch from ocp_resources.virtual_machine import VirtualMachine