Starting in version 2.0, hyperglass supports custom plugins. There are two main types of plugins: - **Input Plugins**: Apply custom validation logic to or transform user input before the query is sent to a device. - **Output Plugins**: Interact with the output from a device before it's displayed to the user. Plugins are associated with a directive. ## Examples ### Input Plugins #### Convert a CIDR Prefix to Network and Mask In this example, the following query is sent to hyperglass: ```json { "query_target": "192.0.2.0/24", "query_location": "your_location", "query_type": "ip_route_directive" } ``` The below plugin is defined and referenced by a directive: ```python filename="/path/to/your/transform_plugin.py" from ipaddress import ip_network from hyperglass.plugins import InputPlugin class TransformCIDR(InputPlugin): def transform(self, query): (target := query.query_target) target_network = ip_network(target) if target_network.version == 4: return f"{target_network.network_address!s} {target_network.netmask!s}" return target ``` ```yaml filename="directives.yaml" ip_route_directive: name: IP Route plugins: - '/path/to/your/transform_plugin.py' rules: - condition: '0.0.0.0/0' action: permit command: 'show ip route {target}' - condition: '::/0' action: permit command: 'show ipv6 route {target}' ``` When the query is received, the query target is transformed, resulting in this being sent to the device: ``` show ip route 192.0.2.0 255.255.255.0 ``` instead of: ``` show ip route 192.0.2.0/24 ``` #### Validate User Input In this example, we want to perform some custom validation not available via the directives `condition` API. For instance, say you wanted to ensure a query target isn't contained within a dynamic list of [bogon prefixes from Team Cymru](https://www.team-cymru.com/bogon-networks). ```python filename="/path/to/your/validation_plugin.py" from ipaddress import ip_network from hyperglass.plugins import InputPlugin from hyperglass.external import HTTPClient class BogonPlugin(InputPlugin): def validate(self, query): target = ip_network(query.query_target) with HTTPClient(base_url="https://team-cymru.org") as client: response = client.get("/Services/Bogons/fullbogons-ipv4.txt") bogon_strings = [line.strip() for line in response.text.split("\n") if not line.startswith("#")] bogons = [ip_network(bogon) for bogon in bogon_strings] for bogon in bogons: if target in bogon or target == bogon: return False # Return false to fail validation. return True ``` This isn't the best real-world example, since the above plugin would be run on every request, likely resulting in slow query responses, but it illustrates the power of plugins. ### Output Plugins #### Redact Sensitive Information Say one of your directives might show some sensitive information in the query output. Using an output plugin, we can replace any text matching a pattern (or multiple patterns) with some other text. ```python import re from hyperglass.plugins import OutputPlugin SENSITIVE_PATTERN = re.compile("SuperSecretInfo") class Redact(OutputPlugin): def process(self, output, query): result = [] for each_output in output: redacted = SENSITIVE_PATTERN.sub("", each_output) result.append(redacted) return result ``` If the query output was: ``` Lorem ipsum dolor sit amet, SuperSecretInfo consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Viverra suspendisse potenti nullam ac. At elementum eu facilisis sed odio morbi. SuperSecretInfo iaculis urna id volutpat lacus.Nisl nisi scelerisque eu ultrices vitae. Accumsan SuperSecretInfo tortor posuere ac ut consequat semper viverra nam libero. Libero id faucibus nisl tincidunt eget nullam non nisi. Et ligula ullamcorper malesuada SuperSecretInfo proin libero nunc. Et malesuada fames ac turpis egestas sed. Nulla facilisi cras fermentum odio eu. SuperSecretInfo condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Nisl rhoncus mattis rhoncus urna neque. Tortor aliquam nulla facilisi cras SuperSecretInfo fermentum odio eu feugiat. Neque egestas congue quisque egestas diam in arcu cursus SuperSecretInfo. ``` The above plugin would transform the output to: ``` Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Viverra suspendisse potenti nullam ac. At elementum eu facilisis sed odio morbi. iaculis urna id volutpat lacus.Nisl nisi scelerisque eu ultrices vitae. Accumsan tortor posuere ac ut consequat semper viverra nam libero. Libero id faucibus nisl tincidunt eget nullam non nisi. Et ligula ullamcorper malesuada proin libero nunc. Et malesuada fames ac turpis egestas sed. Nulla facilisi cras fermentum odio eu. condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Nisl rhoncus mattis rhoncus urna neque. Tortor aliquam nulla facilisi cras fermentum odio eu feugiat. Neque egestas congue quisque egestas diam in arcu cursus . ```