diff --git a/napalm/eos/eos.py b/napalm/eos/eos.py index 76f95f551..827bee3f1 100644 --- a/napalm/eos/eos.py +++ b/napalm/eos/eos.py @@ -1202,21 +1202,78 @@ def get_arp_table(self, vrf=""): return arp_table def get_ntp_servers(self): - commands = ["show running-config | section ntp"] + result = {} - raw_ntp_config = self._run_commands(commands, encoding="text")[0].get( - "output", "" - ) + commands = ["show running-config | section ntp"] - ntp_config = napalm.base.helpers.textfsm_extractor( - self, "ntp_peers", raw_ntp_config + raw_ntp_config = ( + self._run_commands(commands, encoding="text")[0] + .get("output", "") + .splitlines() ) - return { - str(ntp_peer.get("ntppeer")): {} - for ntp_peer in ntp_config - if ntp_peer.get("ntppeer", "") - } + for server in raw_ntp_config: + details = { + "port": 123, + "version": 4, + "association_type": "SERVER", + "iburst": False, + "prefer": False, + "network_instance": "default", + "source_address": "", + "key_id": -1, + } + tokens = server.split() + if tokens[2] == "vrf": + details["network_instance"] = tokens[3] + server_ip = details["address"] = tokens[4] + idx = 5 + else: + server_ip = details["address"] = tokens[2] + idx = 3 + try: + parsed_address = napalm.base.helpers.ipaddress.ip_address(server_ip) + family = parsed_address.version + except ValueError: + # Assume family of 4, unless local-interface has no IPv4 addresses + family = 4 + while idx < len(tokens): + if tokens[idx] == "iburst": + details["iburst"] = True + idx += 1 + + elif tokens[idx] == "key": + details["key_id"] = int(tokens[idx + 1]) + idx += 2 + + elif tokens[idx] == "local-interface": + interfaces = self.get_interfaces_ip() + intf = tokens[idx + 1] + if family == 6 and interfaces[intf]["ipv6"]: + details["source_address"] = list( + interfaces[intf]["ipv6"].keys() + )[0] + elif interfaces[intf]["ipv4"]: + details["source_address"] = list( + interfaces[intf]["ipv4"].keys() + )[0] + elif interfaces[intf]["ipv6"]: + details["source_address"] = list( + interfaces[intf]["ipv6"].keys() + )[0] + idx += 2 + + elif tokens[idx] == "version": + details["version"] = int(tokens[idx + 1]) + idx += 2 + + elif tokens[idx] == "prefer": + details["prefer"] = True + idx += 1 + + result[server_ip] = details + + return result def get_ntp_stats(self): ntp_stats = [] diff --git a/test/eos/mocked_data/test_get_ntp_servers/details/expected_result.json b/test/eos/mocked_data/test_get_ntp_servers/details/expected_result.json new file mode 100644 index 000000000..cbdf65d1b --- /dev/null +++ b/test/eos/mocked_data/test_get_ntp_servers/details/expected_result.json @@ -0,0 +1,24 @@ +{ + "1.2.3.4": { + "port": 123, + "version": 4, + "association_type": "SERVER", + "iburst": true, + "prefer": true, + "network_instance": "FOO", + "source_address": "", + "key_id": -1, + "address": "1.2.3.4" + }, + "4.3.2.1": { + "port": 123, + "version": 4, + "association_type": "SERVER", + "iburst": false, + "prefer": false, + "network_instance": "FOO", + "source_address": "172.20.20.2", + "key_id": -1, + "address": "4.3.2.1" + } +} diff --git a/test/eos/mocked_data/test_get_ntp_servers/details/show_ip_interface.json b/test/eos/mocked_data/test_get_ntp_servers/details/show_ip_interface.json new file mode 100644 index 000000000..955643613 --- /dev/null +++ b/test/eos/mocked_data/test_get_ntp_servers/details/show_ip_interface.json @@ -0,0 +1,48 @@ +{ + "interfaces": { + "Management0": { + "name": "Management0", + "lineProtocolStatus": "up", + "interfaceStatus": "connected", + "mtu": 1500, + "interfaceAddressBrief": { + "ipAddr": { + "address": "172.20.20.2", + "maskLen": 24 + } + }, + "ipv4Routable240": false, + "ipv4Routable0": false, + "enabled": true, + "description": "", + "interfaceAddress": { + "primaryIp": { + "address": "172.20.20.2", + "maskLen": 24 + }, + "secondaryIps": {}, + "secondaryIpsOrderedList": [], + "virtualIp": { + "address": "0.0.0.0", + "maskLen": 0 + }, + "virtualSecondaryIps": {}, + "virtualSecondaryIpsOrderedList": [], + "broadcastAddress": "255.255.255.255", + "dhcp": false + }, + "proxyArp": false, + "proxyArpAllowDefault": false, + "localProxyArp": false, + "gratuitousArp": false, + "routedAddr": "00:1c:73:7b:8c:1d", + "isVrrpBackup": false, + "vrf": "default", + "urpf": "disable", + "addresslessForwarding": "isInvalid", + "directedBroadcastEnabled": false, + "maxMssIngress": 0, + "maxMssEgress": 0 + } + } +} diff --git a/test/eos/mocked_data/test_get_ntp_servers/details/show_ipv6_interface.json b/test/eos/mocked_data/test_get_ntp_servers/details/show_ipv6_interface.json new file mode 100644 index 000000000..a4b8142b0 --- /dev/null +++ b/test/eos/mocked_data/test_get_ntp_servers/details/show_ipv6_interface.json @@ -0,0 +1,46 @@ +{ + "interfaces": { + "Management0": { + "name": "Management0", + "lineProtocolStatus": "up", + "interfaceStatus": "connected", + "mtu": 1500, + "linkLocal": { + "address": "fe80::21c:73ff:fe7b:8c1d", + "subnet": "fe80::/64", + "active": true, + "leastpref": false, + "dadfailed": false + }, + "state": "enabled", + "addresses": [ + { + "address": "2001:172:20:20::2", + "subnet": "2001:172:20:20::/64", + "active": true, + "leastpref": false, + "dadfailed": false + } + ], + "globalAddressesAreVirtual": false, + "multicastGroupAddresses": [ + "ff02::1", + "ff02::1:ff00:2", + "ff02::1:ff7b:8c1d" + ], + "dadStatus": "unavailable", + "dadAttempts": -1, + "ndReachableTime": 30000, + "ndRetransmitInterval": 1000, + "enhancedDad": false, + "autoConfigStatus": "stateless", + "urpf": "disable", + "urpfV4V6Mismatch": false, + "vrf": "default", + "addrSource": "manual", + "maxMssIngress": 0, + "maxMssEgress": 0, + "acceptUnsolicitedNa": false + } + } +} diff --git a/test/eos/mocked_data/test_get_ntp_servers/details/show_running_config___section_ntp.text b/test/eos/mocked_data/test_get_ntp_servers/details/show_running_config___section_ntp.text new file mode 100644 index 000000000..98a32b9ba --- /dev/null +++ b/test/eos/mocked_data/test_get_ntp_servers/details/show_running_config___section_ntp.text @@ -0,0 +1,2 @@ +ntp server vrf FOO 1.2.3.4 prefer iburst +ntp server vrf FOO 4.3.2.1 local-interface Management0 diff --git a/test/eos/mocked_data/test_get_ntp_servers/normal/expected_result.json b/test/eos/mocked_data/test_get_ntp_servers/normal/expected_result.json index b3a9d7d23..d59b3d99e 100644 --- a/test/eos/mocked_data/test_get_ntp_servers/normal/expected_result.json +++ b/test/eos/mocked_data/test_get_ntp_servers/normal/expected_result.json @@ -1 +1,35 @@ -{"1.2.3.4": {}, "2001:0db8:0a0b:12f0:0000:0000:0000:0001": {}, "5.6.7.8": {}} +{ + "1.2.3.4": { + "port": 123, + "version": 4, + "association_type": "SERVER", + "iburst": false, + "prefer": false, + "network_instance": "default", + "source_address": "", + "key_id": -1, + "address": "1.2.3.4" + }, + "5.6.7.8": { + "port": 123, + "version": 4, + "association_type": "SERVER", + "iburst": false, + "prefer": false, + "network_instance": "default", + "source_address": "", + "key_id": -1, + "address": "5.6.7.8" + }, + "2001:0db8:0a0b:12f0:0000:0000:0000:0001": { + "port": 123, + "version": 4, + "association_type": "SERVER", + "iburst": false, + "prefer": false, + "network_instance": "default", + "source_address": "", + "key_id": -1, + "address": "2001:0db8:0a0b:12f0:0000:0000:0000:0001" + } +}