diff --git a/docs/developers/writing_profiles.rst b/docs/developers/writing_profiles.rst index 551bb4a8..9a46ab39 100644 --- a/docs/developers/writing_profiles.rst +++ b/docs/developers/writing_profiles.rst @@ -57,6 +57,12 @@ In this case we are using the ``XMLParser`` parser. In order to get the data we device we have to call the method ``_rpc`` with the ``args`` and ``kwargs`` parameters. This is, by the way, an RPC call for a junos device. +**Note:** If a model is called by other models, like openconfig-if-ethernet is called by openconfig-interfaces, +there is no need to specify the execute section in the metadata, if the commands will be the same. +Since the first model executes the commands, the data from the commands will be shared with the +models that the first model calls. While it will work it to specify the same commands in the metadata +section for the second model, it could cause the commands to be executed multiple times. + * **vlan** - This is the part that follows the model specification. In this case is ``vlan`` but in others it might be ``interfaces``, ``addressess`` or something else, this will be model dependent but it's basically whatever it's not ``metadata``. This part will follow the model specification diff --git a/napalm_yang/jinja_filters/__init__.py b/napalm_yang/jinja_filters/__init__.py index 500eccb7..6805ae02 100644 --- a/napalm_yang/jinja_filters/__init__.py +++ b/napalm_yang/jinja_filters/__init__.py @@ -1,11 +1,13 @@ import ip_filters import json_filters import vlan_filters +import mac_filters JINJA_FILTERS = [ ip_filters, json_filters, vlan_filters, + mac_filters, ] diff --git a/napalm_yang/jinja_filters/mac_filters.py b/napalm_yang/jinja_filters/mac_filters.py new file mode 100644 index 00000000..9b37199d --- /dev/null +++ b/napalm_yang/jinja_filters/mac_filters.py @@ -0,0 +1,23 @@ +from napalm_yang.jinja_filters.helpers import check_empty +import netaddr + + +def filters(): + return { + "dotted_mac_to_colon": dotted_mac_to_colon, + "colon_mac_to_dotted": colon_mac_to_dotted, + } + + +@check_empty() +def dotted_mac_to_colon(value): + mac = netaddr.EUI(value) + mac.dialect = netaddr.mac_unix_expanded + return str(mac) + + +@check_empty() +def colon_mac_to_dotted(value): + mac = netaddr.EUI(value) + mac.dialect = netaddr.mac_cisco + return str(mac) diff --git a/napalm_yang/mappings/eos/parsers/state/openconfig-if-ethernet/ethernet.yaml b/napalm_yang/mappings/eos/parsers/state/openconfig-if-ethernet/ethernet.yaml new file mode 100644 index 00000000..4ef7a85a --- /dev/null +++ b/napalm_yang/mappings/eos/parsers/state/openconfig-if-ethernet/ethernet.yaml @@ -0,0 +1,68 @@ +--- +metadata: + processor: JSONParser +ethernet: + _process: unnecessary + config: + _process: unnecessary + state: + _process: unnecessary + auto-negotiate: + _process: not_implemented + counters: + _process: + - path: interfaceCounters + in-8021q-frames: + _process: not_implemented + in-crc-errors: + _process: + - path: inputErrorsDetail.fcsErrors + in-fragment-frames: + _process: + - path: inputErrorsDetail.runtFrames + in-jabber-frames: + _process: not_implemented + in-mac-control-frames: + _process: not_implemented + in-mac-pause-frames: + _process: + - path: inputErrorsDetail.rxPause + in-oversize-frames: + _process: + - path: inputErrorsDetail.giantFrames + out-8021q-frames: + _process: not_implemented + out-mac-control-frames: + _process: not_implemented + out-mac-pause-frames: + _process: + - path: outputErrorsDetail.txPause + duplex-mode: + _process: + - path: duplex + # Note the value string is .lower() after the regex is parsed + # but before the map, hence the difference + regexp: "(?PduplexFull|duplexHalf)" + map: + duplexfull: FULL + duplexhalf: HALF + effective-speed: + _process: + # OC effective-speed units are Mbps + - path: bandwidth + regexp: "(?P\\d+)" + value: "{{ value / 1000 }}" + enable-flow-control: + _process: not_implemented + hw-mac-address: + _process: + - path: burnedInAddress + mac-address: + _process: + - path: physicalAddress + negotiated-duplex-mode: + _process: not_implemented + negotiated-port-speed: + _process: not_implemented + port-speed: + _process: not_implemented diff --git a/napalm_yang/mappings/nxos/parsers/state/openconfig-if-ethernet/ethernet.yaml b/napalm_yang/mappings/nxos/parsers/state/openconfig-if-ethernet/ethernet.yaml new file mode 100644 index 00000000..b563481d --- /dev/null +++ b/napalm_yang/mappings/nxos/parsers/state/openconfig-if-ethernet/ethernet.yaml @@ -0,0 +1,70 @@ +--- + +metadata: + processor: JSONParser +ethernet: + _process: unnecessary + config: + _process: not_implemented + state: + _process: unnecessary + auto-negotiate: + _process: not_implemented + counters: + _process: unnecessary + in-8021q-frames: + _process: not_implemented + in-crc-errors: + _process: + - path: eth_crc + in-fragment-frames: + _process: + - path: eth_runts + in-jabber-frames: + _process: not_implemented + in-mac-control-frames: + _process: not_implemented + in-mac-pause-frames: + _process: + - path: eth_inpause + in-oversize-frames: + _process: + - path: eth_jumbo_inpkts + out-8021q-frames: + _process: not_implemented + out-mac-control-frames: + _process: not_implemented + out-mac-pause-frames: + _process: + - path: eth_outpause + duplex-mode: + _process: not_implemented + effective-speed: + _process: + - path: eth_bw + regexp: "(?P\\d+)" + value: "{{ value / 1000 }}" + enable-flow-control: + _process: + - path: eth_in_flowctrl + map: + "off": false + "on": true + hw-mac-address: + _process: + - path: eth_bia_addr + regexp: "(?P\\S+)" + value: "{{ value | dotted_mac_to_colon }}" + when: "{{ interface_key[0:4] not in ['loop'] }}" + mac-address: + _process: + - path: eth_hw_addr + regexp: "(?P\\S+)" + value: "{{ value | dotted_mac_to_colon }}" + when: "{{ interface_key[0:4] not in ['loop'] }}" + negotiated-duplex-mode: + _process: not_implemented + negotiated-port-speed: + _process: not_implemented + port-speed: + _process: not_implemented diff --git a/test/integration/test_profiles.py b/test/integration/test_profiles.py index e3b7fa72..d859cd34 100644 --- a/test/integration/test_profiles.py +++ b/test/integration/test_profiles.py @@ -44,6 +44,7 @@ def pretty_json(dictionary): ["junos", "config", napalm_yang.models.openconfig_system, "default"], ["junos", "state", napalm_yang.models.openconfig_interfaces, "default"], ["nxos", "config", napalm_yang.models.openconfig_interfaces, "default"], + ["nxos", "state", napalm_yang.models.openconfig_interfaces, "default"], ] diff --git a/test/integration/test_profiles/eos/openconfig-interfaces/state/default/expected.json b/test/integration/test_profiles/eos/openconfig-interfaces/state/default/expected.json index 90adab40..8b79fe4e 100644 --- a/test/integration/test_profiles/eos/openconfig-interfaces/state/default/expected.json +++ b/test/integration/test_profiles/eos/openconfig-interfaces/state/default/expected.json @@ -2,6 +2,21 @@ "interfaces": { "interface": { "Ethernet1": { + "ethernet": { + "state": { + "counters": { + "in-crc-errors": 0, + "in-fragment-frames": 0, + "in-mac-pause-frames": 0, + "in-oversize-frames": 0, + "out-mac-pause-frames": 0 + }, + "duplex-mode": "FULL", + "effective-speed": 0, + "hw-mac-address": "08:00:27:76:17:76", + "mac-address": "08:00:27:76:17:76" + } + }, "name": "Ethernet1", "state": { "admin-status": "UP", @@ -28,6 +43,20 @@ } }, "Ethernet2": { + "ethernet": { + "state": { + "counters": { + "in-crc-errors": 0, + "in-fragment-frames": 0, + "in-mac-pause-frames": 0, + "in-oversize-frames": 0, + "out-mac-pause-frames": 0 + }, + "duplex-mode": "FULL", + "effective-speed": 0, + "mac-address": "08:00:27:78:47:29" + } + }, "name": "Ethernet2", "state": { "admin-status": "DOWN", @@ -78,6 +107,11 @@ } }, "Loopback1": { + "ethernet": { + "state": { + "effective-speed": 0 + } + }, "name": "Loopback1", "state": { "admin-status": "UP", @@ -90,6 +124,21 @@ } }, "Management1": { + "ethernet": { + "state": { + "counters": { + "in-crc-errors": 0, + "in-fragment-frames": 0, + "in-mac-pause-frames": 0, + "in-oversize-frames": 0, + "out-mac-pause-frames": 0 + }, + "duplex-mode": "FULL", + "effective-speed": 1000000, + "hw-mac-address": "08:00:27:7d:44:c1", + "mac-address": "08:00:27:7d:44:c1" + } + }, "name": "Management1", "state": { "admin-status": "UP", @@ -116,6 +165,12 @@ } }, "Port-Channel1": { + "ethernet": { + "state": { + "effective-speed": 0, + "mac-address": "08:00:27:78:47:29" + } + }, "name": "Port-Channel1", "state": { "admin-status": "UP", @@ -158,4 +213,3 @@ } } } - diff --git a/test/integration/test_profiles/nxos/openconfig-interfaces/state/default/expected.json b/test/integration/test_profiles/nxos/openconfig-interfaces/state/default/expected.json new file mode 100644 index 00000000..400d8a32 --- /dev/null +++ b/test/integration/test_profiles/nxos/openconfig-interfaces/state/default/expected.json @@ -0,0 +1,134 @@ +{ + "interfaces": { + "interface": { + "Ethernet1/1": { + "ethernet": { + "state": { + "counters": { + "in-crc-errors": 0, + "in-fragment-frames": 0, + "in-mac-pause-frames": 0, + "in-oversize-frames": 0, + "out-mac-pause-frames": 0 + }, + "effective-speed": 40000, + "enable-flow-control": false, + "hw-mac-address": "00:c8:8b:bd:de:e8", + "mac-address": "00:c8:8b:bd:de:e8" + } + }, + "name": "Ethernet1/1", + "state": { + "counters": { + "in-broadcast-pkts": 0, + "in-discards": 0, + "in-multicast-pkts": 1154731, + "in-octets": 261237940, + "out-broadcast-pkts": 0, + "out-discards": 0, + "out-multicast-pkts": 0, + "out-octets": 1109620799, + "out-unicast-pkts": 12701532 + }, + "oper-status": "UP" + } + }, + "Ethernet1/2": { + "ethernet": { + "state": { + "counters": { + "in-crc-errors": 0, + "in-fragment-frames": 0, + "in-mac-pause-frames": 0, + "in-oversize-frames": 0, + "out-mac-pause-frames": 0 + }, + "effective-speed": 10000, + "enable-flow-control": false, + "hw-mac-address": "00:c8:8b:bd:de:e9", + "mac-address": "00:c8:8b:bd:de:e9" + } + }, + "name": "Ethernet1/2", + "state": { + "counters": { + "in-broadcast-pkts": 0, + "in-discards": 0, + "in-multicast-pkts": 0, + "in-octets": 0, + "out-broadcast-pkts": 0, + "out-discards": 0, + "out-multicast-pkts": 0, + "out-octets": 0, + "out-unicast-pkts": 0 + }, + "oper-status": "DOWN" + } + }, + "Ethernet1/3": { + "ethernet": { + "state": { + "counters": { + "in-crc-errors": 0, + "in-fragment-frames": 0, + "in-mac-pause-frames": 0, + "in-oversize-frames": 0, + "out-mac-pause-frames": 0 + }, + "effective-speed": 10000, + "enable-flow-control": false, + "hw-mac-address": "00:c8:8b:bd:de:ea", + "mac-address": "00:c8:8b:bd:de:ea" + } + }, + "name": "Ethernet1/3", + "state": { + "counters": { + "in-broadcast-pkts": 0, + "in-discards": 0, + "in-multicast-pkts": 0, + "in-octets": 0, + "out-broadcast-pkts": 0, + "out-discards": 0, + "out-multicast-pkts": 0, + "out-octets": 0, + "out-unicast-pkts": 0 + }, + "oper-status": "DOWN" + } + }, + "Ethernet1/4": { + "ethernet": { + "state": { + "counters": { + "in-crc-errors": 0, + "in-fragment-frames": 0, + "in-mac-pause-frames": 0, + "in-oversize-frames": 0, + "out-mac-pause-frames": 0 + }, + "effective-speed": 10000, + "enable-flow-control": false, + "hw-mac-address": "00:c8:8b:bd:de:eb", + "mac-address": "00:c8:8b:bd:de:eb" + } + }, + "name": "Ethernet1/4", + "state": { + "counters": { + "in-broadcast-pkts": 0, + "in-discards": 0, + "in-multicast-pkts": 0, + "in-octets": 0, + "out-broadcast-pkts": 0, + "out-discards": 0, + "out-multicast-pkts": 0, + "out-octets": 0, + "out-unicast-pkts": 0 + }, + "oper-status": "DOWN" + } + } + } + } +} diff --git a/test/integration/test_profiles/nxos/openconfig-interfaces/state/default/mocked/cli.1.show_interfaces.0 b/test/integration/test_profiles/nxos/openconfig-interfaces/state/default/mocked/cli.1.show_interface.0 similarity index 99% rename from test/integration/test_profiles/nxos/openconfig-interfaces/state/default/mocked/cli.1.show_interfaces.0 rename to test/integration/test_profiles/nxos/openconfig-interfaces/state/default/mocked/cli.1.show_interface.0 index ca46e40d..964dfe7d 100644 --- a/test/integration/test_profiles/nxos/openconfig-interfaces/state/default/mocked/cli.1.show_interfaces.0 +++ b/test/integration/test_profiles/nxos/openconfig-interfaces/state/default/mocked/cli.1.show_interface.0 @@ -278,7 +278,7 @@ "share_state": "Dedicated", "state": "down", "state_rsn_desc": "Member port of 40G" - }, + } ] } }