Introduction
On previous post testing was done to push ACL to Cisco ASA with static information, however in production preparing static information directly to the run method of Nornir is not practical, if the information is passed as a dictionary through API gateway the payload will have to be passed to the add_acl
function.
So there is a modification of the code to make the code more practical.
Modification to the original code and template
This is a testing code to accept dynamic payload and nornir uses jinja2 template to render the commands and push the ACL commands directly to Cisco ASA with netmiko.
Keyword argument is added to the original add_acl
.
def add_acl(task, **kwargs): cmd = task.run(task=template_file, name="Generating template", template="asa_acl.j2", path="./templates/", acl_attr=kwargs ) task.host["config"] = cmd.result task.run(task=netmiko_send_config, name="Sending configuration", config_commands=task.host["config"]) task.run(task=netmiko_save_config, name="Saving configuration", cmd="write memory")
Modification of the template as follows:
{% if acl_attr.line_number is defined %} access-list {{ acl_attr.acl_name }} line {{acl_attr.line_number}} extended {{acl_attr.action}} {{acl_attr.protocol}} {{acl_attr.src_fw_object_type}} {{acl_attr.src_object}} {{acl_attr.dst_fw_object_type}} {{acl_attr.dst_object}} {{acl_attr.svc_object_group_type}} {{acl_attr.svc_object_group}} log {% else %} access-list {{acl_attr.acl_name}} extended {{acl_attr.action}} {{acl_attr.protocol}} {{acl_attr.src_fw_object_type}} {{acl_attr.src_object}} {{acl_attr.dst_fw_object_type}} {{acl_attr.dst_object}} {{acl_attr.svc_object_group_type}} {{acl_attr.svc_object_group}} log {% endif %}
You can study the jinja2 documentation to understand how to pass in dictionary values.
Entire code for testing
from nornir import InitNornir from nornir.plugins.tasks.networking import netmiko_send_config, netmiko_save_config from nornir.plugins.tasks.text import template_file from nornir.plugins.functions.text import print_result from pyvault2.vault.hvault2 import get_kv2_secret """ The credential_from_vault function can be found here: https://github.com/sirbowen78/pyvault2/blob/master/vault/hvault2.py """ credential_from_vault = get_kv2_secret(mount_path="cisco_asa", path="fw01", find="data") """ Reference: https://nornir.readthedocs.io/en/stable/tutorials/intro/grouping_tasks.html """ def change_host_data(host): host.username = credential_from_vault["username"] host.password = credential_from_vault["password"] host.hostname = credential_from_vault["ip"] host.platform = "cisco_asa" def add_acl(task, **kwargs): cmd = task.run(task=template_file, name="Generating template", template="asa_acl.j2", path="./templates/", acl_attr=kwargs ) task.host["config"] = cmd.result task.run(task=netmiko_send_config, name="Sending configuration", config_commands=task.host["config"]) task.run(task=netmiko_save_config, name="Saving configuration", cmd="write memory") nr = InitNornir( inventory={ "plugin": "nornir.plugins.inventory.simple.SimpleInventory", "options": { "host_file": "templates/hosts.yaml" }, "transform_function": change_host_data } ) payload = { "acl_name": "abc", "action": "deny", "protocol": "tcp", "src_fw_object_type": "host", "src_object": "192.168.1.122", "dst_fw_object_type": "host", "dst_object": "172.16.1.1", "svc_object_group_type": "eq", "svc_object_group": "65000" } r = nr.run(task=add_acl, **payload) print_result(r)
Demonstration
Insert a deny rule.
payload = { "acl_name": "abc", "action": "deny", "protocol": "tcp", "src_fw_object_type": "host", "src_object": "10.168.10.200", "dst_fw_object_type": "host", "dst_object": "192.168.100.100", "svc_object_group_type": "eq", "svc_object_group": "8443" } r = nr.run(task=add_acl, **payload) print_result(r)
Insert a deny rule to the top of the entire acl:
payload = { "acl_name": "abc", "action": "deny", "line_number": "1", "protocol": "tcp", "src_fw_object_type": "host", "src_object": "10.1.10.200", "dst_fw_object_type": "host", "dst_object": "172.32.100.100", "svc_object_group_type": "eq", "svc_object_group": "443" }