From ae87eeab9069f5db56efc6e3c05ef62b460f6d19 Mon Sep 17 00:00:00 2001 From: checktheroads Date: Sun, 5 Jan 2020 00:32:54 -0700 Subject: [PATCH] add SSL support for hyperglass-agent --- hyperglass/.gitignore | 1 + hyperglass/command/execute.py | 35 +++++++++++++++++--------- hyperglass/configuration/models/ssl.py | 15 +++++++++++ 3 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 hyperglass/configuration/models/ssl.py diff --git a/hyperglass/.gitignore b/hyperglass/.gitignore index f88c11c..bb7d937 100644 --- a/hyperglass/.gitignore +++ b/hyperglass/.gitignore @@ -8,3 +8,4 @@ test.py __pycache__/ parsing/ *_old +certs/ diff --git a/hyperglass/command/execute.py b/hyperglass/command/execute.py index 5f2bb7c..3097ecb 100644 --- a/hyperglass/command/execute.py +++ b/hyperglass/command/execute.py @@ -26,7 +26,6 @@ from hyperglass.command.validate import Validate from hyperglass.configuration import devices from hyperglass.configuration import params from hyperglass.constants import Supported -from hyperglass.constants import protocol_map from hyperglass.exceptions import AuthError from hyperglass.exceptions import DeviceTimeout from hyperglass.exceptions import ResponseEmpty @@ -225,18 +224,31 @@ class Connect: """Connect to a device running hyperglass-agent via HTTP.""" log.debug(f"Query parameters: {self.query}") - headers = {"Content-Type": "application/json"} - http_protocol = protocol_map.get(self.device.port, "https") - endpoint = "{protocol}://{addr}:{port}/query".format( - protocol=http_protocol, addr=self.device.address, port=self.device.port + client_params = { + "headers": {"Content-Type": "application/json"}, + "timeout": params.general.request_timeout, + } + if self.device.ssl is not None and self.device.ssl.enable: + http_protocol = "https" + client_params.update({"verify": str(self.device.ssl.cert)}) + log.debug( + ( + f"Using {str(self.device.ssl.cert)} to validate connection " + f"to {self.device.name}" + ) + ) + else: + http_protocol = "http" + endpoint = "{protocol}://{address}:{port}/query/".format( + protocol=http_protocol, address=self.device.address, port=self.device.port ) - log.debug(f"HTTP Headers: {headers}") log.debug(f"URL endpoint: {endpoint}") try: - async with httpx.Client() as http_client: + async with httpx.Client(**client_params) as http_client: responses = [] + for query in self.query: encoded_query = await jwt_encode( payload=query, @@ -244,11 +256,9 @@ class Connect: duration=params.general.request_timeout, ) log.debug(f"Encoded JWT: {encoded_query}") + raw_response = await http_client.post( - endpoint, - headers=headers, - json={"encoded": encoded_query}, - timeout=params.general.request_timeout, + endpoint, json={"encoded": encoded_query} ) log.debug(f"HTTP status code: {raw_response.status_code}") @@ -278,7 +288,8 @@ class Connect: device_name=self.device.display_name, error=rest_msg, ) - except OSError: + except OSError as ose: + log.critical(str(ose)) raise RestError( params.messages.connection_error, device_name=self.device.display_name, diff --git a/hyperglass/configuration/models/ssl.py b/hyperglass/configuration/models/ssl.py new file mode 100644 index 0000000..16a8794 --- /dev/null +++ b/hyperglass/configuration/models/ssl.py @@ -0,0 +1,15 @@ +"""Validate SSL configuration variables.""" + +# Third Party Imports +from pydantic import FilePath +from pydantic import StrictBool + +# Project Imports +from hyperglass.configuration.models._utils import HyperglassModel + + +class Ssl(HyperglassModel): + """Validate SSL config parameters.""" + + enable: StrictBool = True + cert: FilePath