From 1e0aa4a04e7b064d84df4e903cb343c4f910cd34 Mon Sep 17 00:00:00 2001 From: dbasunag Date: Thu, 19 Dec 2024 07:48:18 -0500 Subject: [PATCH 01/10] debug log would print raw data and readme is updated to reflect that --- README.md | 1 + ocp_resources/resource.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3bfd10a3f5..4685857ceb 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ To change log level export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL: ```bash export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL= # can be: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" ``` +DEBUG log level should be used with caution. DEBUG loglevel prints unhashed raw data for resources on the log. ## Code check We use pre-commit for code check. diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index f2e48666cb..2688a319fe 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -885,7 +885,7 @@ def create(self, wait: bool = False) -> Optional[ResourceInstance]: hashed_res = self.hash_resource_dict(resource_dict=self.res) 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)}") + self.logger.debug(f"\n{yaml.dump(self.res)}") resource_kwargs = {"body": self.res, "namespace": self.namespace} if self.dry_run: resource_kwargs["dry_run"] = "All" @@ -905,7 +905,7 @@ def delete(self, wait: bool = False, timeout: int = TIMEOUT_4MINUTES, body: Dict try: hashed_data = self.hash_resource_dict(resource_dict=self.instance.to_dict()) self.logger.info(f"Deleting {hashed_data}") - self.logger.debug(f"\n{yaml.dump(hashed_data)}") + self.logger.debug(f"\n{yaml.dump(self.instance.to_dict())}") self.api.delete(name=self.name, namespace=self.namespace, body=body) if wait: @@ -940,7 +940,7 @@ def update(self, resource_dict: Dict[str, Any]) -> None: """ hashed_resource_dict = self.hash_resource_dict(resource_dict=resource_dict) self.logger.info(f"Update {self.kind} {self.name}:\n{hashed_resource_dict}") - self.logger.debug(f"\n{yaml.dump(hashed_resource_dict)}") + self.logger.debug(f"\n{yaml.dump(resource_dict)}") self.api.patch( body=resource_dict, namespace=self.namespace, @@ -954,7 +954,7 @@ def update_replace(self, resource_dict: Dict[str, Any]) -> None: """ hashed_resource_dict = self.hash_resource_dict(resource_dict=resource_dict) self.logger.info(f"Replace {self.kind} {self.name}: \n{hashed_resource_dict}") - self.logger.debug(f"\n{yaml.dump(hashed_resource_dict)}") + self.logger.debug(f"\n{yaml.dump(resource_dict)}") self.api.replace(body=resource_dict, name=self.name, namespace=self.namespace) @staticmethod From 6241b49b1964edc2d1146c9814b56e7e51ab68e4 Mon Sep 17 00:00:00 2001 From: dbasunag Date: Thu, 19 Dec 2024 08:32:46 -0500 Subject: [PATCH 02/10] updates --- README.md | 3 ++- ocp_resources/resource.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4685857ceb..e2bc960536 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,8 @@ To change log level export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL: ```bash export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL= # can be: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" ``` -DEBUG log level should be used with caution. DEBUG loglevel prints unhashed raw data for resources on the log. +IMPORTANT: DEBUG log level should be used with caution. DEBUG loglevel prints unhashed raw data for resources on the +log. ## Code check We use pre-commit for code check. diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index 2688a319fe..3c673e9147 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -555,6 +555,8 @@ def _ensure_exists(self) -> None: def _set_logger(self) -> logging.Logger: log_level = os.environ.get("OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL", "INFO") log_file = os.environ.get("OPENSHIFT_PYTHON_WRAPPER_LOG_FILE", "") + if log_level == "DEBUG": + self.logger.warning(f"{log_level} selected. Unhashed resource data would be printed on log.") return get_logger( name=f"{__name__.rsplit('.')[0]} {self.kind}", level=log_level, From d921d54518a686d28cd3465b9924223c244e8977 Mon Sep 17 00:00:00 2001 From: dbasunag Date: Thu, 19 Dec 2024 09:46:38 -0500 Subject: [PATCH 03/10] updated readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index e2bc960536..03786ec740 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,7 @@ To change log level export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL: ```bash export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL= # can be: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" ``` -IMPORTANT: DEBUG log level should be used with caution. DEBUG loglevel prints unhashed raw data for resources on the -log. +Important: DEBUG log level should be used with caution. It prints unhashed raw data for resources in the logs, which may expose sensitive information. Use only in secure environments.log. ## Code check We use pre-commit for code check. From 6cdec07aa6aa6a53a28f6e5eae59f5f875e0c065 Mon Sep 17 00:00:00 2001 From: dbasunag Date: Fri, 20 Dec 2024 08:06:02 -0500 Subject: [PATCH 04/10] minor fix --- ocp_resources/resource.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index 49738c1008..fc4983c6ec 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -564,13 +564,14 @@ def _ensure_exists(self) -> None: def _set_logger(self) -> logging.Logger: log_level = os.environ.get("OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL", "INFO") log_file = os.environ.get("OPENSHIFT_PYTHON_WRAPPER_LOG_FILE", "") - if log_level == "DEBUG": - self.logger.warning(f"{log_level} selected. Unhashed resource data would be printed on log.") - return get_logger( + logger = get_logger( name=f"{__name__.rsplit('.')[0]} {self.kind}", level=log_level, filename=log_file, ) + if log_level == "DEBUG": + logger.warning(f"{log_level} selected. Unhashed resource data would be printed on log.") + return logger def _prepare_node_selector_spec(self) -> Dict[str, str]: return self.node_selector or self.node_selector_labels or {} From 37572ff1dc0f134810a18ffcbfa9f6e2c9f8e864 Mon Sep 17 00:00:00 2001 From: dbasunag Date: Fri, 20 Dec 2024 10:20:27 -0500 Subject: [PATCH 05/10] remove the warning about debug level --- ocp_resources/resource.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index fc4983c6ec..c8a88ca601 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -564,14 +564,11 @@ def _ensure_exists(self) -> None: def _set_logger(self) -> logging.Logger: log_level = os.environ.get("OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL", "INFO") log_file = os.environ.get("OPENSHIFT_PYTHON_WRAPPER_LOG_FILE", "") - logger = get_logger( + return get_logger( name=f"{__name__.rsplit('.')[0]} {self.kind}", level=log_level, filename=log_file, ) - if log_level == "DEBUG": - logger.warning(f"{log_level} selected. Unhashed resource data would be printed on log.") - return logger def _prepare_node_selector_spec(self) -> Dict[str, str]: return self.node_selector or self.node_selector_labels or {} From a919958619473f8fc1947175359b8dc3de54f5b5 Mon Sep 17 00:00:00 2001 From: dbasunag Date: Fri, 20 Dec 2024 13:22:02 -0500 Subject: [PATCH 06/10] updates based on reviews --- ocp_resources/resource.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index c8a88ca601..f879b07897 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -912,9 +912,10 @@ def delete(self, wait: bool = False, timeout: int = TIMEOUT_4MINUTES, body: Dict if self.exists: try: - hashed_data = self.hash_resource_dict(resource_dict=self.instance.to_dict()) + instance_dict = self.instance.to_dict() + hashed_data = self.hash_resource_dict(resource_dict=instance_dict) self.logger.info(f"Deleting {hashed_data}") - self.logger.debug(f"\n{yaml.dump(self.instance.to_dict())}") + self.logger.debug(f"\n{yaml.dump(instance_dict)}") self.api.delete(name=self.name, namespace=self.namespace, body=body) if wait: From c603aabcc472ea197b0da4c0dfb3dabbf98d26da Mon Sep 17 00:00:00 2001 From: Meni Yakove <441263+myakove@users.noreply.github.com> Date: Sun, 22 Dec 2024 15:52:40 +0200 Subject: [PATCH 07/10] Update README.md Co-authored-by: Ruth Netser --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 03786ec740..626ccf7f6f 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ To change log level export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL: ```bash export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL= # can be: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" ``` -Important: DEBUG log level should be used with caution. It prints unhashed raw data for resources in the logs, which may expose sensitive information. Use only in secure environments.log. +Important: DEBUG log level should be used with caution. It prints unhashed raw data for resources in the logs, which may expose sensitive information. Use only in secure environments. ## Code check We use pre-commit for code check. From 7b5f35f4408f79f5a63b06a49cac4c607c85c2de Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Mon, 23 Dec 2024 13:32:23 +0200 Subject: [PATCH 08/10] User can disable hash by env var --- README.md | 43 +++++++++++++++++++++++++++++++-------- ocp_resources/resource.py | 12 +++++++---- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 626ccf7f6f..2b4f34aa5f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # openshift-python-wrapper (`wrapper`) + Pypi: [openshift-python-wrapper](https://pypi.org/project/openshift-python-wrapper) A python wrapper for [kubernetes-python-client](https://github.com/kubernetes-client/python) with support for [RedHat Container Virtualization](https://www.openshift.com/learn/topics/virtualization) Docs: [openshift-python-wrapper docs](https://openshift-python-wrapper.readthedocs.io/en/latest/) @@ -14,7 +15,7 @@ The wrapper handles it all and provides simple and intuitive functionality. ![Alt Text](examples/pod_example.gif) -Both developers or testers can use the wrapper. The code is modular and easy to maintain. +Both developers or testers can use the wrapper. The code is modular and easy to maintain. Instead of writing custom code for every API, you can use the wrapper that provides a consistent interface for interacting with APIs. It saves time, avoids code duplications, and reduces the chance of errors. @@ -25,31 +26,43 @@ Resources can even be saved for debugging. Resource manifests and logs can be easily collected. ## Installation + From source: + ```bash git clone https://github.com/RedHatQE/openshift-python-wrapper.git cd openshift-python-wrapper python setup.py install --user ``` + From pypi: + ```bash pip install openshift-python-wrapper --user ``` ## Release new version -### requirements: -* Export GitHub token + +### requirements + +- Export GitHub token + ```bash export GITHUB_TOKEN= ``` -* [release-it](https://github.com/release-it/release-it) + +- [release-it](https://github.com/release-it/release-it) + ```bash sudo npm install --global release-it npm install --save-dev @release-it/bumper ``` -### usage: -* Create a release, run from the relevant branch. -To create a 4.11 release, run: + +### usage + +- Create a release, run from the relevant branch. + To create a 4.11 release, run: + ```bash git checkout v4.11 git pull @@ -57,22 +70,33 @@ release-it # Follow the instructions ``` ## docs + Hosted on readthedocs.io [openshift-python-wrapper](https://openshift-python-wrapper.readthedocs.io/en/latest/) ## PR dependency + For PR dependency we use [dpulls](https://www.dpulls.com/) To make PR depends on other PR add `depends on #` in the PR description. ## Logging configuration -To change log level export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL: + +To change log level export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL: ```bash export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL= # can be: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" ``` -Important: DEBUG log level should be used with caution. It prints unhashed raw data for resources in the logs, which may expose sensitive information. Use only in secure environments. + +- By default some sensitive information is hashed in the logs, and if running with DEBUG the log output can be corrupted. + In secure environments user can set `OPENSHIFT_PYTHON_WRAPPER_HASH_LOG_DATA="false"` environment variable to disable the log hashing. + + ```bash + export OPENSHIFT_PYTHON_WRAPPER_HASH_LOG_DATA="false" + ``` ## Code check + We use pre-commit for code check. + ```bash pre-commit install ``` @@ -80,4 +104,5 @@ pre-commit install Some code examples locate at [examples](examples) directory ## Contribute to the project + To contribute new additions or changes to the project, please refer to the [contribution guide](CONTRIBUTING.md) first. diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index f879b07897..a89fd3210b 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -894,7 +894,7 @@ def create(self, wait: bool = False) -> Optional[ResourceInstance]: hashed_res = self.hash_resource_dict(resource_dict=self.res) self.logger.info(f"Create {self.kind} {self.name}") self.logger.info(f"Posting {hashed_res}") - self.logger.debug(f"\n{yaml.dump(self.res)}") + self.logger.debug(f"\n{yaml.dump(hashed_res)}") resource_kwargs = {"body": self.res, "namespace": self.namespace} if self.dry_run: resource_kwargs["dry_run"] = "All" @@ -915,7 +915,7 @@ def delete(self, wait: bool = False, timeout: int = TIMEOUT_4MINUTES, body: Dict instance_dict = self.instance.to_dict() hashed_data = self.hash_resource_dict(resource_dict=instance_dict) self.logger.info(f"Deleting {hashed_data}") - self.logger.debug(f"\n{yaml.dump(instance_dict)}") + self.logger.debug(f"\n{yaml.dump(hashed_data)}") self.api.delete(name=self.name, namespace=self.namespace, body=body) if wait: @@ -950,7 +950,7 @@ def update(self, resource_dict: Dict[str, Any]) -> None: """ hashed_resource_dict = self.hash_resource_dict(resource_dict=resource_dict) self.logger.info(f"Update {self.kind} {self.name}:\n{hashed_resource_dict}") - self.logger.debug(f"\n{yaml.dump(resource_dict)}") + self.logger.debug(f"\n{yaml.dump(hashed_resource_dict)}") self.api.patch( body=resource_dict, namespace=self.namespace, @@ -964,7 +964,7 @@ def update_replace(self, resource_dict: Dict[str, Any]) -> None: """ hashed_resource_dict = self.hash_resource_dict(resource_dict=resource_dict) self.logger.info(f"Replace {self.kind} {self.name}: \n{hashed_resource_dict}") - self.logger.debug(f"\n{yaml.dump(resource_dict)}") + self.logger.debug(f"\n{yaml.dump(hashed_resource_dict)}") self.api.replace(body=resource_dict, name=self.name, namespace=self.namespace) @staticmethod @@ -1275,10 +1275,14 @@ 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") + if os.environ.get("OPENSHIFT_PYTHON_WRAPPER_HASH_LOG_DATA", "true") == "false": + return resource_dict + if self.keys_to_hash and self.hash_log_data: resource_dict = copy.deepcopy(resource_dict) for key_name in self.keys_to_hash: resource_dict = replace_key_with_hashed_value(resource_dict=resource_dict, key_name=key_name) + return resource_dict def get_condition_message(self, condition_type: str, condition_status: str = "") -> str: From 38692437ffb0b900b3a29e9fadf8e76c31460eb1 Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Mon, 23 Dec 2024 13:39:50 +0200 Subject: [PATCH 09/10] Fix typing --- ocp_resources/resource.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index a89fd3210b..0b911bfe5c 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -912,8 +912,7 @@ def delete(self, wait: bool = False, timeout: int = TIMEOUT_4MINUTES, body: Dict if self.exists: try: - instance_dict = self.instance.to_dict() - hashed_data = self.hash_resource_dict(resource_dict=instance_dict) + hashed_data = self.hash_resource_dict(resource_dict=self.instance.to_dict()) self.logger.info(f"Deleting {hashed_data}") self.logger.debug(f"\n{yaml.dump(hashed_data)}") self.api.delete(name=self.name, namespace=self.namespace, body=body) From cc6c7ebc516bb68b76f37da92f30ffbbc7074a9d Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Mon, 23 Dec 2024 13:44:10 +0200 Subject: [PATCH 10/10] call hash_resource_dict only if instance is a dict --- ocp_resources/resource.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ocp_resources/resource.py b/ocp_resources/resource.py index 0b911bfe5c..f1038c4892 100644 --- a/ocp_resources/resource.py +++ b/ocp_resources/resource.py @@ -912,9 +912,15 @@ def delete(self, wait: bool = False, timeout: int = TIMEOUT_4MINUTES, body: Dict if self.exists: try: - hashed_data = self.hash_resource_dict(resource_dict=self.instance.to_dict()) - self.logger.info(f"Deleting {hashed_data}") - self.logger.debug(f"\n{yaml.dump(hashed_data)}") + _instance_dict = self.instance.to_dict() + if isinstance(_instance_dict, dict): + hashed_data = self.hash_resource_dict(resource_dict=_instance_dict) + self.logger.info(f"Deleting {hashed_data}") + self.logger.debug(f"\n{yaml.dump(hashed_data)}") + + else: + self.logger.warning(f"{self.kind}: {self.name} instance.to_dict() return was not a dict") + self.api.delete(name=self.name, namespace=self.namespace, body=body) if wait: