From 8c04858adc551a24dcf9c7dd8d81b61f8c955778 Mon Sep 17 00:00:00 2001 From: Przemek Rogala Date: Thu, 25 Apr 2024 13:59:37 +0100 Subject: [PATCH 1/4] [Infoblox] Replace requests.request with requests.Session. --- .../integrations/infoblox/utils/client.py | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/nautobot_ssot/integrations/infoblox/utils/client.py b/nautobot_ssot/integrations/infoblox/utils/client.py index 2e43312f9..c210328bb 100644 --- a/nautobot_ssot/integrations/infoblox/utils/client.py +++ b/nautobot_ssot/integrations/infoblox/utils/client.py @@ -1,7 +1,6 @@ """All interactions with infoblox.""" # pylint: disable=too-many-lines from __future__ import annotations -import copy import json import ipaddress import logging @@ -10,6 +9,7 @@ from collections import defaultdict from typing import Optional import requests +from requests.auth import HTTPBasicAuth from requests.exceptions import HTTPError from requests.compat import urljoin from dns import reversename @@ -113,41 +113,60 @@ def __init__( raise InvalidUrlScheme(scheme=parsed_url.scheme) else: self.url = parsed_url.geturl() - self.username = username - self.password = password - self.verify_ssl = verify_ssl + self.auth = HTTPBasicAuth(username, password) self.wapi_version = wapi_version - self.cookie = cookie - if self.verify_ssl is False: + self.session = self._init_session(verify_ssl=verify_ssl, cookie=cookie) + + def _init_session(self, verify_ssl: bool, cookie: Optional[dict]) -> requests.Session: + """Initiatlize requests Session object used across all the API calls. + + Args: + verify_ssl (bool): whether to verify SSL cert for https calls + cookie (dict): optional dict with cookies to set on the Session object + + Returns: + initialized session object + """ + if verify_ssl is False: requests.packages.urllib3.disable_warnings( # pylint: disable=no-member requests.packages.urllib3.exceptions.InsecureRequestWarning # pylint: disable=no-member ) # pylint: disable=no-member self.headers = {"Content-Type": "application/json"} - self.extra_vars = {} + session = requests.Session() + if cookie and isinstance(cookie, dict): + session.cookies.update(self.cookie) + session.verify = verify_ssl + session.headers.update(self.headers) + session.auth = self.auth + + return session def _request(self, method, path, **kwargs): - """Return a response object after making a request to by other methods. + """Return a response object after making a request by a specified method. Args: - method (str): Request HTTP method to call with requests. + method (str): Request HTTP method to call with Session.request. path (str): URL path to call. Returns: :class:`~requests.Response`: Response from the API. """ - kwargs["verify"] = self.verify_ssl - kwargs["headers"] = self.headers api_path = f"/wapi/{self.wapi_version}/{path}" url = urljoin(self.url, api_path) - if self.cookie: - resp = requests.request( - method, url, cookies=self.cookie, timeout=PLUGIN_CFG["infoblox_request_timeout"], **kwargs - ) + if self.session.cookies.get("ibapauth"): + self.session.auth = None else: - kwargs["auth"] = requests.auth.HTTPBasicAuth(self.username, self.password) - resp = requests.request(method, url, timeout=PLUGIN_CFG["infoblox_request_timeout"], **kwargs) - self.cookie = copy.copy(resp.cookies.get_dict("ibapauth")) + self.session.auth = self.auth + + resp = self.session.request(method, url, timeout=PLUGIN_CFG["infoblox_request_timeout"], **kwargs) + # Infoblox provides meaningful error messages for error codes >= 400 + if resp.status_code >= 400: + try: + err_msg = resp.json() + except json.decoder.JSONDecodeError: + err_msg = resp.text + logger.error(err_msg) resp.raise_for_status() return resp From 477f44321e243d6c1f775e5e661b02ac08a84164 Mon Sep 17 00:00:00 2001 From: Przemek Rogala Date: Thu, 25 Apr 2024 14:11:54 +0100 Subject: [PATCH 2/4] Add change fragment. --- changes/437.changed | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/437.changed diff --git a/changes/437.changed b/changes/437.changed new file mode 100644 index 000000000..7704dce4e --- /dev/null +++ b/changes/437.changed @@ -0,0 +1 @@ +Changed the Infoblox `utils.client` to make API calls using `requests.Session` instead of `requests.request`. \ No newline at end of file From 380c5f690c8accc440b77651e2c701d3ec39e814 Mon Sep 17 00:00:00 2001 From: Przemek Rogala Date: Thu, 25 Apr 2024 14:32:37 +0100 Subject: [PATCH 3/4] Fix reference to cookie var. --- nautobot_ssot/integrations/infoblox/utils/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nautobot_ssot/integrations/infoblox/utils/client.py b/nautobot_ssot/integrations/infoblox/utils/client.py index c210328bb..def133980 100644 --- a/nautobot_ssot/integrations/infoblox/utils/client.py +++ b/nautobot_ssot/integrations/infoblox/utils/client.py @@ -134,7 +134,7 @@ def _init_session(self, verify_ssl: bool, cookie: Optional[dict]) -> requests.Se self.headers = {"Content-Type": "application/json"} session = requests.Session() if cookie and isinstance(cookie, dict): - session.cookies.update(self.cookie) + session.cookies.update(cookie) session.verify = verify_ssl session.headers.update(self.headers) session.auth = self.auth From 2eb2782893e5d8a260a3cec0bb062015246b9764 Mon Sep 17 00:00:00 2001 From: Przemek Rogala Date: Thu, 25 Apr 2024 16:42:03 +0100 Subject: [PATCH 4/4] Fix typo. --- nautobot_ssot/integrations/infoblox/utils/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nautobot_ssot/integrations/infoblox/utils/client.py b/nautobot_ssot/integrations/infoblox/utils/client.py index def133980..689055795 100644 --- a/nautobot_ssot/integrations/infoblox/utils/client.py +++ b/nautobot_ssot/integrations/infoblox/utils/client.py @@ -118,7 +118,7 @@ def __init__( self.session = self._init_session(verify_ssl=verify_ssl, cookie=cookie) def _init_session(self, verify_ssl: bool, cookie: Optional[dict]) -> requests.Session: - """Initiatlize requests Session object used across all the API calls. + """Initialize requests Session object that is used across all the API calls. Args: verify_ssl (bool): whether to verify SSL cert for https calls