diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5de7ab3241..a723fb917f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,57 +1,44 @@ default_language_version: - python: python3 + python: python3 repos: - - repo: https://github.com/myint/autoflake - rev: "v2.0.2" - hooks: - - id: autoflake - args: - - --in-place - - --remove-unused-variables - - --remove-all-unused-imports - - - repo: https://github.com/hadialqattan/pycln - rev: "v2.1.3" + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: "v4.6.0" hooks: - - id: pycln + - id: check-merge-conflict + - id: debug-statements + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] # Do not process Markdown files. + - id: end-of-file-fixer + - id: check-ast + - id: check-builtin-literals + - id: check-docstring-first + - id: check-toml - - repo: https://github.com/pre-commit/mirrors-isort - rev: "v5.10.1" + - repo: https://github.com/PyCQA/flake8 + rev: "7.1.0" hooks: - - id: isort + - id: flake8 + args: [--config=.flake8] + additional_dependencies: ["flake8-mutable"] - - repo: https://github.com/psf/black - rev: "23.1.0" + - repo: https://github.com/Yelp/detect-secrets + rev: v1.5.0 hooks: - - id: black - args: [--preview] + - id: detect-secrets - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: "v4.4.0" + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.5.1 hooks: - - id: check-merge-conflict - - id: debug-statements - - id: trailing-whitespace - args: [--markdown-linebreak-ext=md] # Do not process Markdown files. - - id: end-of-file-fixer - - id: check-ast - - id: check-builtin-literals + - id: ruff + - id: ruff-format - - repo: https://github.com/PyCQA/flake8 - rev: "6.0.0" + - repo: https://github.com/renovatebot/pre-commit-hooks + rev: 37.426.0 hooks: - - id: flake8 - args: [--max-line-length=120] - additional_dependencies: [ - "git+https://github.com/RedHatQE/flake8-plugins.git", - "pep8-naming", - "flake8-comprehensions", - "flake8-mutable", - "flake8-simplify", - ] + - id: renovate-config-validator - - repo: https://github.com/Yelp/detect-secrets - rev: v1.4.0 + - repo: https://github.com/gitleaks/gitleaks + rev: v8.18.4 hooks: - - id: detect-secrets + - id: gitleaks diff --git a/examples/special_cases.py b/examples/special_cases.py index 81408eeb70..6032241b73 100644 --- a/examples/special_cases.py +++ b/examples/special_cases.py @@ -2,6 +2,7 @@ Some resources have the same `kind` but different API groups. For example: `Network` which exists in both operator.openshift.io and config.openshift.io API groups """ + from ocp_resources.network import Network # To get the Network resource which uses the default API in the class ("config.openshift.io") diff --git a/ocp_resources/backup.py b/ocp_resources/backup.py index 460de31681..4cb83386a7 100644 --- a/ocp_resources/backup.py +++ b/ocp_resources/backup.py @@ -40,13 +40,11 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "includedNamespaces": self.included_namespaces, - } + self.res.update({ + "spec": { + "includedNamespaces": self.included_namespaces, } - ) + }) if self.excluded_resources: self.res["spec"]["excludedResources"] = self.excluded_resources diff --git a/ocp_resources/catalog_source.py b/ocp_resources/catalog_source.py index ae896c67c2..b3c5b52884 100644 --- a/ocp_resources/catalog_source.py +++ b/ocp_resources/catalog_source.py @@ -33,31 +33,25 @@ def __init__( self.image = image self.display_name = display_name self.publisher = publisher - self.update_strategy_registry_poll_interval = ( - update_strategy_registry_poll_interval - ) + self.update_strategy_registry_poll_interval = update_strategy_registry_poll_interval def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "sourceType": self.source_type, - "image": self.image, - "displayName": self.display_name, - "publisher": self.publisher, - } + self.res.update({ + "spec": { + "sourceType": self.source_type, + "image": self.image, + "displayName": self.display_name, + "publisher": self.publisher, } - ) + }) if self.update_strategy_registry_poll_interval: - self.res["spec"].update( - { - "updateStrategy": { - "registryPoll": { - "interval": self.update_strategy_registry_poll_interval, - }, + self.res["spec"].update({ + "updateStrategy": { + "registryPoll": { + "interval": self.update_strategy_registry_poll_interval, }, - } - ) + }, + }) diff --git a/ocp_resources/catalog_source_config.py b/ocp_resources/catalog_source_config.py index 6c0ea5d21a..3765148f81 100644 --- a/ocp_resources/catalog_source_config.py +++ b/ocp_resources/catalog_source_config.py @@ -39,17 +39,15 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "source": self.source, - "targetNamespace": self.target_namespace, - "packages": self.packages, - "csDisplayName": self.cs_display_name, - "csPublisher": self.cs_publisher, - } + self.res.update({ + "spec": { + "source": self.source, + "targetNamespace": self.target_namespace, + "packages": self.packages, + "csDisplayName": self.cs_display_name, + "csPublisher": self.cs_publisher, } - ) + }) def wait_for_csc_status(self, status, timeout=120): """ @@ -80,7 +78,5 @@ def wait_for_csc_status(self, status, timeout=120): except TimeoutExpiredError: if current_status: - self.logger.error( - f"Status of {self.kind} {self.name} is {current_status}" - ) + self.logger.error(f"Status of {self.kind} {self.name} is {current_status}") raise diff --git a/ocp_resources/cdi_config.py b/ocp_resources/cdi_config.py index 58056bef87..1ee34e9cd1 100644 --- a/ocp_resources/cdi_config.py +++ b/ocp_resources/cdi_config.py @@ -34,9 +34,7 @@ def wait_until_upload_url_changed(self, uploadproxy_url, timeout=TIMEOUT_4MINUTE Returns: bool: True if url is equal to uploadProxyURL. """ - self.logger.info( - f"Wait for {self.kind} {self.name} to ensure current URL == uploadProxyURL" - ) + self.logger.info(f"Wait for {self.kind} {self.name} to ensure current URL == uploadProxyURL") samples = TimeoutSampler( wait_timeout=timeout, sleep=1, diff --git a/ocp_resources/controller_revision.py b/ocp_resources/controller_revision.py index bfd489fbf1..f72cd1cda8 100644 --- a/ocp_resources/controller_revision.py +++ b/ocp_resources/controller_revision.py @@ -38,8 +38,6 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if self.owner_references: - self.res.setdefault("metadata", {}).update( - {"ownerReference": self.owner_references} - ) + self.res.setdefault("metadata", {}).update({"ownerReference": self.owner_references}) if self.revision_object: self.res.update({"data": self.revision_object.res}) diff --git a/ocp_resources/cron_job.py b/ocp_resources/cron_job.py index 4f0ae4cb77..734e33181d 100644 --- a/ocp_resources/cron_job.py +++ b/ocp_resources/cron_job.py @@ -75,29 +75,20 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if not (self.job_template and self.schedule): - raise ValueError( - "yaml_file or parameters 'job_template' and 'schedule' are" - " required." - ) - self.res.update( - { - "spec": { - "jobTemplate": self.job_template, - "schedule": self.schedule, - } + raise ValueError("yaml_file or parameters 'job_template' and 'schedule' are" " required.") + self.res.update({ + "spec": { + "jobTemplate": self.job_template, + "schedule": self.schedule, } - ) + }) if self.timezone: self.res["spec"]["timezone"] = self.timezone if self.suspend: self.res["spec"]["suspend"] = self.suspend if self.successful_jobs_history_limit: - self.res["spec"][ - "successfulJobsHistoryLimit" - ] = self.successful_jobs_history_limit + self.res["spec"]["successfulJobsHistoryLimit"] = self.successful_jobs_history_limit if self.failed_jobs_history_limit: - self.res["spec"][ - "failedJobsHistoryLimit" - ] = self.failed_jobs_history_limit + self.res["spec"]["failedJobsHistoryLimit"] = self.failed_jobs_history_limit if self.concurrency_policy: self.res["spec"]["concurrencyPolicy"] = self.concurrency_policy diff --git a/ocp_resources/csi_storage_capacity.py b/ocp_resources/csi_storage_capacity.py index d19fda9858..2f9597fb8a 100644 --- a/ocp_resources/csi_storage_capacity.py +++ b/ocp_resources/csi_storage_capacity.py @@ -61,14 +61,10 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if not self.storage_class_name: - raise ValueError( - "yaml_file or parameter 'storage_class_name' is required." - ) - self.res.update( - { - "storageClassName": self.storage_class_name, - } - ) + raise ValueError("yaml_file or parameter 'storage_class_name' is required.") + self.res.update({ + "storageClassName": self.storage_class_name, + }) if self.maximum_volume_size: self.res["maximumVolumeSize"] = self.maximum_volume_size if self.node_topology: diff --git a/ocp_resources/daemonset.py b/ocp_resources/daemonset.py index 372692334f..1961cc1daa 100644 --- a/ocp_resources/daemonset.py +++ b/ocp_resources/daemonset.py @@ -36,10 +36,7 @@ def wait_until_deployed(self, timeout=TIMEOUT_4MINUTES): status = sample.items[0].status desired_number_scheduled = status.desiredNumberScheduled number_ready = status.numberReady - if ( - desired_number_scheduled > 0 - and desired_number_scheduled == number_ready - ): + if desired_number_scheduled > 0 and desired_number_scheduled == number_ready: return def delete(self, wait=False, timeout=TIMEOUT_4MINUTES, body=None): diff --git a/ocp_resources/data_import_cron.py b/ocp_resources/data_import_cron.py index aea9bd24d7..a7701131b7 100644 --- a/ocp_resources/data_import_cron.py +++ b/ocp_resources/data_import_cron.py @@ -59,31 +59,21 @@ def to_dict(self): if self.image_stream and self.url: raise ValueError("imageStream and url can not coexist") - self.res.update( - { - "spec": { - "template": { - "spec": { - "source": { - "registry": {"pullMethod": self.pull_method} - }, - "storage": { - "resources": {"requests": {"storage": self.size}} - }, - } + self.res.update({ + "spec": { + "template": { + "spec": { + "source": {"registry": {"pullMethod": self.pull_method}}, + "storage": {"resources": {"requests": {"storage": self.size}}}, } } } - ) + }) spec = self.res["spec"]["template"]["spec"] if self.bind_immediate_annotation: - self.res["metadata"].setdefault("annotations", {}).update( - { - f"{NamespacedResource.ApiGroup.CDI_KUBEVIRT_IO}/storage.bind.immediate.requested": ( - "true" - ) - } - ) + self.res["metadata"].setdefault("annotations", {}).update({ + f"{NamespacedResource.ApiGroup.CDI_KUBEVIRT_IO}/storage.bind.immediate.requested": ("true") + }) if self.image_stream: spec["source"]["registry"]["imageStream"] = self.image_stream if self.url: diff --git a/ocp_resources/data_source.py b/ocp_resources/data_source.py index 3465331d23..8a857a1b23 100644 --- a/ocp_resources/data_source.py +++ b/ocp_resources/data_source.py @@ -33,13 +33,11 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "source": self.source, - }, - } - ) + self.res.update({ + "spec": { + "source": self.source, + }, + }) @property def pvc(self): diff --git a/ocp_resources/datavolume.py b/ocp_resources/datavolume.py index 4914d44db8..3d707c6860 100644 --- a/ocp_resources/datavolume.py +++ b/ocp_resources/datavolume.py @@ -151,16 +151,14 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "source": {self.source: {"url": self.url}}, - self.api_name: { - "resources": {"requests": {"storage": self.size}}, - }, - } + self.res.update({ + "spec": { + "source": {self.source: {"url": self.url}}, + self.api_name: { + "resources": {"requests": {"storage": self.size}}, + }, } - ) + }) if self.access_modes: self.res["spec"][self.api_name]["accessModes"] = [self.access_modes] if self.content_type: @@ -174,31 +172,21 @@ def to_dict(self): if self.source == "http" or "registry": self.res["spec"]["source"][self.source]["url"] = self.url if self.cert_configmap: - self.res["spec"]["source"][self.source][ - "certConfigMap" - ] = self.cert_configmap + self.res["spec"]["source"][self.source]["certConfigMap"] = self.cert_configmap if self.source == "upload" or self.source == "blank": self.res["spec"]["source"][self.source] = {} if self.hostpath_node: - self.res["metadata"].setdefault("annotations", {}).update( - { - f"{NamespacedResource.ApiGroup.KUBEVIRT_IO}/provisionOnNode": ( - self.hostpath_node - ) - } - ) + self.res["metadata"].setdefault("annotations", {}).update({ + f"{NamespacedResource.ApiGroup.KUBEVIRT_IO}/provisionOnNode": (self.hostpath_node) + }) if self.multus_annotation: - self.res["metadata"].setdefault("annotations", {}).update( - { - f"{NamespacedResource.ApiGroup.K8S_V1_CNI_CNCF_IO}/networks": ( - self.multus_annotation - ) - } - ) + self.res["metadata"].setdefault("annotations", {}).update({ + f"{NamespacedResource.ApiGroup.K8S_V1_CNI_CNCF_IO}/networks": (self.multus_annotation) + }) if self.bind_immediate_annotation: - self.res["metadata"].setdefault("annotations", {}).update( - {f"{self.api_group}/storage.bind.immediate.requested": "true"} - ) + self.res["metadata"].setdefault("annotations", {}).update({ + f"{self.api_group}/storage.bind.immediate.requested": "true" + }) if self.source == "pvc": self.res["spec"]["source"]["pvc"] = { "name": self.source_pvc or "dv-source", @@ -207,13 +195,9 @@ def to_dict(self): if self.preallocation is not None: self.res["spec"]["preallocation"] = self.preallocation if self.delete_after_completion: - self.res["metadata"].setdefault("annotations", {}).update( - { - f"{self.api_group}/storage.deleteAfterCompletion": ( - self.delete_after_completion - ) - } - ) + self.res["metadata"].setdefault("annotations", {}).update({ + f"{self.api_group}/storage.deleteAfterCompletion": (self.delete_after_completion) + }) def wait_deleted(self, timeout=TIMEOUT_4MINUTES): """ @@ -233,9 +217,7 @@ def wait(self, timeout=600, failure_timeout=120): # If DV's status is not Pending, continue with the flow self.wait_for_status(status=self.Status.SUCCEEDED, timeout=timeout) - self.pvc.wait_for_status( - status=PersistentVolumeClaim.Status.BOUND, timeout=timeout - ) + self.pvc.wait_for_status(status=PersistentVolumeClaim.Status.BOUND, timeout=timeout) @property def pvc(self): @@ -281,9 +263,7 @@ def _check_none_pending_status(self, failure_timeout=120): def wait_for_dv_success(self, timeout=600, failure_timeout=120): self.logger.info(f"Wait DV success for {timeout} seconds") self._check_none_pending_status(failure_timeout=failure_timeout) - self.pvc.wait_for_status( - status=PersistentVolumeClaim.Status.BOUND, timeout=timeout - ) + self.pvc.wait_for_status(status=PersistentVolumeClaim.Status.BOUND, timeout=timeout) # if garbage collector enabled, the DV deleted once succeeded try: for sample in TimeoutSampler( diff --git a/ocp_resources/deployment.py b/ocp_resources/deployment.py index 4dd790e684..8aa6857438 100644 --- a/ocp_resources/deployment.py +++ b/ocp_resources/deployment.py @@ -67,9 +67,6 @@ def wait_for_replicas(self, deployed=True, timeout=TIMEOUT_4MINUTES): if ( (deployed and spec_replicas) - and spec_replicas - == updated_replicas - == available_replicas - == ready_replicas + and spec_replicas == updated_replicas == available_replicas == ready_replicas ) or not (deployed or spec_replicas or total_replicas): return diff --git a/ocp_resources/endpoint_slice.py b/ocp_resources/endpoint_slice.py index 9fee7d166c..c0606eb28d 100644 --- a/ocp_resources/endpoint_slice.py +++ b/ocp_resources/endpoint_slice.py @@ -55,15 +55,10 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if not (self.address_type and self.endpoints): - raise ValueError( - "yaml_file or parameters 'address_type' and 'endpoints' are" - " required." - ) - self.res.update( - { - "addressTypes": self.address_type, - "endpoints": self.endpoints, - } - ) + raise ValueError("yaml_file or parameters 'address_type' and 'endpoints' are" " required.") + self.res.update({ + "addressTypes": self.address_type, + "endpoints": self.endpoints, + }) if self.ports: self.res["ports"] = self.ports diff --git a/ocp_resources/endpoints.py b/ocp_resources/endpoints.py index 9cce321b46..4407be207c 100644 --- a/ocp_resources/endpoints.py +++ b/ocp_resources/endpoints.py @@ -52,14 +52,10 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if not (self.addresses and self.ports): - raise ValueError( - "yaml_file or parameters 'addresses' and 'ports' are required." - ) - self.res.update( - { - "subsets": { - "addresses": self.addresses, - "ports": self.ports, - } + raise ValueError("yaml_file or parameters 'addresses' and 'ports' are required.") + self.res.update({ + "subsets": { + "addresses": self.addresses, + "ports": self.ports, } - ) + }) diff --git a/ocp_resources/event.py b/ocp_resources/event.py index df5037d92a..fbc51218ee 100644 --- a/ocp_resources/event.py +++ b/ocp_resources/event.py @@ -54,9 +54,7 @@ def get( f" resource_version={resource_version}, timeout={timeout}" ) - event_listener = dyn_client.resources.get( - api_version=cls.api_version, kind=cls.__name__ - ) + event_listener = dyn_client.resources.get(api_version=cls.api_version, kind=cls.__name__) yield from event_listener.watch( namespace=namespace, name=name, diff --git a/ocp_resources/hook.py b/ocp_resources/hook.py index 79e2d76795..4636f4ebd4 100644 --- a/ocp_resources/hook.py +++ b/ocp_resources/hook.py @@ -42,11 +42,9 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "image": self.image, - "playbook": self.playbook, - }, - } - ) + self.res.update({ + "spec": { + "image": self.image, + "playbook": self.playbook, + }, + }) diff --git a/ocp_resources/host.py b/ocp_resources/host.py index c457f9a59b..f974f66c39 100644 --- a/ocp_resources/host.py +++ b/ocp_resources/host.py @@ -46,19 +46,17 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "id": self.host_id, - "ipAddress": self.ip_address, - "secret": { - "name": self.secret_name, - "namespace": self.secret_namespace, - }, - "provider": { - "name": self.provider_name, - "namespace": self.provider_namespace, - }, - } + self.res.update({ + "spec": { + "id": self.host_id, + "ipAddress": self.ip_address, + "secret": { + "name": self.secret_name, + "namespace": self.secret_namespace, + }, + "provider": { + "name": self.provider_name, + "namespace": self.provider_namespace, + }, } - ) + }) diff --git a/ocp_resources/hyperconverged.py b/ocp_resources/hyperconverged.py index 2889931d8d..e21771f597 100644 --- a/ocp_resources/hyperconverged.py +++ b/ocp_resources/hyperconverged.py @@ -33,11 +33,7 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if self.infra: - self.res.setdefault("spec", {}).setdefault("infra", {}).update( - self.infra - ) + self.res.setdefault("spec", {}).setdefault("infra", {}).update(self.infra) if self.workloads: - self.res.setdefault("spec", {}).setdefault("workloads", {}).update( - self.workloads - ) + self.res.setdefault("spec", {}).setdefault("workloads", {}).update(self.workloads) diff --git a/ocp_resources/image_content_source_policy.py b/ocp_resources/image_content_source_policy.py index 62e48048ef..298c36096e 100644 --- a/ocp_resources/image_content_source_policy.py +++ b/ocp_resources/image_content_source_policy.py @@ -28,6 +28,4 @@ def to_dict(self): if not self.yaml_file: if not self.repository_digest_mirrors: raise ValueError("repository_digest_mirrors must be defined") - self.res["spec"] = { - "repositoryDigestMirrors": self.repository_digest_mirrors - } + self.res["spec"] = {"repositoryDigestMirrors": self.repository_digest_mirrors} diff --git a/ocp_resources/image_stream.py b/ocp_resources/image_stream.py index 184567e88c..2a054f5f70 100644 --- a/ocp_resources/image_stream.py +++ b/ocp_resources/image_stream.py @@ -39,11 +39,9 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "lookupPolicy": {"local": self.lookup_policy}, - "tags": self.tags, - } + self.res.update({ + "spec": { + "lookupPolicy": {"local": self.lookup_policy}, + "tags": self.tags, } - ) + }) diff --git a/ocp_resources/ip_address_pool.py b/ocp_resources/ip_address_pool.py index 527852f203..618cf1432c 100644 --- a/ocp_resources/ip_address_pool.py +++ b/ocp_resources/ip_address_pool.py @@ -43,10 +43,7 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if not self.addresses: - raise ValueError( - "Either required parameter is missing 'addresses' or provide" - " yaml_file." - ) + raise ValueError("Either required parameter is missing 'addresses' or provide" " yaml_file.") self.res["spec"] = {"addresses": self.addresses} diff --git a/ocp_resources/job.py b/ocp_resources/job.py index 705df08850..4e336f55a4 100644 --- a/ocp_resources/job.py +++ b/ocp_resources/job.py @@ -76,14 +76,10 @@ def to_dict(self): self.res["spec"]["template"]["spec"]["containers"] = self.containers if self.service_account: - self.res["spec"]["template"]["spec"][ - "serviceAccount" - ] = self.service_account + self.res["spec"]["template"]["spec"]["serviceAccount"] = self.service_account if self.restart_policy: - self.res["spec"]["template"]["spec"][ - "restartPolicy" - ] = self.restart_policy + self.res["spec"]["template"]["spec"]["restartPolicy"] = self.restart_policy def delete(self, wait=False, timeout=TIMEOUT_4MINUTES, body=None): """ @@ -98,7 +94,5 @@ def delete(self, wait=False, timeout=TIMEOUT_4MINUTES, body=None): bool: True if delete succeeded, False otherwise. """ if not body and self.background_propagation_policy: - body = kubernetes.client.V1DeleteOptions( - propagation_policy=self.background_propagation_policy - ) + body = kubernetes.client.V1DeleteOptions(propagation_policy=self.background_propagation_policy) return super().delete(wait=wait, timeout=timeout, body=body) diff --git a/ocp_resources/kube_descheduler.py b/ocp_resources/kube_descheduler.py index 576fe8ad12..7e860fc0ef 100644 --- a/ocp_resources/kube_descheduler.py +++ b/ocp_resources/kube_descheduler.py @@ -51,15 +51,13 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "deschedulingIntervalSeconds": self.descheduling_interval, - "logLevel": self.log_level, - "managementState": self.management_state, - "mode": self.mode, - "operatorLogLevel": self.operator_log_level, - "profiles": self.profiles, - } + self.res.update({ + "spec": { + "deschedulingIntervalSeconds": self.descheduling_interval, + "logLevel": self.log_level, + "managementState": self.management_state, + "mode": self.mode, + "operatorLogLevel": self.operator_log_level, + "profiles": self.profiles, } - ) + }) diff --git a/ocp_resources/l2_advertisement.py b/ocp_resources/l2_advertisement.py index f5c27a25e3..4eeb3fa697 100644 --- a/ocp_resources/l2_advertisement.py +++ b/ocp_resources/l2_advertisement.py @@ -51,6 +51,4 @@ def to_dict(self): self.res["spec"]["ipAddressPools"] = self.ip_address_pools if self.ip_address_pools_selectors: - self.res["spec"][ - "ipAddressPoolSelectors" - ] = self.ip_address_pools_selectors + self.res["spec"]["ipAddressPoolSelectors"] = self.ip_address_pools_selectors diff --git a/ocp_resources/machine.py b/ocp_resources/machine.py index 1a7e88a674..d37c504ec8 100644 --- a/ocp_resources/machine.py +++ b/ocp_resources/machine.py @@ -35,15 +35,11 @@ def cluster_name(self): @property def machine_role(self): - return self.instance.metadata.labels[ - f"{self.api_group}/cluster-api-machine-role" - ] + return self.instance.metadata.labels[f"{self.api_group}/cluster-api-machine-role"] @property def machine_type(self): - return self.instance.metadata.labels[ - f"{self.api_group}/cluster-api-machine-type" - ] + return self.instance.metadata.labels[f"{self.api_group}/cluster-api-machine-type"] @property def machineset_name(self): diff --git a/ocp_resources/machine_health_check.py b/ocp_resources/machine_health_check.py index 46af0fb1fe..2b4deb4d0f 100644 --- a/ocp_resources/machine_health_check.py +++ b/ocp_resources/machine_health_check.py @@ -49,9 +49,7 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if self.reboot_strategy: - self.res["metadata"]["annotations"] = { - f"{self.api_group}/remediation-strategy": "external-baremetal" - } + self.res["metadata"]["annotations"] = {f"{self.api_group}/remediation-strategy": "external-baremetal"} self.res.setdefault("spec", {}) self.res["spec"]["nodeStartupTimeout"] = self.node_startup_timeout self.res["spec"]["maxUnhealthy"] = self.max_unhealthy diff --git a/ocp_resources/machine_set.py b/ocp_resources/machine_set.py index ca0e94ee18..da48d8790a 100644 --- a/ocp_resources/machine_set.py +++ b/ocp_resources/machine_set.py @@ -104,26 +104,16 @@ def to_dict(self): "selector": { "matchLabels": { f"{self.api_group}/{_cluster_api_cluster}": self.cluster_name, - f"{self.api_group}/{_cluster_api_machineset}": ( - f"{self.cluster_name}-{self.machine_role}" - ), + f"{self.api_group}/{_cluster_api_machineset}": (f"{self.cluster_name}-{self.machine_role}"), } }, "template": { _metadata: { _labels: { - f"{self.api_group}/{_cluster_api_cluster}": ( - self.cluster_name - ), - f"{self.api_group}/{_cluster_api_machine_role}": ( - self.machine_role - ), - f"{self.api_group}/{_cluster_api_machine_type}": ( - self.machine_type - ), - f"{self.api_group}/{_cluster_api_machineset}": ( - f"{self.cluster_name}-{self.machine_role}" - ), + f"{self.api_group}/{_cluster_api_cluster}": (self.cluster_name), + f"{self.api_group}/{_cluster_api_machine_role}": (self.machine_role), + f"{self.api_group}/{_cluster_api_machine_type}": (self.machine_type), + f"{self.api_group}/{_cluster_api_machineset}": (f"{self.cluster_name}-{self.machine_role}"), } }, _spec: {"providerSpec": self.provider_spec}, @@ -172,9 +162,7 @@ def wait_for_replicas(self, timeout=TIMEOUT_5MINUTES, sleep=1): ) return False - def scale_replicas( - self, replicas, wait_timeout=TIMEOUT_5MINUTES, sleep=1, wait=True - ): + def scale_replicas(self, replicas, wait_timeout=TIMEOUT_5MINUTES, sleep=1, wait=True): """ Scale down/up a machine-set replicas. @@ -190,10 +178,7 @@ def scale_replicas( super().to_dict() self.res.update({"spec": {"replicas": replicas}}) - self.logger.info( - f"Scale machine-set from {self.desired_replicas} replicas to" - f" {replicas} replicas" - ) + self.logger.info(f"Scale machine-set from {self.desired_replicas} replicas to" f" {replicas} replicas") self.update(resource_dict=self.res) if wait: return self.wait_for_replicas(timeout=wait_timeout, sleep=sleep) diff --git a/ocp_resources/migration.py b/ocp_resources/migration.py index 1ea9194f00..70c4a3d3a1 100644 --- a/ocp_resources/migration.py +++ b/ocp_resources/migration.py @@ -46,18 +46,14 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "plan": { - "name": self.plan_name, - "namespace": self.plan_namespace, - } + self.res.update({ + "spec": { + "plan": { + "name": self.plan_name, + "namespace": self.plan_namespace, } } - ) + }) if self.cut_over: - self.res["spec"]["cutover"] = self.cut_over.strftime( - format="%Y-%m-%dT%H:%M:%SZ" - ) + self.res["spec"]["cutover"] = self.cut_over.strftime(format="%Y-%m-%dT%H:%M:%SZ") diff --git a/ocp_resources/migration_policy.py b/ocp_resources/migration_policy.py index 75b3e51ac9..92333ef489 100644 --- a/ocp_resources/migration_policy.py +++ b/ocp_resources/migration_policy.py @@ -51,14 +51,10 @@ def to_dict(self): if self.bandwidth_per_migration: self.res["spec"]["bandwidthPerMigration"] = self.bandwidth_per_migration if self.completion_timeout_per_gb: - self.res["spec"][ - "completionTimeoutPerGiB" - ] = self.completion_timeout_per_gb + self.res["spec"]["completionTimeoutPerGiB"] = self.completion_timeout_per_gb if self.namespace_selector: selectors.setdefault("namespaceSelector", self.namespace_selector) if self.vmi_selector: - selectors.setdefault( - "virtualMachineInstanceSelector", self.vmi_selector - ) + selectors.setdefault("virtualMachineInstanceSelector", self.vmi_selector) diff --git a/ocp_resources/mtv.py b/ocp_resources/mtv.py index 9932ac6279..c2ee70e3a8 100644 --- a/ocp_resources/mtv.py +++ b/ocp_resources/mtv.py @@ -4,11 +4,7 @@ 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 "" - ) + log_msg += f"{status_condition_name}->{status_condition} \n" if status_condition else "" return log_msg @@ -104,39 +100,19 @@ def wait_for_resource_status( try: for sample in samples: current_conditions = ( - sample.items[0].status.get("conditions") - if sample.items and sample.items[0].status - else [] + 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] - ): + 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:" - f" {last_condition}" - ) - ) + self.logger.error(msg=(f"Last Status Condition of {self.kind} {self.name} was:" f" {last_condition}")) raise def wait_for_condition_ready(self, wait_timeout=360): diff --git a/ocp_resources/network_attachment_definition.py b/ocp_resources/network_attachment_definition.py index edf970881a..80b0e73c6b 100644 --- a/ocp_resources/network_attachment_definition.py +++ b/ocp_resources/network_attachment_definition.py @@ -52,9 +52,7 @@ def to_dict(self): if not self.yaml_file: if self.resource_name is not None: self.res["metadata"]["annotations"] = { - f"{NamespacedResource.ApiGroup.K8S_V1_CNI_CNCF_IO}/resourceName": ( - self.resource_name - ) + f"{NamespacedResource.ApiGroup.K8S_V1_CNI_CNCF_IO}/resourceName": (self.resource_name) } self.res["spec"] = {} if self.config: @@ -154,9 +152,7 @@ def to_dict(self): super().to_dict() if self.tuning_type: self.old_nad_format = True - self.res["spec"]["config"].setdefault("plugins", []).append( - {"type": self.tuning_type} - ) + self.res["spec"]["config"].setdefault("plugins", []).append({"type": self.tuning_type}) self.res["spec"]["config"] = json.dumps(self.res["spec"]["config"]) diff --git a/ocp_resources/node.py b/ocp_resources/node.py index 511c44dd31..3719849e82 100644 --- a/ocp_resources/node.py +++ b/ocp_resources/node.py @@ -14,16 +14,13 @@ class Status(Resource.Status): @property def kubelet_ready(self): return any( - stat["reason"] == "KubeletReady" - and stat["status"] == self.Condition.Status.TRUE + stat["reason"] == "KubeletReady" and stat["status"] == self.Condition.Status.TRUE for stat in self.instance.status.conditions ) @property def machine_name(self): - return self.instance.metadata.annotations[ - f"{self.ApiGroup.MACHINE_OPENSHIFT_IO}/machine" - ].split("/")[-1] + return self.instance.metadata.annotations[f"{self.ApiGroup.MACHINE_OPENSHIFT_IO}/machine"].split("/")[-1] @property def internal_ip(self): diff --git a/ocp_resources/node_network_configuration_policy.py b/ocp_resources/node_network_configuration_policy.py index 7b0e08fd68..958890df12 100644 --- a/ocp_resources/node_network_configuration_policy.py +++ b/ocp_resources/node_network_configuration_policy.py @@ -114,29 +114,20 @@ def _nodes(self): if self.node_selector: return list(Node.get(dyn_client=self.client, name=self.node_selector)) if self.node_selector_labels: - node_labels = ",".join( - [ - f"{label_key}={label_value}" - for label_key, label_value in self.node_selector_labels.items() - ] - ) + node_labels = ",".join([ + f"{label_key}={label_value}" for label_key, label_value in self.node_selector_labels.items() + ]) return list(Node.get(dyn_client=self.client, label_selector=node_labels)) def set_interface(self, interface): if not self.res: super().to_dict() # First drop the interface if it's already in the list - interfaces = [ - iface - for iface in self.desired_state["interfaces"] - if iface["name"] != interface["name"] - ] + interfaces = [iface for iface in self.desired_state["interfaces"] if iface["name"] != interface["name"]] # Add the interface interfaces.append(interface) self.desired_state["interfaces"] = interfaces - self.res.setdefault("spec", {}).setdefault("desiredState", {})["interfaces"] = ( - self.desired_state["interfaces"] - ) + self.res.setdefault("spec", {}).setdefault("desiredState", {})["interfaces"] = self.desired_state["interfaces"] def to_dict(self): super().to_dict() @@ -145,9 +136,7 @@ def to_dict(self): self.res.setdefault("spec", {}).setdefault("desiredState", {}) if self.node_selector_spec: - self.res.setdefault("spec", {}).setdefault( - "nodeSelector", self.node_selector_spec - ) + self.res.setdefault("spec", {}).setdefault("nodeSelector", self.node_selector_spec) if self.capture: self.res["spec"]["capture"] = self.capture @@ -159,9 +148,7 @@ def to_dict(self): self.res["spec"]["desiredState"]["routes"] = self.routes if self.max_unavailable: - self.res.setdefault("spec", {}).setdefault( - "maxUnavailable", self.max_unavailable - ) + self.res.setdefault("spec", {}).setdefault("maxUnavailable", self.max_unavailable) if self.iface: """ @@ -262,9 +249,7 @@ def _ports_backup(self, ip_family): elif ip_family == IPV6_STR: self.ipv6_ports_backup_dict[port] = _port[ip_family] else: - raise ValueError( - f"'ip_family' must be either '{IPV4_STR}' or '{IPV6_STR}'" - ) + raise ValueError(f"'ip_family' must be either '{IPV4_STR}' or '{IPV6_STR}'") def ipv4_ports_backup(self): self._ports_backup(ip_family=IPV4_STR) @@ -339,13 +324,7 @@ def _absent_interface(self): self.add_ports() ResourceEditor( - patches={ - self: { - "spec": { - "desiredState": {"interfaces": self.desired_state["interfaces"]} - } - } - } + patches={self: {"spec": {"desiredState": {"interfaces": self.desired_state["interfaces"]}}}} ).update() @property @@ -375,8 +354,7 @@ def wait_for_configuration_conditions_unknown_or_progressing(self, wait_timeout= and sample[0]["type"] == self.Conditions.Type.AVAILABLE and ( sample[0]["status"] == self.Condition.Status.UNKNOWN - or sample[0]["reason"] - == self.Conditions.Reason.CONFIGURATION_PROGRESSING + or sample[0]["reason"] == self.Conditions.Reason.CONFIGURATION_PROGRESSING ) ): return sample @@ -387,15 +365,11 @@ def _process_failed_status(self, failed_condition_reason): nnce_name = failed_nnce.instance.metadata.name nnce_dict = failed_nnce.instance.to_dict() for cond in nnce_dict["status"]["conditions"]: - err_msg = self._get_nnce_error_msg( - nnce_name=nnce_name, nnce_condition=cond - ) + err_msg = self._get_nnce_error_msg(nnce_name=nnce_name, nnce_condition=cond) if err_msg: last_err_msg = err_msg - raise NNCPConfigurationFailed( - f"Reason: {failed_condition_reason}\n{last_err_msg}" - ) + raise NNCPConfigurationFailed(f"Reason: {failed_condition_reason}\n{last_err_msg}") def wait_for_status_success(self): failed_condition_reason = self.Conditions.Reason.FAILED_TO_CONFIGURE @@ -404,9 +378,7 @@ def wait_for_status_success(self): # if we get here too fast there are no conditions, we need to wait. self.wait_for_configuration_conditions_unknown_or_progressing() - samples = TimeoutSampler( - wait_timeout=self.success_timeout, sleep=1, func=lambda: self.status - ) + samples = TimeoutSampler(wait_timeout=self.success_timeout, sleep=1, func=lambda: self.status) try: for sample in samples: if sample == self.Conditions.Reason.SUCCESSFULLY_CONFIGURED: @@ -414,14 +386,10 @@ def wait_for_status_success(self): return sample elif sample == no_match_node_condition_reason: - raise NNCPConfigurationFailed( - f"{self.name}. Reason: {no_match_node_condition_reason}" - ) + raise NNCPConfigurationFailed(f"{self.name}. Reason: {no_match_node_condition_reason}") elif sample == failed_condition_reason: - self._process_failed_status( - failed_condition_reason=failed_condition_reason - ) + self._process_failed_status(failed_condition_reason=failed_condition_reason) except (TimeoutExpiredError, NNCPConfigurationFailed): self.logger.error( @@ -439,9 +407,7 @@ def nnces(self): return nnces def node_nnce(self, node_name): - nnce = [ - nnce for nnce in self.nnces if nnce.labels["nmstate.io/node"] == node_name - ] + nnce = [nnce for nnce in self.nnces if nnce.labels["nmstate.io/node"] == node_name] return nnce[0] if nnce else None @staticmethod @@ -473,8 +439,5 @@ def _get_failed_nnce(self): continue for nnce_cond in nnce.instance.status.conditions: - if ( - nnce_cond.type == "Failing" - and nnce_cond.status == Resource.Condition.Status.TRUE - ): + if nnce_cond.type == "Failing" and nnce_cond.status == Resource.Condition.Status.TRUE: yield nnce diff --git a/ocp_resources/node_network_state.py b/ocp_resources/node_network_state.py index dd48a55f7b..d864bec822 100644 --- a/ocp_resources/node_network_state.py +++ b/ocp_resources/node_network_state.py @@ -34,11 +34,7 @@ def __init__( def set_interface(self, interface): # First drop the interface is's already in the list - interfaces = [ - iface - for iface in self.desired_state["interfaces"] - if iface["name"] != interface["name"] - ] + interfaces = [iface for iface in self.desired_state["interfaces"] if iface["name"] != interface["name"]] # Add the interface interfaces.append(interface) @@ -47,15 +43,13 @@ def set_interface(self, interface): def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "nodeName": self.name, - "managed": True, - "desiredState": self.desired_state, - } + self.res.update({ + "spec": { + "nodeName": self.name, + "managed": True, + "desiredState": self.desired_state, } - ) + }) def apply(self): retries_on_conflict = 3 @@ -79,9 +73,7 @@ def _find_up_interface(): return None self.logger.info(f"Checking if interface {name} is up -- {self.name}") - samples = TimeoutSampler( - wait_timeout=TIMEOUT_4MINUTES, sleep=SLEEP, func=_find_up_interface - ) + samples = TimeoutSampler(wait_timeout=TIMEOUT_4MINUTES, sleep=SLEEP, func=_find_up_interface) for sample in samples: if sample: return diff --git a/ocp_resources/operator_source.py b/ocp_resources/operator_source.py index 0b48d5035b..1f3db6aeef 100644 --- a/ocp_resources/operator_source.py +++ b/ocp_resources/operator_source.py @@ -36,15 +36,13 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "type": "appregistry", - "endpoint": "https://quay.io/cnr", - "registryNamespace": self.registry_namespace, - "displayName": self.display_name, - "publisher": self.publisher, - "authorizationToken": {"secretName": self.secret}, - } + self.res.update({ + "spec": { + "type": "appregistry", + "endpoint": "https://quay.io/cnr", + "registryNamespace": self.registry_namespace, + "displayName": self.display_name, + "publisher": self.publisher, + "authorizationToken": {"secretName": self.secret}, } - ) + }) diff --git a/ocp_resources/persistent_volume.py b/ocp_resources/persistent_volume.py index 79f090cf8c..a6377cebc7 100644 --- a/ocp_resources/persistent_volume.py +++ b/ocp_resources/persistent_volume.py @@ -18,10 +18,4 @@ def max_available_pvs(self): """ Returns the maximum number (int) of PV's which are in 'Available' state """ - return len( - [ - pv - for pv in self.api.get()["items"] - if pv.status.phase == Resource.Condition.AVAILABLE - ] - ) + return len([pv for pv in self.api.get()["items"] if pv.status.phase == Resource.Condition.AVAILABLE]) diff --git a/ocp_resources/persistent_volume_claim.py b/ocp_resources/persistent_volume_claim.py index a8456b7f55..396609cc98 100644 --- a/ocp_resources/persistent_volume_claim.py +++ b/ocp_resources/persistent_volume_claim.py @@ -66,15 +66,13 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "volumeMode": self.volume_mode, - "accessModes": [self.accessmodes], - "resources": {"requests": {"storage": self.size}}, - } + self.res.update({ + "spec": { + "volumeMode": self.volume_mode, + "accessModes": [self.accessmodes], + "resources": {"requests": {"storage": self.size}}, } - ) + }) """ Hostpath-provisioner is "node aware", when using it, a node attribute on the claim must be introduced as follows. @@ -82,16 +80,12 @@ def to_dict(self): kubevirt.io/provisionOnNode: """ if self.hostpath_node: - self.res["metadata"]["annotations"] = { - "kubevirt.io/provisionOnNode": self.hostpath_node - } + self.res["metadata"]["annotations"] = {"kubevirt.io/provisionOnNode": self.hostpath_node} if self.storage_class: self.res["spec"]["storageClassName"] = self.storage_class if self.pvlabel: - self.res["spec"]["selector"] = { - "matchLabels": {"pvLabel": self.pvlabel} - } + self.res["spec"]["selector"] = {"matchLabels": {"pvLabel": self.pvlabel}} def bound(self): """ @@ -105,6 +99,4 @@ def bound(self): @property def selected_node(self): - return self.instance.metadata.annotations.get( - "volume.kubernetes.io/selected-node" - ) + return self.instance.metadata.annotations.get("volume.kubernetes.io/selected-node") diff --git a/ocp_resources/pipeline.py b/ocp_resources/pipeline.py index b86389b309..bfed2504c1 100644 --- a/ocp_resources/pipeline.py +++ b/ocp_resources/pipeline.py @@ -46,10 +46,7 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if not (self.tasks or self.params or self.final_parallel_tasks): - raise ValueError( - "spec is expected to have at least one of the optional fields, got" - " none" - ) + raise ValueError("spec is expected to have at least one of the optional fields, got" " none") self.res["spec"] = {} if self.params: self.res["spec"]["params"] = self.params diff --git a/ocp_resources/pipelineruns.py b/ocp_resources/pipelineruns.py index b8f597947d..1f03b5f71e 100644 --- a/ocp_resources/pipelineruns.py +++ b/ocp_resources/pipelineruns.py @@ -48,8 +48,7 @@ def to_dict(self): if self.params: self.res["spec"]["params"] = [ - {"name": params_name, "value": params_value} - for params_name, params_value in self.params.items() + {"name": params_name, "value": params_value} for params_name, params_value in self.params.items() ] if self.service_account_name: diff --git a/ocp_resources/plan.py b/ocp_resources/plan.py index b2441d0914..65dc847906 100644 --- a/ocp_resources/plan.py +++ b/ocp_resources/plan.py @@ -112,32 +112,30 @@ def generate_hook_spec(hook_name, hook_namespace, hook_type): def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "warm": self.warm_migration, - "targetNamespace": self.target_namespace, - "map": { - "storage": { - "name": self.storage_map_name, - "namespace": self.storage_map_namespace, - }, - "network": { - "name": self.network_map_name, - "namespace": self.network_map_namespace, - }, + self.res.update({ + "spec": { + "warm": self.warm_migration, + "targetNamespace": self.target_namespace, + "map": { + "storage": { + "name": self.storage_map_name, + "namespace": self.storage_map_namespace, }, - "vms": self.virtual_machines_list, - "provider": { - "source": { - "name": self.source_provider_name, - "namespace": self.source_provider_namespace, - }, - "destination": { - "name": self.destination_provider_name, - "namespace": self.destination_provider_namespace, - }, + "network": { + "name": self.network_map_name, + "namespace": self.network_map_namespace, }, - } + }, + "vms": self.virtual_machines_list, + "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/pod.py b/ocp_resources/pod.py index 6fc3c58bfa..5c7e89e5da 100644 --- a/ocp_resources/pod.py +++ b/ocp_resources/pod.py @@ -16,13 +16,7 @@ def __init__(self, command, rc, out, err): self.err = err def __str__(self): - return ( - "Command execution failure: " - f"{self.cmd}, " - f"RC: {self.rc}, " - f"OUT: {self.out}, " - f"ERR: {self.err}" - ) + return "Command execution failure: " f"{self.cmd}, " f"RC: {self.rc}, " f"OUT: {self.out}, " f"ERR: {self.err}" class Pod(NamespacedResource): @@ -105,23 +99,17 @@ def execute(self, command, timeout=60, container=None, ignore_rc=False): while resp.is_open(): resp.run_forever(timeout=2) try: - error_channel = json.loads( - resp.read_channel(kubernetes.stream.ws_client.ERROR_CHANNEL) - ) + error_channel = json.loads(resp.read_channel(kubernetes.stream.ws_client.ERROR_CHANNEL)) break except json.decoder.JSONDecodeError: # Check remaining time, in order to throw exception # if remaining time reached zero if timeout_watch.remaining_time() <= 0: - raise ExecOnPodError( - command=command, rc=-1, out="", err=stream_closed_error - ) + raise ExecOnPodError(command=command, rc=-1, out="", err=stream_closed_error) rcstring = error_channel.get("status") if rcstring is None: - raise ExecOnPodError( - command=command, rc=-1, out="", err=stream_closed_error - ) + raise ExecOnPodError(command=command, rc=-1, out="", err=stream_closed_error) stdout = resp.read_stdout(timeout=5) stderr = resp.read_stderr(timeout=5) @@ -133,9 +121,7 @@ def execute(self, command, timeout=60, container=None, ignore_rc=False): raise ExecOnPodError(command=command, rc=-1, out="", err=error_channel) returncode = [ - int(cause["message"]) - for cause in error_channel["details"]["causes"] - if cause["reason"] == "ExitCode" + int(cause["message"]) for cause in error_channel["details"]["causes"] if cause["reason"] == "ExitCode" ][0] raise ExecOnPodError(command=command, rc=returncode, out=stdout, err=stderr) @@ -147,9 +133,7 @@ def log(self, **kwargs): Returns: str: Pod logs. """ - return self._kube_v1_api.read_namespaced_pod_log( - name=self.name, namespace=self.namespace, **kwargs - ) + return self._kube_v1_api.read_namespaced_pod_log(name=self.name, namespace=self.namespace, **kwargs) @property def node(self): diff --git a/ocp_resources/provider.py b/ocp_resources/provider.py index 2e937dec72..93676db73f 100644 --- a/ocp_resources/provider.py +++ b/ocp_resources/provider.py @@ -44,16 +44,14 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "type": self.provider_type, - "url": self.url, - "secret": { - "name": self.secret_name, - "namespace": self.secret_namespace, - }, - "settings": {"vddkInitImage": self.vddk_init_image}, - } + self.res.update({ + "spec": { + "type": self.provider_type, + "url": self.url, + "secret": { + "name": self.secret_name, + "namespace": self.secret_namespace, + }, + "settings": {"vddkInitImage": self.vddk_init_image}, } - ) + }) diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index 782cb0ef0a..1b860556da 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -41,21 +41,15 @@ def _find_supported_resource(dyn_client, api_group, kind): results = dyn_client.resources.search(group=api_group, kind=kind) - sorted_results = sorted( - results, key=lambda result: KubeAPIVersion(result.api_version), reverse=True - ) + sorted_results = sorted(results, key=lambda result: KubeAPIVersion(result.api_version), reverse=True) for result in sorted_results: - if KubeAPIVersion(result.api_version) <= KubeAPIVersion( - MAX_SUPPORTED_API_VERSION - ): + if KubeAPIVersion(result.api_version) <= KubeAPIVersion(MAX_SUPPORTED_API_VERSION): return result def _get_api_version(dyn_client, api_group, kind): # Returns api_group/api_version - res = _find_supported_resource( - dyn_client=dyn_client, api_group=api_group, kind=kind - ) + res = _find_supported_resource(dyn_client=dyn_client, api_group=api_group, kind=kind) if not res: log = f"Couldn't find {kind} in {api_group} api group" LOGGER.warning(log) @@ -99,14 +93,11 @@ def get_client(config_file=None, config_dict=None, context=None): def sub_resource_level(current_class, owner_class, parent_class): # 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( - [ - class_iterator - for class_iterator in current_class.mro() - if class_iterator not in owner_class.mro() - and issubclass(class_iterator, parent_class) - ] - ): + for class_iterator in reversed([ + class_iterator + for class_iterator in current_class.mro() + if class_iterator not in owner_class.mro() and issubclass(class_iterator, parent_class) + ]): return class_iterator.__name__ @@ -129,20 +120,11 @@ def parse(self, vstring): with contextlib.suppress(ValueError): components[idx] = int(obj) - errmsg = ( - f"version '{vstring}' does not conform to kubernetes api versioning" - " guidelines" - ) + errmsg = f"version '{vstring}' does not conform to kubernetes api versioning" " guidelines" - if ( - len(components) not in (2, 4) - or components[0] != "v" - or not isinstance(components[1], int) - ): + 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) - ): + if len(components) == 4 and (components[2] not in ("alpha", "beta") or not isinstance(components[3], int)): raise ValueError(errmsg) self.version = components @@ -273,9 +255,7 @@ class ApiGroup: METRICS_K8S_IO = "metrics.k8s.io" MIGRATIONS_KUBEVIRT_IO = "migrations.kubevirt.io" MONITORING_COREOS_COM = "monitoring.coreos.com" - NETWORKADDONSOPERATOR_NETWORK_KUBEVIRT_IO = ( - "networkaddonsoperator.network.kubevirt.io" - ) + NETWORKADDONSOPERATOR_NETWORK_KUBEVIRT_IO = "networkaddonsoperator.network.kubevirt.io" NETWORKING_ISTIO_IO = "networking.istio.io" NETWORKING_K8S_IO = "networking.k8s.io" NODE_LABELLER_KUBEVIRT_IO = "node-labeller.kubevirt.io" @@ -361,8 +341,7 @@ def __init__( self.api_group = api_group or self.api_group if not self.api_group and not self.api_version: raise NotImplementedError( - "Subclasses of Resource require self.api_group or self.api_version to" - " be defined" + "Subclasses of Resource require self.api_group or self.api_version to" " be defined" ) self.namespace = None self.name = name @@ -436,9 +415,7 @@ def _base_body(self): "metadata": {"name": self.name}, } if self.label: - self.res.setdefault("metadata", {}).setdefault("labels", {}).update( - self.label - ) + self.res.setdefault("metadata", {}).setdefault("labels", {}).update(self.label) def to_dict(self): """ @@ -519,8 +496,7 @@ def clean_up(self): check_exists=False, ): self.logger.warning( - f"Skip resource {self.kind} {self.name} teardown. Got" - f" {_export_str}={skip_resource_teardown}" + f"Skip resource {self.kind} {self.name} teardown. Got" f" {_export_str}={skip_resource_teardown}" ) return @@ -529,9 +505,7 @@ def clean_up(self): @classmethod def _prepare_resources(cls, dyn_client, singular_name, *args, **kwargs): if not cls.api_version: - cls.api_version = _get_api_version( - dyn_client=dyn_client, api_group=cls.api_group, kind=cls.kind - ) + cls.api_version = _get_api_version(dyn_client=dyn_client, api_group=cls.api_group, kind=cls.kind) get_kwargs = {"singular_name": singular_name} if singular_name else {} return dyn_client.resources.get( @@ -552,9 +526,7 @@ def _set_client_and_api_version(self): self.client = get_client(config_file=self.config_file, context=self.context) if not self.api_version: - self.api_version = _get_api_version( - dyn_client=self.client, api_group=self.api_group, kind=self.kind - ) + self.api_version = _get_api_version(dyn_client=self.client, api_group=self.api_group, kind=self.kind) def full_api(self, **kwargs): """ @@ -579,9 +551,7 @@ def full_api(self, **kwargs): kwargs = self._prepare_singular_name_kwargs(**kwargs) - return self.client.resources.get( - api_version=self.api_version, kind=self.kind, **kwargs - ) + return self.client.resources.get(api_version=self.api_version, kind=self.kind, **kwargs) @property def api(self): @@ -646,16 +616,12 @@ def client_wait_deleted(self, timeout): Raises: TimeoutExpiredError: If resource still exists. """ - samples = TimeoutSampler( - wait_timeout=timeout, sleep=1, func=lambda: self.exists - ) + samples = TimeoutSampler(wait_timeout=timeout, sleep=1, func=lambda: self.exists) for sample in samples: if not sample: return - def wait_for_status( - self, status, timeout=TIMEOUT_4MINUTES, stop_status=None, sleep=1 - ): + def wait_for_status(self, status, timeout=TIMEOUT_4MINUTES, stop_status=None, sleep=1): """ Wait for resource to be in status @@ -690,23 +656,17 @@ def wait_for_status( current_status = sample_status.phase if current_status != last_logged_status: last_logged_status = current_status - self.logger.info( - f"Status of {self.kind} {self.name} is {current_status}" - ) + self.logger.info(f"Status of {self.kind} {self.name} is {current_status}") if current_status == status: return if current_status == stop_status: - raise TimeoutExpiredError( - f"Status of {self.kind} {self.name} is {current_status}" - ) + raise TimeoutExpiredError(f"Status of {self.kind} {self.name} is {current_status}") except TimeoutExpiredError: if current_status: - self.logger.error( - f"Status of {self.kind} {self.name} is {current_status}" - ) + self.logger.error(f"Status of {self.kind} {self.name} is {current_status}") raise def create(self, wait=False): @@ -729,9 +689,7 @@ def create(self, wait=False): self.logger.info(f"Create {self.kind} {self.name}") self.logger.info(f"Posting {hashed_res}") self.logger.debug(f"\n{yaml.dump(hashed_res)}") - resource_ = self.api.create( - body=self.res, namespace=self.namespace, dry_run=self.dry_run - ) + resource_ = self.api.create(body=self.res, namespace=self.namespace, dry_run=self.dry_run) with contextlib.suppress(TimeoutExpiredError): # some resources do not support get() (no instance) or the client do not have permissions self.initial_resource_version = self.instance.metadata.resourceVersion @@ -797,9 +755,7 @@ def update_replace(self, resource_dict): self.api.replace(body=resource_dict, name=self.name, namespace=self.namespace) @staticmethod - def retry_cluster_exceptions( - func, exceptions_dict=DEFAULT_CLUSTER_RETRY_EXCEPTIONS, **kwargs - ): + def retry_cluster_exceptions(func, exceptions_dict=DEFAULT_CLUSTER_RETRY_EXCEPTIONS, **kwargs): sampler = TimeoutSampler( wait_timeout=10, sleep=1, @@ -839,18 +795,14 @@ def get( dyn_client = get_client(config_file=config_file, context=context) def _get(): - _resources = cls._prepare_resources( - dyn_client=dyn_client, singular_name=singular_name, *args, **kwargs - ) + _resources = cls._prepare_resources(dyn_client=dyn_client, singular_name=singular_name, *args, **kwargs) try: for resource_field in _resources.items: yield cls(client=dyn_client, name=resource_field.metadata.name) except TypeError: yield cls(client=dyn_client, name=_resources.metadata.name) - return Resource.retry_cluster_exceptions( - func=_get, exceptions_dict=exceptions_dict - ) + return Resource.retry_cluster_exceptions(func=_get, exceptions_dict=exceptions_dict) @property def instance(self): @@ -910,10 +862,7 @@ def wait_for_condition(self, condition, status, timeout=300): Raises: TimeoutExpiredError: If Resource condition in not in desire status. """ - self.logger.info( - f"Wait for {self.kind}/{self.name}'s '{condition}' condition to be" - f" '{status}'" - ) + self.logger.info(f"Wait for {self.kind}/{self.name}'s '{condition}' condition to be" f" '{status}'") timeout_watcher = TimeoutWatch(timeout=timeout) for sample in TimeoutSampler( @@ -1025,9 +974,7 @@ def events( ) @staticmethod - def get_all_cluster_resources( - config_file=None, config_dict=None, context=None, *args, **kwargs - ): + def get_all_cluster_resources(config_file=None, config_dict=None, context=None, *args, **kwargs): """ Get all cluster resources @@ -1046,9 +993,7 @@ def get_all_cluster_resources( print(f"Resource: {resource}") """ - client = get_client( - config_file=config_file, config_dict=config_dict, context=context - ) + client = get_client(config_file=config_file, config_dict=config_dict, context=context) for _resource in client.resources.search(): try: _resources = client.get(_resource, *args, **kwargs) @@ -1156,9 +1101,7 @@ def get( if not dyn_client: dyn_client = get_client(config_file=config_file, context=context) - _resources = cls._prepare_resources( - dyn_client=dyn_client, singular_name=singular_name, *args, **kwargs - ) + _resources = cls._prepare_resources(dyn_client=dyn_client, singular_name=singular_name, *args, **kwargs) try: for resource_field in _resources.items: if raw: @@ -1278,9 +1221,7 @@ def update(self, backup_resources=False): )[0].to_dict() namespace = update.get("metadata", {}).get("namespace") - backup = self._create_backup( - original=original_resource_dict, patch=update - ) + backup = self._create_backup(original=original_resource_dict, patch=update) if namespace: # Add namespace to metadata for restore. backup["metadata"]["namespace"] = namespace @@ -1291,28 +1232,19 @@ def update(self, backup_resources=False): resource_to_patch.append(resource) self._backups[resource] = backup else: - LOGGER.warning( - "ResourceEdit: no diff found in patch for " - f"{resource.name} -- skipping" - ) + LOGGER.warning("ResourceEdit: no diff found in patch for " f"{resource.name} -- skipping") if not resource_to_patch: return else: resource_to_patch = self._patches - patches_to_apply = { - resource: self._patches[resource] for resource in resource_to_patch - } + patches_to_apply = {resource: self._patches[resource] for resource in resource_to_patch} # apply changes - self._apply_patches_sampler( - patches=patches_to_apply, action_text="Updating", action=self.action - ) + self._apply_patches_sampler(patches=patches_to_apply, action_text="Updating", action=self.action) def restore(self): - self._apply_patches_sampler( - patches=self._backups, action_text="Restoring", action=self.action - ) + self._apply_patches_sampler(patches=self._backups, action_text="Restoring", action=self.action) def __enter__(self): self.update(backup_resources=True) @@ -1329,9 +1261,7 @@ def _dictify_resourcefield(res): return ResourceEditor._dictify_resourcefield(res=dict(res.items())) elif isinstance(res, dict): return { - ResourceEditor._dictify_resourcefield( - res=key - ): ResourceEditor._dictify_resourcefield(res=value) + ResourceEditor._dictify_resourcefield(res=key): ResourceEditor._dictify_resourcefield(res=value) for key, value in res.items() } elif isinstance(res, list): @@ -1366,9 +1296,7 @@ def _create_backup(original, patch): continue # recursive call - key_diff = ResourceEditor._create_backup( - original=original[key], patch=value - ) + key_diff = ResourceEditor._create_backup(original=original[key], patch=value) if key_diff is not None: diff_dict[key] = key_diff @@ -1395,10 +1323,7 @@ def _apply_patches(patches, action_text, action): """ for resource, patch in patches.items(): - LOGGER.info( - f"ResourceEdits: {action_text} data for " - f"resource {resource.kind} {resource.name}" - ) + LOGGER.info(f"ResourceEdits: {action_text} data for " f"resource {resource.kind} {resource.name}") # add name to patch if "metadata" not in patch: @@ -1418,15 +1343,11 @@ def _apply_patches(patches, action_text, action): patch["metadata"]["name"] = resource.name patch["metadata"]["namespace"] = resource.namespace - patch["metadata"][ - "resourceVersion" - ] = resource.instance.metadata.resourceVersion + patch["metadata"]["resourceVersion"] = resource.instance.metadata.resourceVersion patch["kind"] = resource.kind patch["apiVersion"] = resource.api_version - resource.update_replace( - resource_dict=patch - ) # replace the resource metadata + resource.update_replace(resource_dict=patch) # replace the resource metadata def _apply_patches_sampler(self, patches, action_text, action): exceptions_dict = {ConflictError: []} diff --git a/ocp_resources/restore.py b/ocp_resources/restore.py index ca15e3efc1..788995d761 100644 --- a/ocp_resources/restore.py +++ b/ocp_resources/restore.py @@ -41,12 +41,10 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "backupName": self.backup_name, - } + self.res.update({ + "spec": { + "backupName": self.backup_name, } - ) + }) if self.included_namespaces: self.res["spec"]["includedNamespaces"] = self.included_namespaces diff --git a/ocp_resources/route.py b/ocp_resources/route.py index 771b7466dc..28671b6245 100644 --- a/ocp_resources/route.py +++ b/ocp_resources/route.py @@ -38,9 +38,7 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if self.service: - self.res.update( - {"spec": {"to": {"kind": "Service", "name": self.service}}} - ) + self.res.update({"spec": {"to": {"kind": "Service", "name": self.service}}}) if self.destination_ca_cert: self.res["spec"]["tls"] = { "destinationCACertificate": self.destination_ca_cert, diff --git a/ocp_resources/secret.py b/ocp_resources/secret.py index c7c9c73610..0c47a6cf09 100644 --- a/ocp_resources/secret.py +++ b/ocp_resources/secret.py @@ -45,14 +45,12 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if self.accesskeyid: - self.res.update( - { - "data": { - "accessKeyId": self.accesskeyid, - "secretKey": self.secretkey, - } + self.res.update({ + "data": { + "accessKeyId": self.accesskeyid, + "secretKey": self.secretkey, } - ) + }) if self.htpasswd: self.res.update({"data": {"htpasswd": self.htpasswd}}) if self.data_dict: @@ -64,15 +62,11 @@ def to_dict(self): @property def certificate_not_after(self): - return self.instance.metadata.annotations[ - "auth.openshift.io/certificate-not-after" - ] + return self.instance.metadata.annotations["auth.openshift.io/certificate-not-after"] @property def certificate_not_before(self): - return self.instance.metadata.annotations[ - "auth.openshift.io/certificate-not-before" - ] + return self.instance.metadata.annotations["auth.openshift.io/certificate-not-before"] @property def keys_to_hash(self): diff --git a/ocp_resources/sriov_network_node_policy.py b/ocp_resources/sriov_network_node_policy.py index d08e537dea..2d9f47ad51 100644 --- a/ocp_resources/sriov_network_node_policy.py +++ b/ocp_resources/sriov_network_node_policy.py @@ -62,6 +62,4 @@ def to_dict(self): if self.node_selector: self.res["spec"]["nodeSelector"] = self.node_selector else: - self.res["spec"]["nodeSelector"] = { - "feature.node.kubernetes.io/network-sriov.capable": "true" - } + self.res["spec"]["nodeSelector"] = {"feature.node.kubernetes.io/network-sriov.capable": "true"} diff --git a/ocp_resources/sriov_network_node_state.py b/ocp_resources/sriov_network_node_state.py index d345a0a5f4..d21efa081f 100644 --- a/ocp_resources/sriov_network_node_state.py +++ b/ocp_resources/sriov_network_node_state.py @@ -26,9 +26,7 @@ def totalvfs(iface): return iface.totalvfs def wait_for_status_sync(self, wanted_status, timeout=1000): - self.logger.info( - f"Wait for {self.kind} {self.name} status to be {wanted_status}" - ) + self.logger.info(f"Wait for {self.kind} {self.name} status to be {wanted_status}") try: timeout_watcher = TimeoutWatch(timeout=timeout) for sample in TimeoutSampler( @@ -47,8 +45,5 @@ def wait_for_status_sync(self, wanted_status, timeout=1000): if sample == wanted_status: return except TimeoutExpiredError: - self.logger.error( - f"after {timeout} seconds, {self.name} status is" - f" {self.instance.status.syncStatus}" - ) + self.logger.error(f"after {timeout} seconds, {self.name} status is" f" {self.instance.status.syncStatus}") raise diff --git a/ocp_resources/storage_class.py b/ocp_resources/storage_class.py index 87a66f66a4..0b37e5061a 100644 --- a/ocp_resources/storage_class.py +++ b/ocp_resources/storage_class.py @@ -42,6 +42,4 @@ class VolumeBindingMode: WaitForFirstConsumer = "WaitForFirstConsumer" class Annotations: - IS_DEFAULT_CLASS = ( - f"{Resource.ApiGroup.STORAGECLASS_KUBERNETES_IO}/is-default-class" - ) + IS_DEFAULT_CLASS = f"{Resource.ApiGroup.STORAGECLASS_KUBERNETES_IO}/is-default-class" diff --git a/ocp_resources/subscription.py b/ocp_resources/subscription.py index 0dcee0cd81..b83ea49d0e 100644 --- a/ocp_resources/subscription.py +++ b/ocp_resources/subscription.py @@ -44,25 +44,19 @@ def __init__( def to_dict(self): super().to_dict() if not self.yaml_file: - self.res.update( - { - "spec": { - "sourceNamespace": self.source_namespace, - "source": self.source, - "name": self.package_name or self.name, - "channel": self.channel, - "installPlanApproval": self.install_plan_approval, - "startingCSV": self.starting_csv, - } + self.res.update({ + "spec": { + "sourceNamespace": self.source_namespace, + "source": self.source, + "name": self.package_name or self.name, + "channel": self.channel, + "installPlanApproval": self.install_plan_approval, + "startingCSV": self.starting_csv, } - ) + }) if self.node_selector: - self.res["spec"].setdefault("config", {}).setdefault( - "nodeSelector", {} - ).update(self.node_selector) + self.res["spec"].setdefault("config", {}).setdefault("nodeSelector", {}).update(self.node_selector) if self.tolerations: - self.res["spec"].setdefault("config", {}).setdefault( - "tolerations", [] - ).append(self.tolerations) + self.res["spec"].setdefault("config", {}).setdefault("tolerations", []).append(self.tolerations) diff --git a/ocp_resources/template.py b/ocp_resources/template.py index 41a9731ce1..92892128da 100644 --- a/ocp_resources/template.py +++ b/ocp_resources/template.py @@ -28,12 +28,8 @@ class Flavor: class Annotations: DEPRECATED = f"{NamespacedResource.ApiGroup.TEMPLATE_KUBEVIRT_IO}/deprecated" PROVIDER = f"{NamespacedResource.ApiGroup.TEMPLATE_KUBEVIRT_IO}/provider" - PROVIDER_SUPPORT_LEVEL = ( - f"{NamespacedResource.ApiGroup.TEMPLATE_KUBEVIRT_IO}/provider-support-level" - ) - PROVIDER_URL = ( - f"{NamespacedResource.ApiGroup.TEMPLATE_KUBEVIRT_IO}/provider-url" - ) + PROVIDER_SUPPORT_LEVEL = f"{NamespacedResource.ApiGroup.TEMPLATE_KUBEVIRT_IO}/provider-support-level" + PROVIDER_URL = f"{NamespacedResource.ApiGroup.TEMPLATE_KUBEVIRT_IO}/provider-url" class VMAnnotations: OS = f"{Resource.ApiGroup.VM_KUBEVIRT_IO}/os" @@ -53,9 +49,7 @@ def process(self, client=None, **kwargs): instance_dict["parameters"] = params # namespace label - If not defined, the template is expected to belong to the same namespace as the VM. instance_namespace = instance_dict["metadata"]["namespace"] - instance_dict["objects"][0]["metadata"]["labels"][ - "vm.kubevirt.io/template.namespace" - ] = instance_namespace + instance_dict["objects"][0]["metadata"]["labels"]["vm.kubevirt.io/template.namespace"] = instance_namespace instance_json = json.dumps(instance_dict) body = json.loads(instance_json) @@ -70,8 +64,6 @@ def process(self, client=None, **kwargs): def generate_template_labels(os, workload, flavor): return [ f"{Template.Labels.OS}/{os}", - ( - f"{Template.Labels.WORKLOAD}/{getattr(Template.Workload, workload.upper())}" - ), + (f"{Template.Labels.WORKLOAD}/{getattr(Template.Workload, workload.upper())}"), f"{Template.Labels.FLAVOR}/{getattr(Template.Flavor, flavor.upper())}", ] diff --git a/ocp_resources/utils.py b/ocp_resources/utils.py index 2b757dcf04..6266558dbc 100644 --- a/ocp_resources/utils.py +++ b/ocp_resources/utils.py @@ -149,8 +149,7 @@ def __iter__(self): finally: if self.elapsed_time and self.print_log: LOGGER.info( - "Elapsed time:" - f" {self.elapsed_time} [{datetime.timedelta(seconds=self.elapsed_time)}]" + "Elapsed time:" f" {self.elapsed_time} [{datetime.timedelta(seconds=self.elapsed_time)}]" ) raise TimeoutExpiredError(self._get_exception_log(exp=last_exp)) @@ -186,9 +185,7 @@ def _is_raisable_exception(self, exp): for entry in self.exceptions_dict: if isinstance(exp, entry): # Check inheritance for raised exception exception_messages = self.exceptions_dict.get(entry) - if self._is_exception_matched( - exp=exp, exception_messages=exception_messages - ): + if self._is_exception_matched(exp=exp, exception_messages=exception_messages): return False return True @@ -224,9 +221,7 @@ def remaining_time(self): return self.start_time + self.timeout - time.time() -def skip_existing_resource_creation_teardown( - resource, export_str, user_exported_args, check_exists=True -): +def skip_existing_resource_creation_teardown(resource, export_str, user_exported_args, check_exists=True): """ Args: resource (Resource): Resource to match against. @@ -269,10 +264,7 @@ def _return_resource(_resource, _check_exists, _msg): ) for _name, _namespace in _resource_args.items(): - if resource_name == _name and ( - resource_namespace == _namespace - or not (resource_namespace and _namespace) - ): + if resource_name == _name and (resource_namespace == _namespace or not (resource_namespace and _namespace)): return _return_resource( _resource=resource, _check_exists=check_exists, diff --git a/ocp_resources/virtual_machine.py b/ocp_resources/virtual_machine.py index 0789719de2..960a967423 100644 --- a/ocp_resources/virtual_machine.py +++ b/ocp_resources/virtual_machine.py @@ -68,9 +68,7 @@ def _subresource_api_url(self): ) def api_request(self, method, action, **params): - return super().api_request( - method=method, action=action, url=self._subresource_api_url, **params - ) + return super().api_request(method=method, action=action, url=self._subresource_api_url, **params) def to_dict(self): super().to_dict() @@ -89,9 +87,7 @@ def restart(self, timeout=TIMEOUT_4MINUTES, wait=False): self.vmi.virt_launcher_pod.wait_deleted() return self.vmi.wait_until_running(timeout=timeout, stop_status="dummy") - def stop( - self, timeout=TIMEOUT_4MINUTES, vmi_delete_timeout=TIMEOUT_4MINUTES, wait=False - ): + def stop(self, timeout=TIMEOUT_4MINUTES, vmi_delete_timeout=TIMEOUT_4MINUTES, wait=False): self.api_request(method="PUT", action="stop") if wait: self.wait_for_ready_status(timeout=timeout, status=None) @@ -108,10 +104,7 @@ def wait_for_ready_status(self, status, timeout=TIMEOUT_4MINUTES, sleep=1): Raises: TimeoutExpiredError: If timeout reached. """ - self.logger.info( - f"Wait for {self.kind} {self.name} status to be" - f" {'ready' if status == True else status}" - ) + self.logger.info(f"Wait for {self.kind} {self.name} status to be {'ready' if status else status}") samples = TimeoutSampler( wait_timeout=timeout, sleep=sleep, diff --git a/ocp_resources/virtual_machine_export.py b/ocp_resources/virtual_machine_export.py index 42d782ca22..8891af91b8 100644 --- a/ocp_resources/virtual_machine_export.py +++ b/ocp_resources/virtual_machine_export.py @@ -53,18 +53,14 @@ def to_dict(self): super().to_dict() if not self.yaml_file: if not (self.source_kind and self.source_name): - raise ValueError( - "source_kind and source_name or a yaml_file is required" - ) - self.res.update( - { - "spec": { - "tokenSecretRef": self.token_secret_ref, - "source": { - "apiGroup": self.source_api_group, - "kind": self.source_kind, - "name": self.source_name, - }, - } + raise ValueError("source_kind and source_name or a yaml_file is required") + self.res.update({ + "spec": { + "tokenSecretRef": self.token_secret_ref, + "source": { + "apiGroup": self.source_api_group, + "kind": self.source_kind, + "name": self.source_name, + }, } - ) + }) diff --git a/ocp_resources/virtual_machine_import.py b/ocp_resources/virtual_machine_import.py index 6386c06562..4dc70ad36d 100644 --- a/ocp_resources/virtual_machine_import.py +++ b/ocp_resources/virtual_machine_import.py @@ -125,9 +125,7 @@ def __init__( self.target_vm_name = target_vm_name self.start_vm = start_vm self.provider_credentials_secret_name = provider_credentials_secret_name - self.provider_credentials_secret_namespace = ( - provider_credentials_secret_namespace - ) + self.provider_credentials_secret_namespace = provider_credentials_secret_namespace self.provider_mappings = provider_mappings self.resource_mapping_name = resource_mapping_name self.resource_mapping_namespace = resource_mapping_namespace @@ -156,13 +154,9 @@ def to_dict(self): secret["namespace"] = self.provider_credentials_secret_namespace if self.resource_mapping_name: - spec.setdefault("resourceMapping", {})[ - "name" - ] = self.resource_mapping_name + spec.setdefault("resourceMapping", {})["name"] = self.resource_mapping_name if self.resource_mapping_namespace: - spec.setdefault("resourceMapping", {})[ - "namespace" - ] = self.resource_mapping_namespace + spec.setdefault("resourceMapping", {})["namespace"] = self.resource_mapping_namespace if self.target_vm_name: spec["targetVmName"] = self.target_vm_name @@ -173,13 +167,9 @@ def to_dict(self): if self.warm: spec["warm"] = self.warm if self.finalize_date: - spec["finalizeDate"] = self.finalize_date.strftime( - format="%Y-%m-%dT%H:%M:%SZ" - ) + spec["finalizeDate"] = self.finalize_date.strftime(format="%Y-%m-%dT%H:%M:%SZ") - provider_source = spec.setdefault("source", {}).setdefault( - self.provider_type, {} - ) + provider_source = spec.setdefault("source", {}).setdefault(self.provider_type, {}) vm = provider_source.setdefault("vm", {}) if self.vm_id: vm["id"] = self.vm_id @@ -193,28 +183,16 @@ def to_dict(self): if self.provider_mappings: if self.provider_mappings.disk_mappings: - mappings = _map_mappings( - mappings=self.provider_mappings.disk_mappings - ) - provider_source.setdefault("mappings", {}).setdefault( - "diskMappings", mappings - ) + mappings = _map_mappings(mappings=self.provider_mappings.disk_mappings) + provider_source.setdefault("mappings", {}).setdefault("diskMappings", mappings) if self.provider_mappings.network_mappings: - mappings = _map_mappings( - mappings=self.provider_mappings.network_mappings - ) - provider_source.setdefault("mappings", {}).setdefault( - "networkMappings", mappings - ) + mappings = _map_mappings(mappings=self.provider_mappings.network_mappings) + provider_source.setdefault("mappings", {}).setdefault("networkMappings", mappings) if self.provider_mappings.storage_mappings: - mappings = _map_mappings( - mappings=self.provider_mappings.storage_mappings - ) - provider_source.setdefault("mappings", {}).setdefault( - "storageMappings", mappings - ) + mappings = _map_mappings(mappings=self.provider_mappings.storage_mappings) + provider_source.setdefault("mappings", {}).setdefault("storageMappings", mappings) def wait( self, @@ -223,10 +201,7 @@ def wait( cond_status=Condition.Status.TRUE, cond_type=Condition.SUCCEEDED, ): - self.logger.info( - f"Wait for {self.kind} {self.name} {cond_reason} condition to be" - f" {cond_status}" - ) + self.logger.info(f"Wait for {self.kind} {self.name} {cond_reason} condition to be" f" {cond_status}") samples = TimeoutSampler( wait_timeout=timeout, sleep=1, @@ -244,11 +219,7 @@ def wait( current_conditions = sample_status.conditions for cond in current_conditions: last_condition = cond - if ( - cond.type == cond_type - and cond.status == cond_status - and cond.reason == cond_reason - ): + if cond.type == cond_type and cond.status == cond_status and cond.reason == cond_reason: msg = ( f"Status of {self.kind} {self.name} {cond.type} is " f"{cond.status} ({cond.reason}: {cond.message})" @@ -294,9 +265,7 @@ def to_dict(self): super().to_dict() if not self.yaml_file: for provider, mapping in self.mapping.items(): - res_provider_section = self.res.setdefault("spec", {}).setdefault( - provider, {} - ) + res_provider_section = self.res.setdefault("spec", {}).setdefault(provider, {}) if mapping.network_mappings is not None: res_provider_section.setdefault( "networkMappings", diff --git a/ocp_resources/virtual_machine_instance.py b/ocp_resources/virtual_machine_instance.py index 8fb5453e87..745e222f68 100644 --- a/ocp_resources/virtual_machine_instance.py +++ b/ocp_resources/virtual_machine_instance.py @@ -49,9 +49,7 @@ def _subresource_api_url(self): ) def api_request(self, method, action, **params): - return super().api_request( - method=method, action=action, url=self._subresource_api_url, **params - ) + return super().api_request(method=method, action=action, url=self._subresource_api_url, **params) def pause(self, timeout=TIMEOUT_4MINUTES, wait=False): self.api_request(method="PUT", action="pause") @@ -86,9 +84,7 @@ def virt_launcher_pod(self): else: return pods[0] - raise ResourceNotFoundError( - f"VIRT launcher POD not found for {self.kind}:{self.name}" - ) + raise ResourceNotFoundError(f"VIRT launcher POD not found for {self.kind}:{self.name}") @property def virt_handler_pod(self): @@ -117,17 +113,13 @@ def wait_until_running(self, timeout=TIMEOUT_4MINUTES, logs=True, stop_status=No TimeoutExpiredError: If VMI failed to run. """ try: - self.wait_for_status( - status=self.Status.RUNNING, timeout=timeout, stop_status=stop_status - ) + self.wait_for_status(status=self.Status.RUNNING, timeout=timeout, stop_status=stop_status) except TimeoutExpiredError as sampler_ex: if not logs: raise try: virt_pod = self.virt_launcher_pod - self.logger.error( - f"Status of virt-launcher pod {virt_pod.name}: {virt_pod.status}" - ) + self.logger.error(f"Status of virt-launcher pod {virt_pod.name}: {virt_pod.status}") self.logger.debug(f"{virt_pod.name} *****LOGS*****") self.logger.debug(virt_pod.log(container="compute")) except ResourceNotFoundError as virt_pod_ex: @@ -148,9 +140,7 @@ def wait_for_pause_status(self, pause, timeout=TIMEOUT_4MINUTES): Raises: TimeoutExpiredError: If resource not exists. """ - self.logger.info( - f"Wait until {self.kind} {self.name} is {'Paused' if pause else 'Unpuased'}" - ) + self.logger.info(f"Wait until {self.kind} {self.name} is {'Paused' if pause else 'Unpuased'}") self.wait_for_domstate_pause_status(pause=pause, timeout=timeout) self.wait_for_vmi_condition_pause_status(pause=pause, timeout=timeout) @@ -179,9 +169,7 @@ def wait_for_vmi_condition_pause_status(self, pause, timeout=TIMEOUT_4MINUTES): # 'reason' may not exist yet # or # 'reason' may still exist after unpause if the CR has not been updated before we perform this check - if (pause and not sample.get("reason")) or ( - sample.get("reason") == "PausedByUser" and not pause - ): + if (pause and not sample.get("reason")) or (sample.get("reason") == "PausedByUser" and not pause): continue # Paused VM if pause and sample["reason"] == "PausedByUser": @@ -205,8 +193,7 @@ def node(self): def virsh_cmd(self, action): return shlex.split( - "virsh" - f" {self.virt_launcher_pod_hypervisor_connection_uri} {action} {self.namespace}_{self.name}" + "virsh" f" {self.virt_launcher_pod_hypervisor_connection_uri} {action} {self.namespace}_{self.name}" ) def get_xml(self): @@ -256,14 +243,10 @@ def virt_launcher_pod_hypervisor_connection_uri(self): socket = ( virtqemud_socket if virtqemud_socket - in self.virt_launcher_pod.execute( - command=["ls", "/var/run/libvirt/"], container="compute" - ) + in self.virt_launcher_pod.execute(command=["ls", "/var/run/libvirt/"], container="compute") else "libvirt" ) - hypervisor_connection_uri = ( - f"-c qemu+unix:///session?socket=/var/run/libvirt/{socket}-sock" - ) + hypervisor_connection_uri = f"-c qemu+unix:///session?socket=/var/run/libvirt/{socket}-sock" return hypervisor_connection_uri def get_domstate(self): @@ -320,17 +303,11 @@ def guest_user_info(self): def os_version(self): vmi_os_version = self.instance.status.guestOSInfo.get("version", {}) if not vmi_os_version: - self.logger.warning( - "Guest agent is not installed on the VM; OS version is not available." - ) + self.logger.warning("Guest agent is not installed on the VM; OS version is not available.") return vmi_os_version def interface_ip(self, interface): - iface_ip = [ - iface["ipAddress"] - for iface in self.interfaces - if iface["interfaceName"] == interface - ] + iface_ip = [iface["ipAddress"] for iface in self.interfaces if iface["interfaceName"] == interface] return iface_ip[0] if iface_ip else None def execute_virsh_command(self, command): diff --git a/ocp_resources/virtual_machine_restore.py b/ocp_resources/virtual_machine_restore.py index fe513fc249..4bfce094e6 100644 --- a/ocp_resources/virtual_machine_restore.py +++ b/ocp_resources/virtual_machine_restore.py @@ -43,9 +43,7 @@ def to_dict(self): super().to_dict() if not self.yaml_file: spec = self.res.setdefault("spec", {}) - spec.setdefault("target", {})[ - "apiGroup" - ] = NamespacedResource.ApiGroup.KUBEVIRT_IO + spec.setdefault("target", {})["apiGroup"] = NamespacedResource.ApiGroup.KUBEVIRT_IO spec["target"]["kind"] = VirtualMachine.kind spec["target"]["name"] = self.vm_name spec["virtualMachineSnapshotName"] = self.snapshot_name @@ -61,9 +59,7 @@ def wait_complete(self, status=True, timeout=TIMEOUT_4MINUTES): Raises: TimeoutExpiredError: If timeout reached. """ - self.logger.info( - f"Wait for {self.kind} {self.name} status to be complete = {status}" - ) + self.logger.info(f"Wait for {self.kind} {self.name} status to be complete = {status}") timeout_watcher = TimeoutWatch(timeout=timeout) for sample in TimeoutSampler( diff --git a/ocp_resources/virtual_machine_snapshot.py b/ocp_resources/virtual_machine_snapshot.py index 1cb5f18442..b245d9e4c9 100644 --- a/ocp_resources/virtual_machine_snapshot.py +++ b/ocp_resources/virtual_machine_snapshot.py @@ -41,9 +41,7 @@ def to_dict(self): super().to_dict() if not self.yaml_file: spec = self.res.setdefault("spec", {}) - spec.setdefault("source", {})[ - "apiGroup" - ] = NamespacedResource.ApiGroup.KUBEVIRT_IO + spec.setdefault("source", {})["apiGroup"] = NamespacedResource.ApiGroup.KUBEVIRT_IO spec["source"]["kind"] = VirtualMachine.kind spec["source"]["name"] = self.vm_name @@ -58,10 +56,7 @@ def wait_ready_to_use(self, status=True, timeout=TIMEOUT_4MINUTES): Raises: TimeoutExpiredError: If timeout reached. """ - self.logger.info( - f"Wait for {self.kind} {self.name} status to be" - f" {'' if status else 'not '}ready to use" - ) + self.logger.info(f"Wait for {self.kind} {self.name} status to be" f" {'' if status else 'not '}ready to use") timeout_watcher = TimeoutWatch(timeout=timeout) for sample in TimeoutSampler( diff --git a/poetry.lock b/poetry.lock index 4d2de8a443..45f6ace3e8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "appnope" @@ -335,13 +335,13 @@ testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "kubernetes" -version = "28.1.0" +version = "27.2.0" description = "Kubernetes python client" optional = false python-versions = ">=3.6" files = [ - {file = "kubernetes-28.1.0-py2.py3-none-any.whl", hash = "sha256:10f56f8160dcb73647f15fafda268e7f60cf7dbc9f8e46d52fcd46d3beb0c18d"}, - {file = "kubernetes-28.1.0.tar.gz", hash = "sha256:1468069a573430fb1cb5ad22876868f57977930f80a6749405da31cd6086a7e9"}, + {file = "kubernetes-27.2.0-py2.py3-none-any.whl", hash = "sha256:0f9376329c85cf07615ed6886bf9bf21eb1cbfc05e14ec7b0f74ed8153cd2815"}, + {file = "kubernetes-27.2.0.tar.gz", hash = "sha256:d479931c6f37561dbfdf28fc5f46384b1cb8b28f9db344ed4a232ce91990825a"}, ] [package.dependencies] @@ -353,7 +353,7 @@ pyyaml = ">=5.4.1" requests = "*" requests-oauthlib = "*" six = ">=1.9.0" -urllib3 = ">=1.24.2,<2.0" +urllib3 = ">=1.24.2" websocket-client = ">=0.32.0,<0.40.0 || >0.40.0,<0.41.dev0 || >=0.43.dev0" [package.extras] @@ -912,4 +912,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "082d0f1498ee655a0a2d90a103113c340bf734e49028d83cce1f5358c24d10d7" +content-hash = "5c87186e589573954ec737f5092031ca393da224c08174557acbebc804b1a658" diff --git a/pyproject.toml b/pyproject.toml index 1aefcef92a..40abbd07c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,20 +1,12 @@ -[tool.black] -line-length = 88 -target_version = ['py37', 'py38', 'py39', 'py310', "py311"] -exclude = ''' -( - /( - | \.git - | \.venv - | \.mypy_cache - | \.tox - )/ -) -''' +[tool.ruff] +preview = true +line-length = 120 +fix = true +output-format = "grouped" + +[tool.ruff.format] +exclude = [".git", ".venv", ".mypy_cache", ".tox", "__pycache__"] -[tool.isort] -line_length = 88 -profile = "black" [tool.poetry] name = "openshift-python-wrapper" @@ -23,13 +15,13 @@ description = "Wrapper around https://github.com/openshift/openshift-restclient- authors = ["Meni Yakove ", "Ruth Netser "] readme = "README.md" license = "Apache-2.0" -packages = [{include = "ocp_resources"}] +packages = [{ include = "ocp_resources" }] homepage = "https://github.com/RedHatQE/openshift-python-wrapper" documentation = "https://openshift-python-wrapper.readthedocs.io/en/latest/" keywords = ["Openshift", "Kubevirt", "CNV"] classifiers = [ - "Programming Language :: Python :: 3", - "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Operating System :: OS Independent", ] [tool.poetry.urls] @@ -59,7 +51,7 @@ python = "^3.8" openshift = "^0.13.2" xmltodict = "^0.13.0" colorlog = "^6.7.0" -kubernetes = "^28.0.0" +kubernetes = "^27.0.0" python-benedict = "^0.33.0" packaging = "^23.1" python-simple-logger = "^1.0.5" diff --git a/tests/test_resources.py b/tests/test_resources.py index 57d17c1ae1..5e7e496106 100644 --- a/tests/test_resources.py +++ b/tests/test_resources.py @@ -31,7 +31,5 @@ def test_create(): @pytest.mark.kubevirt def test_vm(namespace): name = "test-vm" - with VirtualMachine( - name=name, namespace=namespace.name, body=generate_yaml_from_template(name=name) - ): + with VirtualMachine(name=name, namespace=namespace.name, body=generate_yaml_from_template(name=name)): pass diff --git a/tests/test_validate_resources.py b/tests/test_validate_resources.py index 355c09ef7e..c6b461cefb 100644 --- a/tests/test_validate_resources.py +++ b/tests/test_validate_resources.py @@ -51,9 +51,7 @@ def _process_api_type(api_type, api_value, resource_dict, cls): def _get_api_group_and_version(bodies): for targets in bodies: api_type = targets.targets[0].id - return api_type, getattr( - targets.value, "attr", getattr(targets.value, "s", None) - ) + return api_type, getattr(targets.value, "attr", getattr(targets.value, "s", None)) def _get_namespaced(cls, resource_dict, api_value): @@ -61,9 +59,7 @@ def _get_namespaced(cls, resource_dict, api_value): for base in getattr(cls, "bases", []): api_group_name = _api_group_name(api_value=api_value) namespaced = base.id == "NamespacedResource" - api_group = _api_group_dict( - resource_dict=resource_dict, api_group_name=api_group_name - ) + api_group = _api_group_dict(resource_dict=resource_dict, api_group_name=api_group_name) should_be_namespaced = api_group["namespaced"] == "true" if namespaced != should_be_namespaced: @@ -79,24 +75,18 @@ def _get_api_group(api_value, cls, resource_dict): api_group_name = _api_group_name(api_value=api_value) if api_group_name not in resource_dict["api_group"]: - errors.append( - f"Resource {cls.name} api_group should be " - f"{resource_dict['api_group']}. got {api_group_name}" - ) + errors.append(f"Resource {cls.name} api_group should be " f"{resource_dict['api_group']}. got {api_group_name}") return errors def _get_api_version(api_value, cls, resource_dict): errors = [] api_group_name = _api_group_name(api_value=api_value) - api_group = _api_group_dict( - resource_dict=resource_dict, api_group_name=api_group_name - ) + api_group = _api_group_dict(resource_dict=resource_dict, api_group_name=api_group_name) if api_value.lower() != api_group["api_version"]: desire_api_group = resource_dict["api_version"].split("/")[0] errors.append( - f"Resource {cls.name} have api_version {api_value} " - f"but should have api_group = {desire_api_group}" + f"Resource {cls.name} have api_version {api_value} " f"but should have api_group = {desire_api_group}" ) return errors @@ -114,8 +104,7 @@ def _resource_file(): @pytest.fixture() def resources_definitions(): file_ = ( - "https://raw.githubusercontent.com/RedHatQE/" - "openshift-resources-definitions/main/resources_definitions.json" + "https://raw.githubusercontent.com/RedHatQE/" "openshift-resources-definitions/main/resources_definitions.json" ) content = requests.get(file_).content return json.loads(content) @@ -133,17 +122,9 @@ def resources_definitions_errors(resources_definitions): if not resource_dict: continue - bodies = [ - body_ - for body_ in getattr(cls, "body") - if isinstance(body_, ast.Assign) - ] + bodies = [body_ for body_ in getattr(cls, "body") if isinstance(body_, ast.Assign)] api_type, api_value = _get_api_group_and_version(bodies=bodies) - errors.extend( - _get_namespaced( - cls=cls, resource_dict=resource_dict, api_value=api_value - ) - ) + errors.extend(_get_namespaced(cls=cls, resource_dict=resource_dict, api_value=api_value)) errors.extend( _process_api_type( api_type=api_type, diff --git a/tests/unittests/test_utils.py b/tests/unittests/test_utils.py index 990b6c7dc5..1e838f5d1e 100644 --- a/tests/unittests/test_utils.py +++ b/tests/unittests/test_utils.py @@ -113,9 +113,7 @@ def test_timeout_sampler_raises(self, test_params): "runtime_exception": IndexError("my allowed exception text"), }, { - "exception_log_regex": ( - "^.*\nLast exception: IndexError: my allowed exception text$" - ), + "exception_log_regex": ("^.*\nLast exception: IndexError: my allowed exception text$"), }, id="init_multi_exceptions_raise_allowed_with_allowed_msg", ), @@ -131,11 +129,10 @@ def test_timeout_sampler_raises_timeout(self, test_params, expected): ) except TimeoutExpiredError as exp: exception_log = str(exp) - exception_match = re.compile( - pattern=expected["exception_log_regex"], flags=re.DOTALL - ).match(string=exception_log) + exception_match = re.compile(pattern=expected["exception_log_regex"], flags=re.DOTALL).match( + string=exception_log + ) assert exception_match, ( - f"Expected Regex: {expected['exception_log_regex']!r} Exception Log:" - f" {exception_log!r}" + f"Expected Regex: {expected['exception_log_regex']!r} Exception Log:" f" {exception_log!r}" )