From a552e15a3ed084fcb2ebce0c4d2840aa234f6f63 Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Thu, 21 Nov 2024 13:58:42 -0500 Subject: [PATCH] prevent empty data payload from being send to host (#5) * adds per host verbosity setting This commit allows for a per host verbosity setting to control the amount of debug output. The device can now set `itential_verbosity` to any value in the range of 1 to 5. If the `itential_verbosity` settings is less than the `ansible_verbosity` setting, the `ansible_verbosity` setting will take precedence. * prevent empty data payload from being send to host This commit addresses an issue where an empty data payload would be send to the host as an empty array or empty object. This change will now check if the data is empty and not attempting to send it to the host if it is. * clean up lint errors * update workflow yaml lint error --- .github/workflows/updateChangelog.yml | 2 +- meta/runtime.yml | 2 +- plugins/module_utils/display.py | 17 +++++++++++++++++ plugins/module_utils/hosts.py | 7 +++++++ plugins/module_utils/http.py | 22 ++++++++++++---------- plugins/modules/include_vars.py | 8 ++++---- 6 files changed, 42 insertions(+), 16 deletions(-) diff --git a/.github/workflows/updateChangelog.yml b/.github/workflows/updateChangelog.yml index 3ad3425..2a7de01 100644 --- a/.github/workflows/updateChangelog.yml +++ b/.github/workflows/updateChangelog.yml @@ -16,7 +16,7 @@ jobs: - name: setup python uses: actions/setup-python@v5 with: - python-version: 3.8 #install the python needed + python-version: 3.8 # install the python needed - name: Install dependencies run: | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi diff --git a/meta/runtime.yml b/meta/runtime.yml index 4f8908e..1b45e4e 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,4 +1,4 @@ --- # Collections must specify a minimum required ansible version to upload # to galaxy -requires_ansible: ">=2.17.0" +requires_ansible: ">=2.15.0" diff --git a/plugins/module_utils/display.py b/plugins/module_utils/display.py index 246f3b3..49ee9a1 100644 --- a/plugins/module_utils/display.py +++ b/plugins/module_utils/display.py @@ -3,12 +3,29 @@ # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later +import os + from ansible.utils.display import Display display = Display() +def set_verbosity(lvl) -> None: + """Overrides the verbosity level + + Args: + lvl (int): The verbosity level to set. Value values are in the + range of 1 to 5 + + Returns: + None + """ + if lvl is not None: + if 0 <= lvl <= 6: + display.verbosity = lvl + + def tostring(msg) -> None: """Ensures the passed message is a string diff --git a/plugins/module_utils/hosts.py b/plugins/module_utils/hosts.py index 080d839..2385bca 100644 --- a/plugins/module_utils/hosts.py +++ b/plugins/module_utils/hosts.py @@ -28,6 +28,13 @@ def new(spec, hostvars) -> typing.Any: Returns: An immutable instance that represents the host """ + display.trace("hosts.new") + + verbosity = hostvars.get("itential_verbosity") + if verbosity is not None: + if hostvars.get("ansible_verbosity") < verbosity: + display.set_verbosity(verbosity) + options = spec.get("options") values = dict() diff --git a/plugins/module_utils/http.py b/plugins/module_utils/http.py index 9d069f2..5282e31 100644 --- a/plugins/module_utils/http.py +++ b/plugins/module_utils/http.py @@ -51,6 +51,8 @@ def send_request(method, url, headers=None, data=None, params=None, auth=None, t Returns A `Response` object that contains the response from the API call """ + display.trace("http.send_request") + if disable_warnings is True: urllib3.disable_warnings() @@ -58,7 +60,6 @@ def send_request(method, url, headers=None, data=None, params=None, auth=None, t "method": method, "url": url, "headers": headers, - "data": data, "params": params, "verify": verify, } @@ -72,10 +73,10 @@ def send_request(method, url, headers=None, data=None, params=None, auth=None, t if certificate_file is not None and private_key_file is not None: kwargs["cert"] = (certificate_file, private_key_file) - if isinstance(kwargs.get("data"), (dict, list)): + if isinstance(kwargs.get("data"), (dict, list)) and kwargs.get("data"): kwargs["data"] = json.dumps(data) - display.vvvvv(f"Request: {kwargs}") + display.vvvvv(f"Request object: {kwargs}") try: if session is not None: @@ -83,6 +84,10 @@ def send_request(method, url, headers=None, data=None, params=None, auth=None, t else: resp = requests.request(**kwargs) + display.vvv(f"HTTP response is {resp.status_code} {resp.reason}") + display.vvvvv(f"Start of response body\n{resp.text}\nEnd of response body") + display.vvvvv(f"Call completed in {resp.elapsed}") + except requests.exceptions.ConnectionError as exc: display.vvvvv(traceback.format_exc()) raise AnsibleError(f"Failed to establish a connection to {url}") @@ -116,7 +121,7 @@ def make_url(host, path, port=0, use_tls=True) -> str: Returns: A string that represents the full URL """ - display.trace("http.make_url()", host=host) + display.trace("http.make_url") if port == 0: port = 443 if use_tls is True else 80 @@ -146,6 +151,7 @@ def basic_auth(username, password) -> HTTPBasicAuth: Returns: A `requests.HTTPBasicAuth` object """ + display.trace("http.basic_auth") return HTTPBasicAuth(username, password) @@ -231,6 +237,7 @@ class Session(object): session (requests.Session): The requests library session. """ def __init__(self, name): + display.trace("http.Session.init") self.name = name self.session = requests.Session() @@ -244,7 +251,7 @@ def send(self, request) -> Response: Returns: A `Response` object """ - display.trace("Session.send()", host=self.name) + display.trace("http.Session.send") url = make_url( request.host, @@ -253,8 +260,6 @@ def send(self, request) -> Response: request.use_tls, ) - display.vvv(f"{request.method} {url}", host=self.name) - resp = send_request( method=request.method, url=url, @@ -265,9 +270,6 @@ def send(self, request) -> Response: session=self.session ) - display.vvv(f"RESPONSE status_code={resp.status_code}", host=self.name) - display.vvv(f"Elapsed time {resp.elapsed}", host=self.name) - return Response( status_code=resp.status_code, status=resp.reason, diff --git a/plugins/modules/include_vars.py b/plugins/modules/include_vars.py index 18a26ba..74078a5 100644 --- a/plugins/modules/include_vars.py +++ b/plugins/modules/include_vars.py @@ -36,8 +36,8 @@ EXAMPLES = """ - - name: Include all files from config - itential.core.include_vars: - name: config - path: path/to/files +- name: Include all files from config + itential.core.include_vars: + name: config + path: path/to/files """