Category
Collection Namespace & Version
| Field |
Value |
| Collection namespace |
juniper.device |
| Collection version |
2.0.2 |
| Collection install path |
/home/jcluser/.ansible/collections/ansible_collection |
# How to find it:
ansible-galaxy collection list | grep -E 'juniper|junipernetworks'
Module / Plugin Details
| Field |
Value |
| Module / plugin name |
juniper.device.junos_facts |
| Module version (if shown in output) |
|
| Plugin type |
module |
# How to inspect module documentation:
ansible-doc juniper.device.config
Description
The juniper.device.junos_facts module does not populate the acl_interfaces network resource when a Junos firewall filter is attached to an interface using the standard input or output configuration hierarchy.
The Junos acl_interfaces fact parser currently searches for firewall filter attachments under:
["input-list", "output-list"]
However, for a standard interface firewall filter attachment, Junos returns the filter under:
<input>
<filter-name>ACL-FACT-TEST</filter-name>
</input>
or:
<output>
<filter-name>ACL-FACT-TEST</filter-name>
</output>
As a result, the parser does not find the configured ACL attachment and ansible_network_resources does not populate acl_interfaces.
After changing the parser to process input and output, a second issue is exposed: he ACL is discovered, but Junos returns the ACL name as a dictionary:
{"filter-name": "ACL-FACT-TEST"}
The collector currently stores this entire dictionary as the ACL name:
name: "{'filter-name': 'ACL-FACT-TEST'}"
Instead, it should extract the value of filter-name and store:
name: ACL-FACT-TEST
Therefore, both the changes are required
Inventory File (sanitized)
[junos_devices]
device1 ansible_host=<redacted-ip>
[junos_devices:vars]
ansible_connection=netconf # or juniper.device, ansible.netcommon.netconf
ansible_network_os=junipernetworks.junos.junos # or juniper.device
ansible_user=<redacted>
ansible_ssh_pass=<redacted>
ansible_port=830
all:
hosts:
vendor_qfx:
ansible_host: xx.xx.xx.xx
ansible_user: "xyz"
ansible_password: <xyz>
ansible_port: 830
ansible_connection: ansible.netcommon.netconf
ansible_network_os: juniper.device.junos
Playbook Details
---
- name: Test Junos ACL interface facts
hosts: junos
gather_facts: false
tasks:
- name: Gather Junos ACL interface facts
juniper.device.junos_facts:
gather_subset:
- min
gather_network_resources:
- acl_interfaces
- name: Display gathered network resources
ansible.builtin.debug:
var: ansible_facts.network_resources
ansible-playbook -i inventory.ini test_acl_facts.yml -vvv
Steps to Reproduce
- Install or use the
juniper.device collection.
ansible-galaxy collection install juniper.device
- Configure a Junos firewall filter as an input filter on an interface.
set interfaces xe-0/0/7 unit 0 family inet filter input ACL-FACT-TEST
<interface>
<name>xe-0/0/7</name>
<unit>
<name>0</name>
<family>
<inet>
<filter>
<input>
<filter-name>ACL-FACT-TEST</filter-name>
</input>
</filter>
</inet>
</family>
</unit>
</interface>
-
Create the inventory file using NETCONF connectivity.
-
Run the supplied playbook.
ansible-playbook -i inventory.ini test_acl_facts.yml -vvv
- Observe that
ansible_facts.network_resources is empty even though the interface has an attached firewall filter.
Expected Behavior
The module should populate the interface ACL attachment (acl_interfaces) under ansible_network_resources:
"ansible_facts": {
"ansible_net_api": "netconf",
"ansible_net_gather_network_resources": [
"acl_interfaces"
],
"ansible_net_gather_subset": [
"default"
],
"ansible_net_hostname": "dc1-borderleaf2",
"ansible_net_model": "vqfx-10000",
"ansible_net_python_version": "3.9.19",
"ansible_net_serialnum": "62521362500",
"ansible_net_system": "junos",
"ansible_net_version": "18.1R3-S5.3",
"ansible_network_resources": {
"acl_interfaces": [
{
"access_groups": [
{
"acls": [
{
"direction": "in",
"name": "ACL-FACT-TEST"
}
],
"afi": "ipv4"
}
],
"name": "xe-0/0/7"
}
],
"junos_acl_interfaces": [
{
"access_groups": [
{
"acls": [
{
"direction": "in",
"name": "ACL-FACT-TEST"
}
],
"afi": "ipv4"
}
],
"name": "xe-0/0/7"
}
]
}
}
or
ansible_network_resources:
acl_interfaces:
- name: xe-0/0/7
access_groups:
- afi: ipv4
acls:
- name: ACL-FACT-TEST
direction: in
additionally junos_acl_interfaces should also get populated
ansible_network_resources:
junos_acl_interfaces:
- name: xe-0/0/7
access_groups:
- afi: ipv4
acls:
- name: ACL-FACT-TEST
direction: in
Actual Behavior
The module completes successfully but does not populate acl_interfaces and junos_acl_interfaces resource:
"ansible_facts": {
"ansible_net_api": "netconf",
"ansible_net_gather_network_resources": [
"acl_interfaces"
],
"ansible_net_gather_subset": [
"default"
],
"ansible_net_hostname": "dc1-borderleaf2",
"ansible_net_model": "vqfx-10000",
"ansible_net_python_version": "3.9.19",
"ansible_net_serialnum": "62521362500",
"ansible_net_system": "junos",
"ansible_net_version": "18.1R3-S5.3",
"ansible_network_resources": {}
},
"changed": false,
"invocation": {
"module_args": {
"available_network_resources": false,
"config_format": "text",
"gather_network_resources": [
"acl_interfaces"
],
"gather_subset": [
"min"
]
}
}
configured interface ACL attachment is silently skipped.
Environment
Ansible & Python
| Item |
Version |
| ansible-core |
2.15.13] |
| Python |
3.9.19 |
| OS |
Linux nita 5.14.0-503.14.1.el9_5.x86_64 |
Collection & Python Package Versions
ansible-galaxy collection list | grep -E 'juniper|junipernetworks'
pip show junos-eznc ncclient paramiko lxml
# ansible-galaxy collection list output:
juniper.device 2.0.2
junipernetworks.junos 5.3.1
# pip show output:
junos-eznc : 2.8.2
ncclient : 0.7.0
paramiko : 5.0.0
lxml : 6.1.1
Junos Device
| Item |
Value |
| Junos version |
18.1R3-S5.3 |
| Junos platform / model |
vQFX-10000 |
| Transport |
NETCONF over SSH |
| NETCONF port |
830 |
Junos RPC / XML (if applicable)
<!-- RPC request -->
<!-- RPC response / error -->
Additional Context
Proposed Fix
Change 1: Process input and output
Change from:
for direction in ["input-list", "output-list"]:
rendered_direction = "in" if direction == "input-list" else "out"
to:
for direction in ["input", "output"]:
rendered_direction = "in" if direction == "input" else "out"
Change 2: Extract the ACL Name
Change from
for filter_name in acl_name:
access_groups["acls"].append(
{
"name": filter_name,
"direction": rendered_direction,
},
)
to:
for filter_name in acl_name:
if isinstance(filter_name, dict):
filter_name = filter_name.get("filter-name")
access_groups["acls"].append(
{
"name": filter_name,
"direction": rendered_direction,
},
)
The modified parser section is:
for direction in ["input", "output"]:
rendered_direction = "in" if direction == "input" else "out"
if conf["interface"]["unit"]["family"][family]["filter"].get(direction):
acl_name = conf["interface"]["unit"]["family"][family]["filter"][
direction
]
if not isinstance(acl_name, list):
acl_name = [acl_name]
for filter_name in acl_name:
if isinstance(filter_name, dict):
filter_name = filter_name.get("filter-name")
access_groups["acls"].append(
{
"name": filter_name,
"direction": rendered_direction,
},
)
Support
As Red Hat Ansible Certified Content, this collection is entitled to support through the Ansible Automation Platform (AAP) using the Create issue button on the top right corner of the AAP support portal.
If a support case cannot be opened with Red Hat and the collection has been obtained either from Galaxy or GitHub, there may be community help available on the Ansible Forum.
Category
Collection Namespace & Version
Module / Plugin Details
# How to inspect module documentation: ansible-doc juniper.device.configDescription
The
juniper.device.junos_factsmodule does not populate theacl_interfacesnetwork resource when a Junos firewall filter is attached to an interface using the standardinputoroutputconfiguration hierarchy.The Junos
acl_interfacesfact parser currently searches for firewall filter attachments under:However, for a standard interface firewall filter attachment, Junos returns the filter under:
or:
As a result, the parser does not find the configured ACL attachment and
ansible_network_resourcesdoes not populate acl_interfaces.After changing the parser to process
inputandoutput, a second issue is exposed: he ACL is discovered, but Junos returns the ACL name as a dictionary:{"filter-name": "ACL-FACT-TEST"}
The collector currently stores this entire dictionary as the ACL name:
name: "{'filter-name': 'ACL-FACT-TEST'}"
Instead, it should extract the value of filter-name and store:
name: ACL-FACT-TEST
Therefore, both the changes are required
Inventory File (sanitized)
Playbook Details
Steps to Reproduce
juniper.devicecollection.Create the inventory file using NETCONF connectivity.
Run the supplied playbook.
ansible_facts.network_resourcesis empty even though the interface has an attached firewall filter.Expected Behavior
The module should populate the interface ACL attachment (acl_interfaces) under ansible_network_resources:
or
additionally junos_acl_interfaces should also get populated
Actual Behavior
The module completes successfully but does not populate acl_interfaces and junos_acl_interfaces resource:
configured interface ACL attachment is silently skipped.
Environment
Ansible & Python
Collection & Python Package Versions
Junos Device
Junos RPC / XML (if applicable)
Additional Context
Proposed Fix
Change 1: Process
inputandoutputChange from:
to:
Change 2: Extract the ACL Name
Change from
to:
The modified parser section is:
Support
As Red Hat Ansible Certified Content, this collection is entitled to support through the Ansible Automation Platform (AAP) using the Create issue button on the top right corner of the AAP support portal.
If a support case cannot be opened with Red Hat and the collection has been obtained either from Galaxy or GitHub, there may be community help available on the Ansible Forum.