Repository: napalm-automation/napalm

Issue:
get_mac_address_table() fails on juniper SRX300 series devices
Relevant part of the traceback:

```
....
  File "/tmp/.venv/lib/python3.6/site-packages/napalm/junos/junos.py", line 1565, in get_mac_address_table
    mac_table.get()
  File "/tmp/.venv/lib/python3.6/site-packages/jnpr/junos/factory/optable.py", line 64, in get
    self.xml = getattr(self.RPC, self.GET_RPC)(**rpc_args)
  File "/tmp/.venv/lib/python3.6/site-packages/jnpr/junos/rpcmeta.py", line 345, in _exec_rpc
    return self._junos.execute(rpc, **dec_args)
  File "/tmp/.venv/lib/python3.6/site-packages/jnpr/junos/decorators.py", line 63, in wrapper
    result = function(*args, **kwargs)
  File "/tmp/.venv/lib/python3.6/site-packages/jnpr/junos/decorators.py", line 31, in wrapper
    return function(*args, **kwargs)
  File "/tmp/.venv/lib/python3.6/site-packages/jnpr/junos/device.py", line 794, in execute
    errs=ex)
jnpr.junos.exception.RpcError: RpcError(severity: error, bad_element: get-bridge-mac-table, message: error: syntax error
error: syntax error)
```


Discussion:

Resolving patch:
diff --git a/napalm/junos/junos.py b/napalm/junos/junos.py
--- a/napalm/junos/junos.py
+++ b/napalm/junos/junos.py
@@ -1547,19 +1547,24 @@ def get_mac_address_table(self):
         """Return the MAC address table."""
         mac_address_table = []
 
-        if self.device.facts.get("personality", "") in [
-            "SWITCH"
-        ]:  # for EX & QFX devices
-            if self.device.facts.get("switch_style", "") in [
-                "VLAN_L2NG"
-            ]:  # for L2NG devices
-                mac_table = junos_views.junos_mac_address_table_switch_l2ng(self.device)
-            else:
-                mac_table = junos_views.junos_mac_address_table_switch(self.device)
-        else:
+        switch_style = self.device.facts.get("switch_style", "")
+        if switch_style == "VLAN_L2NG":
+            mac_table = junos_views.junos_mac_address_table_switch_l2ng(self.device)
+        elif switch_style == "BRIDGE_DOMAIN":
             mac_table = junos_views.junos_mac_address_table(self.device)
+        else:  # switch_style == "VLAN"
+            mac_table = junos_views.junos_mac_address_table_switch(self.device)
+
+        try:
+            mac_table.get()
+        except RpcError as e:
+            # Device hasn't got it's l2 subsystem running
+            # Don't error but just return an empty result
+            if "l2-learning subsystem" in e.message:
+                return []
+            else:
+                raise
 
