Skip to content

Commit

Permalink
Merge pull request #9 from wwt/mqtt
Browse files Browse the repository at this point in the history
added fixes for certificate handling
  • Loading branch information
nsthompson authored Aug 16, 2023
2 parents 1c0cec7 + dd50016 commit 215e22c
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 28 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ Fixed certificate path handling when calling wwt.eda.mqtt from EDA server
## v1.0.4

Added additional logging to wwt.eda.mqtt plugin.

## v1.0.5

Fixed certificate handling with wwt.eda.mqtt to account for EDA server file limitations.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ A sample rulebook using *wwt.eda.mqtt* plugin is shown below:
port: 8883
username: <username>
password: <password>
cert_path: <cert directory name>
ca_certs: <cert-filename>
ca_certs: |-
-----BEGIN CERTIFICATE-----
<cert contents>
-----END CERTIFICATE-----
validate_certs: false
topic: meraki/v1/mt/#
filters:
Expand Down
55 changes: 30 additions & 25 deletions extensions/eda/plugins/event_source/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
port: The port where the mqtt server is listening
username: The username to connect to the broker
password: The password to connect to the broker
cert_path: The directory containing certificate files.
Can be in root of repo or under rulebooks.
ca_certs: The filename of optional certificate authority file containing
ca_certs: Multi-line string containing
certificate used to sign mqtt broker certificates
validate_certs: Disable certificate validation - true/false
certfile: The optional client certificate file name containing
certfile: The optional multi-line string containing
the client certificate, as well as CA certificates needed
to establish the certificate's authenticity
keyfile: The optional client key file name containing the client
keyfile: Multi-line string containing the client
private key
keyfile_password: The optional password to be used when loading the
certificate chain
Expand All @@ -25,12 +23,24 @@
import asyncio
import json
import logging
import os
from typing import Any, Dict

import aiomqtt


async def write_certfile(path, content, logger):
"""
Function to write certificate data to a temporary file.
Args:
path (str): Path to temporary file
content (str): Certificate data
logger (object): Logger object
"""
with open(path, "w+", encoding='utf-8') as certfile:
certfile.writelines(content)
logger.info("Cert data written to %s", path)

async def main(queue: asyncio.Queue, args: Dict[str, Any]):
logger = logging.getLogger()

Expand All @@ -41,41 +51,36 @@ async def main(queue: asyncio.Queue, args: Dict[str, Any]):
username = args.get("username")
password = args.get("password")

cert_path = args.get("cert_path")
ca_certs = args.get("ca_certs")
validate_certs = bool(args.get("validate_certs"))
certfile = args.get("certfile")
keyfile = args.get("keyfile")
keyfile_password = args.get("keyfile_password")

# Path management for certificate files
# This solves an issue when using EDA server and finding file paths
path_to_certs = None
# EDA Server does not support file handling with decision environments
# We will accept the cert data as strings and write out temporary files
# to pass when configuring TLS.
path_to_certs = "/tmp"
ca_certs_path = None
certfile_path = None
keyfile_path = None

if cert_path:
# Find the absolute path to the ca_certs filename
for root, dirs, _ in os.walk('./', topdown=True):
for dirname in dirs:
if cert_path in dirname:
path_to_certs = os.path.join(root, dirname)
logger.info("Cert path found at %s", path_to_certs)
break

# Build out cert file absolute paths
# Build out cert file and absolute paths
if ca_certs and path_to_certs:
ca_certs_path = f'{path_to_certs}/{ca_certs}'
logger.info("ca_certs path found at %s", ca_certs_path)
# Write Certificate to file
ca_certs_path = f'{path_to_certs}/ca_certs.crt'
await write_certfile(ca_certs_path, ca_certs, logger)

if certfile and path_to_certs:
certfile_path = f'{path_to_certs}/{certfile}'
logger.info("certfile path found at %s", certfile_path)
# Write Certificate to file
certfile_path = f'{path_to_certs}/certfile.crt'
await write_certfile(certfile_path, certfile, logger)

if keyfile and path_to_certs:
keyfile_path = f'{path_to_certs}/{keyfile}'
logger.info("keyfile path found at %s", keyfile_path)
# Write Certificate to file
keyfile_path = f'{path_to_certs}/keyfile.crt'
await write_certfile(keyfile_path, keyfile, logger)

if ca_certs_path or certfile_path or keyfile_path:
logger.info("Certificates provided, setting tls_params...")
Expand Down
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
namespace: wwt
name: eda
version: 1.0.4
version: 1.0.5
readme: README.md
authors:
- Nick Thompson <[email protected]>
Expand Down

0 comments on commit 215e22c

Please sign in to comment.