diff --git a/f5_cccl/bigip.py b/f5_cccl/bigip.py index 2674889..7feab1b 100644 --- a/f5_cccl/bigip.py +++ b/f5_cccl/bigip.py @@ -137,7 +137,7 @@ def refresh_ltm(self): try: self._refresh_ltm() except F5SDKError as error: - LOGGER.error("F5 SDK Error: %s", error) + LOGGER.error("F5 SDK Error: %s", type(error).__name__) raise cccl_exc.F5CcclCacheRefreshError( "BigIPProxy: failed to refresh internal BIG-IP ltm state.") @@ -147,7 +147,7 @@ def refresh_net(self): try: self._refresh_net() except F5SDKError as error: - LOGGER.error("F5 SDK Error: %s", error) + LOGGER.error("F5 SDK Error: %s", type(error).__name__) raise cccl_exc.F5CcclCacheRefreshError( "BigIPProxy: failed to refresh internal BIG-IP net state.") @@ -174,7 +174,8 @@ def _create_resource(self, resource_type, resource_obj, except (ValueError, TypeError) as error: LOGGER.error( "Failed to create iControl REST resource %s, %s: error(%s)", - resource_obj.name, resource_type.__name__, str(error)) + resource_obj.name, resource_type.__name__, + type(error).__name__) # An error occurred because the constructor did not like the # input. Use resource name and partition to allow for its @@ -453,7 +454,7 @@ def get_default_route_domain(self): # Note: This information is needed when processing the request config # which occurs before self.refresh() is called except Exception as error: - LOGGER.error("F5 SDK Error: %s", error) + LOGGER.error("F5 SDK Error: %s", type(error).__name__) raise cccl_exc.F5CcclResourceNotFoundError( f"The requested partition {self._partition} was not found.") diff --git a/f5_cccl/resource/resource.py b/f5_cccl/resource/resource.py index c1fe099..9e4a44e 100644 --- a/f5_cccl/resource/resource.py +++ b/f5_cccl/resource/resource.py @@ -118,7 +118,7 @@ def __lt__(self, resource): return self.full_path() < resource.full_path() def __str__(self): - return str(self._data) + return "{} /{}/{}".format(self.classname(), self.partition, self.name) def merge(self, desired_data): """Merge in properties from controller instead of replacing""" @@ -384,14 +384,16 @@ def _handle_http_error(self, error): LOGGER.error( "HTTP error(%d): CCCL resource(%s) /%s/%s.", code, self.classname(), self.partition, self.name) + sanitized = "HTTP {} for /{}/{}".format( + code, self.partition, self.name) if code == 404: - raise cccl_exc.F5CcclResourceNotFoundError(str(error)) + raise cccl_exc.F5CcclResourceNotFoundError(sanitized) elif code == 409: - raise cccl_exc.F5CcclResourceConflictError(str(error)) + raise cccl_exc.F5CcclResourceConflictError(sanitized) elif 400 <= code < 500: - raise cccl_exc.F5CcclResourceRequestError(str(error)) + raise cccl_exc.F5CcclResourceRequestError(sanitized) else: - raise cccl_exc.F5CcclError(str(error)) + raise cccl_exc.F5CcclError(sanitized) def _process_metadata_flags(self, name, metadata_list): # look for supported flags diff --git a/f5_cccl/utils/mgmt.py b/f5_cccl/utils/mgmt.py index 12f967f..e905332 100644 --- a/f5_cccl/utils/mgmt.py +++ b/f5_cccl/utils/mgmt.py @@ -16,9 +16,47 @@ # """Wrapper functions for the f5-sdk""" +import logging + from f5.bigip import ManagementRoot +log = logging.getLogger(__name__) + + +def mgmt_root(host, username, password, port, token, ca_certs=None): + """Create a BIG-IP Management Root object. + + Args: + host: BIG-IP hostname or IP. + username: BIG-IP admin username. + password: BIG-IP admin password. + port: BIG-IP management port. + token: Authentication token type (e.g. "tmos"). + ca_certs: Optional path to a PEM CA bundle file for TLS + verification of the BIG-IP management endpoint. + When *None* the default SDK behaviour (no custom + CA verification) is used. + """ + bigip = ManagementRoot(host, username, password, port=port, token=token) + + # Apply custom CA certificate for TLS verification if provided. + # The f5-sdk's ManagementRoot has an 'icrs' attribute which is an + # iControlRESTSession — a subclass of requests.Session. + # Setting .verify on it to a PEM file path enables TLS verification + # against the supplied CA bundle for all subsequent REST calls. + if ca_certs: + try: + bigip.icrs.verify = ca_certs + log.info("TLS verification enabled with CA bundle: %s", ca_certs) + except AttributeError: + # Fallback: some f5-sdk versions may nest the session differently + try: + bigip.icrs.session.verify = ca_certs + log.info("TLS verification enabled (via session.verify) with CA bundle: %s", ca_certs) + except AttributeError: + log.warning( + "Could not set verify on iControlRESTSession; " + "TLS verification with custom CA may not be active." + ) -def mgmt_root(host, username, password, port, token): - """Create a BIG-IP Management Root object""" - return ManagementRoot(host, username, password, port=port, token=token) + return bigip