-        mac_table.get()
         mac_table_items = mac_table.items()
 
         default_values = {


Test patch:
diff --git a/test/junos/mocked_data/test_get_mac_address_table/normal/expected_result.json b/test/junos/mocked_data/test_get_mac_address_table/bridge_domain/expected_result.json
similarity index 100%
rename from test/junos/mocked_data/test_get_mac_address_table/normal/expected_result.json
rename to test/junos/mocked_data/test_get_mac_address_table/bridge_domain/expected_result.json
diff --git a/test/junos/mocked_data/test_get_mac_address_table/bridge_domain/facts.yml b/test/junos/mocked_data/test_get_mac_address_table/bridge_domain/facts.yml
new file mode 100644
--- /dev/null
+++ b/test/junos/mocked_data/test_get_mac_address_table/bridge_domain/facts.yml
@@ -0,0 +1,2 @@
+personality: MX
+switch_style: BRIDGE_DOMAIN
diff --git a/test/junos/mocked_data/test_get_mac_address_table/normal/get-bridge-mac-table.xml b/test/junos/mocked_data/test_get_mac_address_table/bridge_domain/get-bridge-mac-table.xml
similarity index 100%
rename from test/junos/mocked_data/test_get_mac_address_table/normal/get-bridge-mac-table.xml
rename to test/junos/mocked_data/test_get_mac_address_table/bridge_domain/get-bridge-mac-table.xml
diff --git a/test/junos/mocked_data/test_get_mac_address_table/normal/facts.yml b/test/junos/mocked_data/test_get_mac_address_table/normal/facts.yml
deleted file mode 100644
--- a/test/junos/mocked_data/test_get_mac_address_table/normal/facts.yml
+++ /dev/null
@@ -1 +0,0 @@
-personality: MX
diff --git a/test/junos/mocked_data/test_get_mac_address_table/vlan/expected_result.json b/test/junos/mocked_data/test_get_mac_address_table/vlan/expected_result.json
new file mode 100644
--- /dev/null
+++ b/test/junos/mocked_data/test_get_mac_address_table/vlan/expected_result.json
@@ -0,0 +1,20 @@
+[
+  {
+    "interface": "ge-0/0/0.0",
+    "moves": 0,
+    "vlan": 1,
+    "mac": "EC:13:DB:2D:35:DA",
+    "static": false,
+    "last_move": 0,
+    "active": true
+  },
+  {
+    "interface": "ge-0/0/0.0",
+    "moves": 0,
+    "vlan": 9,
+    "mac": "88:5B:DD:3F:3F:80",
+    "static": false,
+    "last_move": 0,
+    "active": true
+  }
+]
diff --git a/test/junos/mocked_data/test_get_mac_address_table/vlan/facts.yml b/test/junos/mocked_data/test_get_mac_address_table/vlan/facts.yml
new file mode 100644
--- /dev/null
+++ b/test/junos/mocked_data/test_get_mac_address_table/vlan/facts.yml
@@ -0,0 +1,2 @@
+personality: SWITCH
+switch_style: VLAN
diff --git a/test/junos/mocked_data/test_get_mac_address_table/vlan/get-ethernet-switching-table-information.xml b/test/junos/mocked_data/test_get_mac_address_table/vlan/get-ethernet-switching-table-information.xml
new file mode 100644
--- /dev/null
+++ b/test/junos/mocked_data/test_get_mac_address_table/vlan/get-ethernet-switching-table-information.xml
@@ -0,0 +1,47 @@
+<ethernet-switching-table-information style="extensive">
+    <ethernet-switching-table style="extensive">
+        <mac-table-count>18</mac-table-count>
+        <mac-table-learned>15</mac-table-learned>
+        <mac-table-persistent>0</mac-table-persistent>
+        <mac-table-entry style="extensive">
+            <mac-vlan>default</mac-vlan>
+            <mac-vlan-tag>1</mac-vlan-tag>
+            <mac-address>*</mac-address>
+            <mac-interface>All-members</mac-interface>
+            <mac-interfaces-list style="flood-list">
+                <mac-interfaces>ge-0/0/0.0</mac-interfaces>
+            </mac-interfaces-list>
+            <mac-type>Flood</mac-type>
+            <mac-action>Forward</mac-action>
+            <mac-nexthop>1355</mac-nexthop>
+        </mac-table-entry>
+        <mac-table-entry style="extensive">
+            <mac-vlan>default</mac-vlan>
+            <mac-vlan-tag>1</mac-vlan-tag>
+            <mac-address>ec:13:db:2d:35:da</mac-address>
+            <mac-interface>ge-0/0/0.0</mac-interface>
+            <mac-interfaces-list>
+                <mac-interfaces>ge-0/0/0.0</mac-interfaces>
+            </mac-interfaces-list>
+            <mac-type>Learn</mac-type>
+            <mac-age seconds="0">0</mac-age>
+            <mac-learned-time seconds="902535">1w3d 10:42:15</mac-learned-time>
+            <mac-action>Forward</mac-action>
+            <mac-nexthop>1354</mac-nexthop>
+        </mac-table-entry>
+        <mac-table-entry style="extensive">
+            <mac-vlan>vlan9</mac-vlan>
+            <mac-vlan-tag>9</mac-vlan-tag>
+            <mac-address>88:5b:dd:3f:3f:80</mac-address>
+            <mac-interface>ge-0/0/0.0</mac-interface>
+            <mac-interfaces-list>
+                <mac-interfaces>ge-0/0/0.0</mac-interfaces>
+            </mac-interfaces-list>
+            <mac-type>Learn</mac-type>
+            <mac-age seconds="0">0</mac-age>
+            <mac-learned-time seconds="902533">1w3d 10:42:13</mac-learned-time>
+            <mac-action>Forward</mac-action>
+            <mac-nexthop>1354</mac-nexthop>
+        </mac-table-entry>
+    </ethernet-switching-table>
+</ethernet-switching-table-information>
diff --git a/test/junos/mocked_data/test_get_mac_address_table/l2ng/expected_result.json b/test/junos/mocked_data/test_get_mac_address_table/vlan_l2ng/expected_result.json
similarity index 100%
rename from test/junos/mocked_data/test_get_mac_address_table/l2ng/expected_result.json
rename to test/junos/mocked_data/test_get_mac_address_table/vlan_l2ng/expected_result.json
diff --git a/test/junos/mocked_data/test_get_mac_address_table/l2ng/facts.yml b/test/junos/mocked_data/test_get_mac_address_table/vlan_l2ng/facts.yml
similarity index 100%
rename from test/junos/mocked_data/test_get_mac_address_table/l2ng/facts.yml
rename to test/junos/mocked_data/test_get_mac_address_table/vlan_l2ng/facts.yml
diff --git a/test/junos/mocked_data/test_get_mac_address_table/l2ng/get-ethernet-switching-table-information.xml b/test/junos/mocked_data/test_get_mac_address_table/vlan_l2ng/get-ethernet-switching-table-information.xml
similarity index 100%
rename from test/junos/mocked_data/test_get_mac_address_table/l2ng/get-ethernet-switching-table-information.xml
rename to test/junos/mocked_data/test_get_mac_address_table/vlan_l2ng/get-ethernet-switching-table-information.xml