From 3f34faeca291c1bc9f973d9a3d5004e7a6ca058c Mon Sep 17 00:00:00 2001 From: kurtmathys <21208410+kurtmathys@users.noreply.github.com> Date: Tue, 7 Oct 2025 14:08:07 +0200 Subject: [PATCH 1/8] Add files via upload Fixes for 'show frequency synchronization' and 'show ptp' on iosxr. Tested with IOS XR 24.1.1 and higher. --- ...ency_synchronization_iosxr_20251007133300.rst | 12 ++++++++++++ .../changelog_show_ptp_iosxr_20251007133300.rst | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 changelog/undistributed/changelog_show_frequency_synchronization_iosxr_20251007133300.rst create mode 100644 changelog/undistributed/changelog_show_ptp_iosxr_20251007133300.rst diff --git a/changelog/undistributed/changelog_show_frequency_synchronization_iosxr_20251007133300.rst b/changelog/undistributed/changelog_show_frequency_synchronization_iosxr_20251007133300.rst new file mode 100644 index 000000000..3259ab917 --- /dev/null +++ b/changelog/undistributed/changelog_show_frequency_synchronization_iosxr_20251007133300.rst @@ -0,0 +1,12 @@ + + +-------------------------------------------------------------------------------- + Fix +-------------------------------------------------------------------------------- + +* iosxr + * Modified ShowFrequencySynchronizationInterfaces: + * Changed wait_to_restore_time from schema to Optional. + + + diff --git a/changelog/undistributed/changelog_show_ptp_iosxr_20251007133300.rst b/changelog/undistributed/changelog_show_ptp_iosxr_20251007133300.rst new file mode 100644 index 000000000..fe5c4afb9 --- /dev/null +++ b/changelog/undistributed/changelog_show_ptp_iosxr_20251007133300.rst @@ -0,0 +1,16 @@ + + +-------------------------------------------------------------------------------- + Fix +-------------------------------------------------------------------------------- + +* iosxr + * Modified ShowPtpPlatformServo: + * Changed , from schema to Optional. + * Updated regex pattern p13, p14 to accommodate various time formats. + + * Modified ShowPtpForeignMastersInterface: + * Changed announce_messages from Schema to Optional. + * Updated regex pattern p2 to accommodate also Multicast (for G.8275.2). + * Added a logic to get only the first 'Clock ID'. + From 13d1cc9f6a8a3609b3487f5408bc6e53d78517cc Mon Sep 17 00:00:00 2001 From: kurtmathys <21208410+kurtmathys@users.noreply.github.com> Date: Tue, 7 Oct 2025 14:13:42 +0200 Subject: [PATCH 2/8] Add files via upload Update for IOS-XR 24.1.1 (and higher) and for Ethernet/Multicast support (G.8275.1). --- .../iosxr/show_frequency_synchronization.py | 702 +++++----- src/genie/libs/parser/iosxr/show_ptp.py | 1130 +++++++++-------- 2 files changed, 918 insertions(+), 914 deletions(-) diff --git a/src/genie/libs/parser/iosxr/show_frequency_synchronization.py b/src/genie/libs/parser/iosxr/show_frequency_synchronization.py index 0fd15f684..608a5b528 100644 --- a/src/genie/libs/parser/iosxr/show_frequency_synchronization.py +++ b/src/genie/libs/parser/iosxr/show_frequency_synchronization.py @@ -1,352 +1,352 @@ -""" show_frequency_synchronization.py - -IOSXR parsers for the following commands: - - * 'show frequency synchronization interfaces {interface}' - * 'show frequency synchronization interfaces' - -""" - -# Python -import re - -# Metaparser -from genie.libs.parser.utils.common import Common -from genie.metaparser import MetaParser -from genie.metaparser.util.schemaengine import Any, Optional - - -class ShowFrequencySynchronizationInterfacesSchema(MetaParser): - ''' Schema for: - * 'show frequency synchronization interfaces' - * 'show frequency synchronization interfaces {interface}' - ''' - - schema = { - 'interfaces': { - Any(): { - 'interface': str, - 'interface_status': str, - Optional('selection'): str, - 'wait_to_restore_time': int, - 'ssm': { - 'status': str, - Optional('peer_time'): str, - Optional('last_ssm_received'): str, - Optional('esmc_ssms'): { - 'sent': { - 'total': int, - 'information': int, - 'event': int, - 'dnu_dus': int - }, - 'received': { - 'total': int, - 'information': int, - 'event': int, - 'dnu_dus': int - } - } - }, - 'input': { - 'status': str, - Optional('selection'): str, - Optional('restore'): str, - Optional('last_received_ql'): str, - Optional('effective_ql'): str, - Optional('priority'): int, - Optional('time_of_day_priority'): int - }, - 'output': { - 'selected_source': str, - 'selected_source_ql': str, - Optional('effective_ql'): str - }, - 'next_selection_points': str - } - } - } - - -# ================================ -# Parser for 'show frequency synchronization interfaces' -# Parser for 'show frequency synchronization interfaces {interface}' -# ================================ -class ShowFrequencySynchronizationInterfaces(ShowFrequencySynchronizationInterfacesSchema): - - cli_command = ['show frequency synchronization interfaces {interface}', - 'show frequency synchronization interfaces'] - - def cli(self, interface=None, output=None): - - if output is None: - if interface: - command = self.cli_command[0].format(interface=interface) - else: - command = self.cli_command[1] - output = self.device.execute(command) - - # initial return dictionary - ret_dict = {} - - # Interface GigabitEthernet0/0/0/16 (up) - # Interface TenGigE0/0/2/0 (shutdown) - p1 = re.compile(r'^Interface\s+(?P\S+)\s+\((?P(up|shutdown|down))\)$') - - # Assigned as input for selection - p2 = re.compile(r'^Assigned\s+as\s+(?P\w+)\s+for\s+selection$') - - # Wait-to-restore time 0 minutes - p3 = re.compile(r'^Wait-to-restore\s+time\s+(?P\d+)\s+minutes$') - - # SSM Enabled - # SSM Disabled - p4 = re.compile(r'^SSM\s+(?P[Enabled|Disabled]+)$') - - # Sent: 97832 97830 2 0 - p5 = re.compile(r'^Sent+:\s+(?P\d+)\s+(?P\d+)\s+(?P\d+)\s+(?P\d+)$') - - # Received: 97831 97830 1 0 - p6 = re.compile(r'^Received+:\s+(?P\d+)\s+(?P\d+)\s+(?P\d+)\s+(?P\d+)$') - - # Up - # Down - p7 = re.compile(r'^(?P[Up|Down]+)$') - - # Down - not assigned for selection - p8 = re.compile(r'^(?P[Up|Down]+)\s+-\s+(?P[\w\s]+)\s+for\s+selection$') - - # Last received QL: Failed - # Last received QL: Opt-I/PRC - p9 = re.compile(r'^Last\s+received\s+QL:\s(?P.*)$') - - # Effective QL: Opt-I/PRC, Priority: 15, Time-of-day Priority 101 - # Effective QL: Failed, Priority: 15, Time-of-day Priority 101 - p10 = re.compile(r'^Effective\s+QL:\s+(?P.*),\s+Priority:\s+(?P\d+),' - r'\s+Time-of-day\s+Priority\s+(?P\d+)$') - - # Restore in 00:04:33 - p11 = re.compile(r'^Restore\s+in\s+(?P[\d:]+)$') - - # Selected source: TenGigE0/0/2/1 - p12 = re.compile(r'^Selected\s+source:\s+(?P.*)$') - - # Selected source QL: Opt-I/PRC - p13 = re.compile(r'^Selected\s+source\s+QL:\s+(?P\S+)$') - - # Effective QL: Opt-I/PRC - p14 = re.compile(r'^Effective\s+QL:\s+(?P\S+)$') - - # Next selection points: SPA_RX_0 - p15 = re.compile(r'^Next\s+selection\s+points:\s+(?P.*)$') - - # Peer Up for 1d02h, last SSM received 0.837s ago - # p16 = re.compile(r'^Peer\s+Up\s+for\s+(?P\w+),\s+last\s+SSM\s+received\s+(?P[\w.]+)\s+ago$') - p16 = re.compile(r'^Peer\s+[Up|Timed Out]+\s+for\s+(?P\w+),\s+last\s+SSM\s+received\s+(?P[\w .]+)') - - for line in output.splitlines(): - line = line.strip() # strip whitespace from beginning and end - - # Interface GigabitEthernet0/0/0/16 (up) - # Interface TenGigE0/0/2/0 (shutdown) - m = p1.match(line) - if m: - group = m.groupdict() - interfaces_dict = ret_dict.setdefault('interfaces', {}).setdefault(group['interface'], {}) - interfaces_dict.update({'interface': group['interface']}) - interfaces_dict.update({'interface_status': group['interface_status']}) - continue - - # Assigned as input for selection - m = p2.match(line) - if m: - group = m.groupdict() - interfaces_dict.update({'selection': group['selection']}) - continue - - # Wait-to-restore time 0 minutes - m = p3.match(line) - if m: - group = m.groupdict() - interfaces_dict.update({'wait_to_restore_time': int(group['wait_to_restore_time'])}) - continue - - # SSM Enabled - # SSM Disabled - m = p4.match(line) - if m: - group = m.groupdict() - # ssm_dict = interfaces_dict.setdefault('ssm', {}).setdefault(group['ssm_status'], {}) - ssm_dict = interfaces_dict.setdefault('ssm', {}) - ssm_dict.update({'status': group['ssm_status']}) - continue - - # Sent: 97832 97830 2 0 - m = p5.match(line) - if m: - group = m.groupdict() - esmc_ssms_dict = ssm_dict.setdefault('esmc_ssms', {}) - sent_dict = esmc_ssms_dict.setdefault('sent', {}) - - sent_dict['total'] = int(m.groupdict()['total']) - sent_dict['information'] = int(m.groupdict()['information']) - sent_dict['event'] = int(m.groupdict()['event']) - sent_dict['dnu_dus'] = int(m.groupdict()['dnu_dus']) - continue - - # Received: 97831 97830 1 0 - m = p6.match(line) - if m: - group = m.groupdict() - received_dict = esmc_ssms_dict.setdefault('received', {}) - - received_dict['total'] = int(m.groupdict()['total']) - received_dict['information'] = int(m.groupdict()['information']) - received_dict['event'] = int(m.groupdict()['event']) - received_dict['dnu_dus'] = int(m.groupdict()['dnu_dus']) - continue - - # Up - # Down - m = p7.match(line) - if m: - group = m.groupdict() - input_dict = interfaces_dict.setdefault('input', {}) - input_dict['status'] = m.groupdict()['input'] - continue - - # Down - not assigned for selection - m = p8.match(line) - if m: - group = m.groupdict() - input_dict = interfaces_dict.setdefault('input', {}) - input_dict['status'] = m.groupdict()['input'] - input_dict['selection'] = m.groupdict()['selection'] - continue - - # Last received QL: Failed - # Last received QL: Opt-I/PRC - m = p9.match(line) - if m: - group = m.groupdict() - input_dict['last_received_ql'] = m.groupdict()['last_received_ql'] - continue - - # Effective QL: Opt-I/PRC, Priority: 15, Time-of-day Priority 101 - # Effective QL: Failed, Priority: 15, Time-of-day Priority 101 - m = p10.match(line) - if m: - group = m.groupdict() - input_dict['effective_ql'] = m.groupdict()['effective_ql'] - input_dict['priority'] = int(m.groupdict()['priority']) - input_dict['time_of_day_priority'] = int(m.groupdict()['time_of_day_priority']) - continue - - # Restore in 00:04:33 - m = p11.match(line) - if m: - group = m.groupdict() - input_dict = interfaces_dict.setdefault('input', {}) - input_dict['restore'] = m.groupdict()['restore'] - continue - - # Selected source: TenGigE0/0/2/1 - # Selected source: GigabitEthernet0/0/0/18 - m = p12.match(line) - if m: - group = m.groupdict() - output_dict = interfaces_dict.setdefault('output', {}) - output_dict['selected_source'] = m.groupdict()['selected_source'] - continue - - # Selected source QL: Opt-I/PRC - m = p13.match(line) - if m: - group = m.groupdict() - output_dict['selected_source_ql'] = m.groupdict()['selected_source_ql'] - continue - - # Effective QL: Opt-I/PRC - m = p14.match(line) - if m: - group = m.groupdict() - output_dict['effective_ql'] = m.groupdict()['effective_ql'] - continue - - # Next selection points: SPA_RX_0 - m = p15.match(line) - if m: - group = m.groupdict() - interfaces_dict.update({'next_selection_points': group['next_selection_points']}) - continue - - # Peer Up for 1d02h, last SSM received 0.837s ago - m = p16.match(line) - if m: - group = m.groupdict() - ssm_dict.update({'peer_time': group['peer_time']}) - ssm_dict.update({'last_ssm_received': group['last_ssm_received']}) - continue - - return ret_dict - - -class ShowFrequencySynchronizationInterfacesBriefSchema(MetaParser): - ''' Schema for: - * 'show frequency synchronization interfaces brief' - ''' - schema = { - 'interface': { - Any () : { - 'flag' : str, - 'interface': str, - 'qlrcv': str, - 'qluse': str, - 'priority': str, - 'qlsnd': str, - 'output_driven_by': str, - } - } - } - -class ShowFrequencySynchronizationInterfacesBrief(ShowFrequencySynchronizationInterfacesBriefSchema): - - cli_command = ['show frequency synchronization interfaces brief'] - - def cli(self, output=None): - if output is None: - output = self.device.execute(self.cli_command[0]) - - ret_dict = {} - - #Fl Interface QLrcv QLuse Pri QLsnd Output driven by - #==== ======================== ===== ===== === ===== ======================== - #>S TenGigE0/0/0/1/0 PRC PRC 100 PRC Internal0 [0/RP0/CPU0] - #>S TenGigE0/0/0/1/1 PRC PRC 100 PRC Internal0 [0/RP0/CPU0] - p1 = re.compile(r'^(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+(?P.+\s+(\[.+?\]))') - - for line in output.splitlines(): - line = line.strip() - - #Fl Interface QLrcv QLuse Pri QLsnd Output driven by - #==== ======================== ===== ===== === ===== ======================== - #>S TenGigE0/0/0/1/0 PRC PRC 100 PRC Internal0 [0/RP0/CPU0] - #>S TenGigE0/0/0/1/1 PRC PRC 100 PRC Internal0 [0/RP0/CPU0] - m = p1.match(line) - if m: - group = m.groupdict() - interface = group['interface'] - interface_dict = ret_dict.setdefault('interface',{}).setdefault(interface, {}) - interface_dict.update({ - 'flag': group['flag'], - 'interface': group['interface'], - 'qlrcv': group['qlrcv'], - 'qluse': group['qluse'], - 'priority': group['priority'], - 'qlsnd': group['qlsnd'], - 'output_driven_by': group['output_driven_by'] - }) - continue - - return ret_dict +""" show_frequency_synchronization.py + +IOSXR parsers for the following commands: + + * 'show frequency synchronization interfaces {interface}' + * 'show frequency synchronization interfaces' + +""" + +# Python +import re + +# Metaparser +from genie.libs.parser.utils.common import Common +from genie.metaparser import MetaParser +from genie.metaparser.util.schemaengine import Any, Optional + + +class ShowFrequencySynchronizationInterfacesSchema(MetaParser): + ''' Schema for: + * 'show frequency synchronization interfaces' + * 'show frequency synchronization interfaces {interface}' + ''' + + schema = { + 'interfaces': { + Any(): { + 'interface': str, + 'interface_status': str, + Optional('selection'): str, + Optional('wait_to_restore_time'): int, + 'ssm': { + 'status': str, + Optional('peer_time'): str, + Optional('last_ssm_received'): str, + Optional('esmc_ssms'): { + 'sent': { + 'total': int, + 'information': int, + 'event': int, + 'dnu_dus': int + }, + 'received': { + 'total': int, + 'information': int, + 'event': int, + 'dnu_dus': int + } + } + }, + 'input': { + Optional('status'): str, + Optional('selection'): str, + Optional('restore'): str, + Optional('last_received_ql'): str, + Optional('effective_ql'): str, + Optional('priority'): int, + Optional('time_of_day_priority'): int + }, + 'output': { + 'selected_source': str, + 'selected_source_ql': str, + Optional('effective_ql'): str + }, + 'next_selection_points': str + } + } + } + + +# ================================ +# Parser for 'show frequency synchronization interfaces' +# Parser for 'show frequency synchronization interfaces {interface}' +# ================================ +class ShowFrequencySynchronizationInterfaces(ShowFrequencySynchronizationInterfacesSchema): + + cli_command = ['show frequency synchronization interfaces {interface}', + 'show frequency synchronization interfaces'] + + def cli(self, interface=None, output=None): + + if output is None: + if interface: + command = self.cli_command[0].format(interface=interface) + else: + command = self.cli_command[1] + output = self.device.execute(command) + + # initial return dictionary + ret_dict = {} + + # Interface GigabitEthernet0/0/0/16 (up) + # Interface TenGigE0/0/2/0 (shutdown) + p1 = re.compile(r'^Interface\s+(?P\S+)\s+\((?P(up|shutdown|down))\)$') + + # Assigned as input for selection + p2 = re.compile(r'^Assigned\s+as\s+(?P\w+)\s+for\s+selection$') + + # Wait-to-restore time 0 minutes + p3 = re.compile(r'^Wait-to-restore\s+time\s+(?P\d+)\s+minutes$') + + # SSM Enabled + # SSM Disabled + p4 = re.compile(r'^SSM\s+(?P[Enabled|Disabled]+)$') + + # Sent: 97832 97830 2 0 + p5 = re.compile(r'^Sent+:\s+(?P\d+)\s+(?P\d+)\s+(?P\d+)\s+(?P\d+)$') + + # Received: 97831 97830 1 0 + p6 = re.compile(r'^Received+:\s+(?P\d+)\s+(?P\d+)\s+(?P\d+)\s+(?P\d+)$') + + # Up + # Down + p7 = re.compile(r'^(?P[Up|Down]+)$') + + # Down - not assigned for selection + p8 = re.compile(r'^(?P[Up|Down]+)\s+-\s+(?P[\w\s]+)\s+for\s+selection$') + + # Last received QL: Failed + # Last received QL: Opt-I/PRC + p9 = re.compile(r'^Last\s+received\s+QL:\s(?P.*)$') + + # Effective QL: Opt-I/PRC, Priority: 15, Time-of-day Priority 101 + # Effective QL: Failed, Priority: 15, Time-of-day Priority 101 + p10 = re.compile(r'^Effective\s+QL:\s+(?P.*),\s+Priority:\s+(?P\d+),' + r'\s+Time-of-day\s+Priority\s+(?P\d+)$') + + # Restore in 00:04:33 + p11 = re.compile(r'^Restore\s+in\s+(?P[\d:]+)$') + + # Selected source: TenGigE0/0/2/1 + p12 = re.compile(r'^Selected\s+source:\s+(?P.*)$') + + # Selected source QL: Opt-I/PRC + p13 = re.compile(r'^Selected\s+source\s+QL:\s+(?P\S+)$') + + # Effective QL: Opt-I/PRC + p14 = re.compile(r'^Effective\s+QL:\s+(?P\S+)$') + + # Next selection points: SPA_RX_0 + p15 = re.compile(r'^Next\s+selection\s+points:\s+(?P.*)$') + + # Peer Up for 1d02h, last SSM received 0.837s ago + # p16 = re.compile(r'^Peer\s+Up\s+for\s+(?P\w+),\s+last\s+SSM\s+received\s+(?P[\w.]+)\s+ago$') + p16 = re.compile(r'^Peer\s+[Up|Timed Out]+\s+for\s+(?P\w+),\s+last\s+SSM\s+received\s+(?P[\w .]+)') + + for line in output.splitlines(): + line = line.strip() # strip whitespace from beginning and end + + # Interface GigabitEthernet0/0/0/16 (up) + # Interface TenGigE0/0/2/0 (shutdown) + m = p1.match(line) + if m: + group = m.groupdict() + interfaces_dict = ret_dict.setdefault('interfaces', {}).setdefault(group['interface'], {}) + interfaces_dict.update({'interface': group['interface']}) + interfaces_dict.update({'interface_status': group['interface_status']}) + continue + + # Assigned as input for selection + m = p2.match(line) + if m: + group = m.groupdict() + interfaces_dict.update({'selection': group['selection']}) + continue + + # Wait-to-restore time 0 minutes + m = p3.match(line) + if m: + group = m.groupdict() + interfaces_dict.update({'wait_to_restore_time': int(group['wait_to_restore_time'])}) + continue + + # SSM Enabled + # SSM Disabled + m = p4.match(line) + if m: + group = m.groupdict() + # ssm_dict = interfaces_dict.setdefault('ssm', {}).setdefault(group['ssm_status'], {}) + ssm_dict = interfaces_dict.setdefault('ssm', {}) + ssm_dict.update({'status': group['ssm_status']}) + continue + + # Sent: 97832 97830 2 0 + m = p5.match(line) + if m: + group = m.groupdict() + esmc_ssms_dict = ssm_dict.setdefault('esmc_ssms', {}) + sent_dict = esmc_ssms_dict.setdefault('sent', {}) + + sent_dict['total'] = int(m.groupdict()['total']) + sent_dict['information'] = int(m.groupdict()['information']) + sent_dict['event'] = int(m.groupdict()['event']) + sent_dict['dnu_dus'] = int(m.groupdict()['dnu_dus']) + continue + + # Received: 97831 97830 1 0 + m = p6.match(line) + if m: + group = m.groupdict() + received_dict = esmc_ssms_dict.setdefault('received', {}) + + received_dict['total'] = int(m.groupdict()['total']) + received_dict['information'] = int(m.groupdict()['information']) + received_dict['event'] = int(m.groupdict()['event']) + received_dict['dnu_dus'] = int(m.groupdict()['dnu_dus']) + continue + + # Up + # Down + m = p7.match(line) + if m: + group = m.groupdict() + input_dict = interfaces_dict.setdefault('input', {}) + input_dict['status'] = m.groupdict()['input'] + continue + + # Down - not assigned for selection + m = p8.match(line) + if m: + group = m.groupdict() + input_dict = interfaces_dict.setdefault('input', {}) + input_dict['status'] = m.groupdict()['input'] + input_dict['selection'] = m.groupdict()['selection'] + continue + + # Last received QL: Failed + # Last received QL: Opt-I/PRC + m = p9.match(line) + if m: + group = m.groupdict() + input_dict['last_received_ql'] = m.groupdict()['last_received_ql'] + continue + + # Effective QL: Opt-I/PRC, Priority: 15, Time-of-day Priority 101 + # Effective QL: Failed, Priority: 15, Time-of-day Priority 101 + m = p10.match(line) + if m: + group = m.groupdict() + input_dict['effective_ql'] = m.groupdict()['effective_ql'] + input_dict['priority'] = int(m.groupdict()['priority']) + input_dict['time_of_day_priority'] = int(m.groupdict()['time_of_day_priority']) + continue + + # Restore in 00:04:33 + m = p11.match(line) + if m: + group = m.groupdict() + input_dict = interfaces_dict.setdefault('input', {}) + input_dict['restore'] = m.groupdict()['restore'] + continue + + # Selected source: TenGigE0/0/2/1 + # Selected source: GigabitEthernet0/0/0/18 + m = p12.match(line) + if m: + group = m.groupdict() + output_dict = interfaces_dict.setdefault('output', {}) + output_dict['selected_source'] = m.groupdict()['selected_source'] + continue + + # Selected source QL: Opt-I/PRC + m = p13.match(line) + if m: + group = m.groupdict() + output_dict['selected_source_ql'] = m.groupdict()['selected_source_ql'] + continue + + # Effective QL: Opt-I/PRC + m = p14.match(line) + if m: + group = m.groupdict() + output_dict['effective_ql'] = m.groupdict()['effective_ql'] + continue + + # Next selection points: SPA_RX_0 + m = p15.match(line) + if m: + group = m.groupdict() + interfaces_dict.update({'next_selection_points': group['next_selection_points']}) + continue + + # Peer Up for 1d02h, last SSM received 0.837s ago + m = p16.match(line) + if m: + group = m.groupdict() + ssm_dict.update({'peer_time': group['peer_time']}) + ssm_dict.update({'last_ssm_received': group['last_ssm_received']}) + continue + + return ret_dict + + +class ShowFrequencySynchronizationInterfacesBriefSchema(MetaParser): + ''' Schema for: + * 'show frequency synchronization interfaces brief' + ''' + schema = { + 'interface': { + Any () : { + 'flag' : str, + 'interface': str, + 'qlrcv': str, + 'qluse': str, + 'priority': str, + 'qlsnd': str, + 'output_driven_by': str, + } + } + } + +class ShowFrequencySynchronizationInterfacesBrief(ShowFrequencySynchronizationInterfacesBriefSchema): + + cli_command = ['show frequency synchronization interfaces brief'] + + def cli(self, output=None): + if output is None: + output = self.device.execute(self.cli_command[0]) + + ret_dict = {} + + #Fl Interface QLrcv QLuse Pri QLsnd Output driven by + #==== ======================== ===== ===== === ===== ======================== + #>S TenGigE0/0/0/1/0 PRC PRC 100 PRC Internal0 [0/RP0/CPU0] + #>S TenGigE0/0/0/1/1 PRC PRC 100 PRC Internal0 [0/RP0/CPU0] + p1 = re.compile(r'^(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+(?P.+\s+(\[.+?\]))') + + for line in output.splitlines(): + line = line.strip() + + #Fl Interface QLrcv QLuse Pri QLsnd Output driven by + #==== ======================== ===== ===== === ===== ======================== + #>S TenGigE0/0/0/1/0 PRC PRC 100 PRC Internal0 [0/RP0/CPU0] + #>S TenGigE0/0/0/1/1 PRC PRC 100 PRC Internal0 [0/RP0/CPU0] + m = p1.match(line) + if m: + group = m.groupdict() + interface = group['interface'] + interface_dict = ret_dict.setdefault('interface',{}).setdefault(interface, {}) + interface_dict.update({ + 'flag': group['flag'], + 'interface': group['interface'], + 'qlrcv': group['qlrcv'], + 'qluse': group['qluse'], + 'priority': group['priority'], + 'qlsnd': group['qlsnd'], + 'output_driven_by': group['output_driven_by'] + }) + continue + + return ret_dict \ No newline at end of file diff --git a/src/genie/libs/parser/iosxr/show_ptp.py b/src/genie/libs/parser/iosxr/show_ptp.py index 371accfc1..70f273e9c 100644 --- a/src/genie/libs/parser/iosxr/show_ptp.py +++ b/src/genie/libs/parser/iosxr/show_ptp.py @@ -1,564 +1,568 @@ -""" show_ptp.py -IOSXR parsers for the following commands: - * 'show ptp platform servo' - * 'show ptp foreign-masters brief' -""" - -# Python -import re - -# Metaparser -from genie.libs.parser.utils.common import Common -from genie.metaparser import MetaParser -from genie.metaparser.util.schemaengine import Any, Optional - - -class ShowPtpPlatformServoSchema(MetaParser): - ''' Schema for: - * 'show ptp platform servo' - ''' - - schema = { - 'platform_servo_stats': { - 'servo_status': str, - 'servo_stat_index': int, - 'device_status': str, - 'servo_mode': str, - 'servo_log_level': int, - 'phase_alignment_accuracy': str, - 'sync_timestamp_updated': int, - 'sync_timestamp_discarded': int, - 'delay_timestamp_updated': int, - 'delay_timestamp_discarded': int, - 'previous_received_timestamp': { - 't1': float, - 't2': float, - 't3': float, - 't4': float - }, - 'last_received_timestamp': { - 't1': float, - 't2': float, - 't3': float, - 't4': float - }, - 'offset_from_master': str, - 'mean_path_delay': str, - 'set_time': int, - 'step_time': int, - 'adjust_freq': int, - Optional('adjust_freq_time'): int, - 'last_set_time': float, - 'flag': int, - 'last_step_time': int, - 'last_adjust_freq': int - } - } - - -# ================================ -# Parser for 'show ptp platform servo' -# ================================ -class ShowPtpPlatformServo(ShowPtpPlatformServoSchema): - - cli_command = ['show ptp platform servo'] - - def cli(self, output=None): - - if output is None: - output = self.device.execute(self.cli_command[0]) - - # initial return dictionary - ret_dict = {} - - # Servo status: Running - p1 = re.compile(r'^Servo\s+status:\s+(?P[a-zA-Z]+)$') - - # Servo stat_index: 2 - p2 = re.compile(r'^Servo\s+stat_index:\s+(?P\d+)$') - - # Device status: PHASE_LOCKED - # Device status: FREQ_LOCKED - p3 = re.compile(r'^Device\s+status:\s+(?P[\w]+)$') - - # Servo Mode: Hybrid - # Servo Mode: Non Hybrid - p4 = re.compile(r'^Servo\s+Mode:\s+(?P[a-zA-Z ]+)$') - - # Servo log level: 0 - p5 = re.compile(r'^Servo\s+log\s+level:\s+(?P\d+)$') - - # Phase Alignment Accuracy: -8 ns - # Phase Alignment Accuracy: -17034645174 ns - p6 = re.compile(r'^Phase\s+Alignment\s+Accuracy:\s+(?P[-\w ]+)$') - - # Sync timestamp updated: 9848934 - p7 = re.compile(r'^Sync\s+timestamp\s+updated:\s+(?P\d+)$') - - # Sync timestamp discarded: 0 - p8 = re.compile(r'^Sync\s+timestamp\s+discarded:\s+(?P\d+)$') - - # Delay timestamp updated: 9848973 - p9 = re.compile(r'^Delay\s+timestamp\s+updated:\s+(?P\d+)$') - - # Delay timestamp discarded: 0 - p10 = re.compile(r'^Delay\s+timestamp\s+discarded:\s+(?P\d+)$') - - # Previous Received Timestamp T1: 1674467002.900294787 T2: 1674467002.900304552 T3: 1674467002.905436033 T4: 1674467002.905445830 - p11 = re.compile(r'^Previous\s+Received\s+Timestamp\s+T1:\s+(?P[\d.]+)\s+T2:\s+(?P[\d.]+)\s+T3:\s+(?P[\d.]+)\s+T4:\s+(?P[\d.]+)$') - - # Last Received Timestamp T1: 1671703729.684676938 T2: 1671703746.719324326 T3: 1671703746.779917501 T4: 1671703729.745274543 - p12 = re.compile(r'^Last\s+Received\s+Timestamp\s+T1:\s+(?P[\d.]+)\s+T2:\s+(?P[\d.]+)\s+T3:\s+(?P[\d.]+)\s+T4:\s+(?P[\d.]+)$') - - # Offset from master: 17 secs, 34645173 nsecs - # Offset from master: -0 secs, 22 nsecs - p13 = re.compile(r'^Offset\s+from\s+master:\s+(?P[-\w ]+),\s+\d+\s+nsecs$') - - # Mean path delay : 0 secs, 2215 nsecs - # Mean path delay : 0 secs, 9732 nsecs - p14 = re.compile(r'^Mean\s+path\s+delay\s+:\s+(?P[\w ]+),\s+\d+\s+nsecs$') - - # setTime():1854 stepTime():7989 adjustFreq():789 adjustFreqTime():437113 - # setTime():2 stepTime():1 adjustFreq():420942 adjustFreqTime():0 - # setTime():0 stepTime():0 adjustFreq():0 - p15 = re.compile(r'^setTime\(\):(?P\d+)\s+stepTime\(\):(?P\d+)\s+adjustFreq\(\):(?P\d+)(?:\s+adjustFreqTime\(\):(?P\d+))?$') - - # Last setTime: 1.000000000 flag:0 Last stepTime:262310484, Last adjustFreq:9999988 - # Last setTime: 273.000000000 flag:0 Last stepTime:105006084, Last adjustFreq:-19615 - # Last setTime: 0.000000000 flag:0 Last stepTime:0 Last adjustFreq:0 - p16 = re.compile(r'^Last\s+setTime:\s+(?P[-\d.]+)\s+flag:(?P\d+)\s+Last\s+stepTime:(?P[-\d]+)(?:(,))?\s+Last\s+adjustFreq:(?P[-\d]+)$') - - for line in output.splitlines(): - line = line.strip() - - # Servo status: Running - m = p1.match(line) - if m: - group = m.groupdict() - ptp_dict = ret_dict.setdefault('platform_servo_stats',{}) - ptp_dict.update({'servo_status': group['servo_status']}) - continue - - # Servo stat_index: 2 - m = p2.match(line) - if m: - group = m.groupdict() - servo_stat_index = int(group['servo_stat_index']) - ptp_dict.update({'servo_stat_index': servo_stat_index}) - continue - - # Device status: PHASE_LOCKED - # Device status: FREQ_LOCKED - m = p3.match(line) - if m: - group = m.groupdict() - ptp_dict.update({'device_status': group['device_status']}) - continue - - # Servo Mode: Hybrid - # Servo Mode: Non Hybrid - m = p4.match(line) - if m: - group = m.groupdict() - ptp_dict.update({'servo_mode': group['servo_mode']}) - continue - - # Servo log level: 0 - m = p5.match(line) - if m: - group = m.groupdict() - servo_log_level = int(group['servo_log_level']) - ptp_dict.update({'servo_log_level': servo_log_level}) - continue - - # Phase Alignment Accuracy: -8 ns - # Phase Alignment Accuracy: -17034645174 ns - m = p6.match(line) - if m: - group = m.groupdict() - ptp_dict.update({'phase_alignment_accuracy': group['phase_alignment_accuracy']}) - continue - - # Sync timestamp updated: 9848934 - m = p7.match(line) - if m: - group = m.groupdict() - sync_timestamp_updated = int(group['sync_timestamp_updated']) - ptp_dict.update({'sync_timestamp_updated': sync_timestamp_updated}) - continue - - # Sync timestamp discarded: 0 - m = p8.match(line) - if m: - group = m.groupdict() - sync_timestamp_discarded = int(group['sync_timestamp_discarded']) - ptp_dict.update({'sync_timestamp_discarded': sync_timestamp_discarded}) - continue - - # Delay timestamp updated: 9848973 - m = p9.match(line) - if m: - group = m.groupdict() - delay_timestamp_updated = int(group['delay_timestamp_updated']) - ptp_dict.update({'delay_timestamp_updated': delay_timestamp_updated}) - continue - - # Delay timestamp discarded: 0 - m = p10.match(line) - if m: - group = m.groupdict() - delay_timestamp_discarded = int(group['delay_timestamp_discarded']) - ptp_dict.update({'delay_timestamp_discarded': delay_timestamp_discarded}) - continue - - # Previous Received Timestamp T1: 1674467002.900294787 T2: 1674467002.900304552 T3: 1674467002.905436033 T4: 1674467002.905445830 - m = p11.match(line) - if m: - group = m.groupdict() - previous_received_timestamp_dict = ptp_dict.setdefault('previous_received_timestamp',{}) - t1 = float(group['t1']) - previous_received_timestamp_dict.update({'t1': t1}) - t2 = float(group['t2']) - previous_received_timestamp_dict.update({'t2': t2}) - t3 = float(group['t3']) - previous_received_timestamp_dict.update({'t3': t3}) - t4 = float(group['t4']) - previous_received_timestamp_dict.update({'t4': t4}) - continue - - # Last Received Timestamp T1: 1671703729.684676938 T2: 1671703746.719324326 T3: 1671703746.779917501 T4: 1671703729.745274543 - m = p12.match(line) - if m: - group = m.groupdict() - last_received_timestamp_dict = ptp_dict.setdefault('last_received_timestamp',{}) - t1 = float(group['t1']) - last_received_timestamp_dict.update({'t1': t1}) - t2 = float(group['t2']) - last_received_timestamp_dict.update({'t2': t2}) - t3 = float(group['t3']) - last_received_timestamp_dict.update({'t3': t3}) - t4 = float(group['t4']) - last_received_timestamp_dict.update({'t4': t4}) - continue - - # Offset from master: 17 secs, 34645173 nsecs - # Offset from master: -0 secs, 22 nsecs - m = p13.match(line) - if m: - group = m.groupdict() - ptp_dict.update({'offset_from_master': group['offset_from_master']}) - continue - - # Mean path delay : 0 secs, 2215 nsecs - # Mean path delay : 0 secs, 9732 nsecs - m = p14.match(line) - if m: - group = m.groupdict() - ptp_dict.update({'mean_path_delay': group['mean_path_delay']}) - continue - - # setTime():1854 stepTime():7989 adjustFreq():789 adjustFreqTime():437113 - # setTime():2 stepTime():1 adjustFreq():420942 adjustFreqTime():0 - m = p15.match(line) - if m: - group = m.groupdict() - set_time = int(group['set_time']) - ptp_dict.update({'set_time': set_time}) - step_time = int(group['step_time']) - ptp_dict.update({'step_time': step_time}) - adjust_freq = int(group['adjust_freq']) - ptp_dict.update({'adjust_freq': adjust_freq}) - if group['adjust_freq_time']: - adjust_freq_time = int(group['adjust_freq_time']) - ptp_dict.update({'adjust_freq_time': adjust_freq_time}) - continue - - # Last setTime: 1.000000000 flag:0 Last stepTime:262310484, Last adjustFreq:9999988 - # Last setTime: 273.000000000 flag:0 Last stepTime:105006084, Last adjustFreq:-19615 - m = p16.match(line) - if m: - group = m.groupdict() - last_set_time = float(group['last_set_time']) - ptp_dict.update({'last_set_time': last_set_time}) - flag = int(group['flag']) - ptp_dict.update({'flag': flag}) - last_step_time = int(group['last_step_time']) - ptp_dict.update({'last_step_time': last_step_time}) - last_adjust_freq = int(group['last_adjust_freq']) - ptp_dict.update({'last_adjust_freq': last_adjust_freq}) - continue - - return ret_dict - -class ShowPtpForeignMastersBriefSchema(MetaParser): - ''' Schema for: - * 'show ptp foreign-masters brief' - ''' - - schema = { - 'interface_name': { - Any(): { - 'transport': str, - 'address': str, - 'cfg_pri': str, - 'priority1': int, - 'state': list - } - } - } - - -# ================================ -# Parser for 'show ptp foreign-masters brief' -# ================================ -class ShowPtpForeignMastersBrief(ShowPtpForeignMastersBriefSchema): - - cli_command = ['show ptp foreign-masters brief'] - - def cli(self, output=None): - - if output is None: - output = self.device.execute(self.cli_command[0]) - - # initial return dictionary - ret_dict = {} - - # Gi0/0/0/19 IPv4 192.168.254.1 None 128 Q,GM - # Gi0/0/0/16 Ethernet 8478.ac6c.0aa2 None 128 M,Q - # Te0/0/2/1 Ethernet 8478.ac6c.0a91 None 128 M,Q,GM - p1 = re.compile(r'^(?P\S+)\s+(?P\w+)\s+(?P
\S+)\s+(?P[None]+)\s+(?P\d+)\s+(?P[A-Z,]+)$') - - for line in output.splitlines(): - line = line.strip() - - # Gi0/0/0/19 IPv4 192.168.254.1 None 128 Q,GM - # Gi0/0/0/16 Ethernet 8478.ac6c.0aa2 None 128 M,Q - # Te0/0/2/1 Ethernet 8478.ac6c.0a91 None 128 M,Q,GM - m = p1.match(line) - if m: - group = m.groupdict() - int_dict = ret_dict.setdefault('interface_name',{}).setdefault(group['interface_name'],{}) - int_dict.update({'transport': group['transport']}) - int_dict.update({'address': group['address']}) - int_dict.update({'cfg_pri': group['cfg_pri']}) - int_dict.update({'priority1': int(group['priority1'])}) - int_dict.update({'state': group['state'].split(',')}) - continue - - return ret_dict - -class ShowPtpForeignMastersInterfaceSchema(MetaParser): - ''' Schema for: - * 'show ptp foreign-masters {interface}' - ''' - - schema = { - 'interface' : { - Any () : { - 'interface' : str, - 'port_number' : str, - 'address_family' : { - Any() : { - 'address_family' : str, - 'ip_address': str, - 'priority' : str, - 'clock_class': str, - 'delay_asymmetry': str, - 'announce_messages': { - Any () : { - 'rate_limit': str, - 'duration': str, - - }, - }, - 'qualified_period':str, - 'clock_id': str, - 'received_clk_properties' : { - 'domain' : str, - 'priority1' : str, - 'priority2' : str, - 'class' : str, - 'accuracy' : str, - 'offset_scaled_log_variance' : str, - 'steps_removed' : str, - 'time_source' : str, - 'time_scale' : str, - 'frequency' : str, - 'time' : str, - 'current_utc_offset' : str, - } - }, - }, - }, - }, - } - -# ================================ -# Parser for 'show ptp foreign-masters {interface}' -# ================================ -class ShowPtpForeignMastersInterface(ShowPtpForeignMastersInterfaceSchema): - - cli_command = 'show ptp foreign-masters {interface}' - - def cli(self, interface= '', output=None): - - if output is None: - output = self.device.execute(self.cli_command.format(interface=interface)) - - # Interface GigabitEthernet0/0/0/2 (PTP port number 2) - p1 = re.compile(r'^Interface\s+(?P\S+)\s\(?PTP\s+port\s+number\s+(?P\d+)\)$') - - # IPv4, Address 192.168.254.1, Unicast - p2 = re.compile(r'^(?P\S+),\s+Address\s+(?P[\d.]+),\s+Unicast$') - - # Configured priority: None (128) - p3 = re.compile(r'^Configured\s+priority:\s+(?P\S+\s+\S+)$') - - # Configured clock class: None - p4 = re.compile(r'^Configured\s+clock\s+class:\s+(?P\w+)$') - - # Configured delay asymmetry: None - p5 = re.compile(r'^Configured\s+delay\s+asymmetry:\s+(?P\w+)$') - - # Announce granted: 8 per-second, 300 seconds - # Sync granted: 64 per-second, 300 seconds - # Delay-resp granted: 64 per-second, 300 seconds - p6 = re.compile(r'^(?P\w+-?\w+\s+\w+):\s+(?P\d+\s+\w+-?\w+),\s+(?P\d+\s+\w+)$') - - # Qualified for 8 hours, 26 minutes, 9 seconds - p7 = re.compile(r'^Qualified\s+for\s(?P\d+\s+\w+,\s+\d+\s+\w+,\s+\d+\s+\w+)$') - - # Clock ID: b0aefffe04cc9b - p8 = re.compile(r'Clock\s+ID:\s+(?P\S+)') - - # Domain: 44, Priority1: 128, Priority2: 128, Class: 6 - p9 = re.compile(r'Domain:\s+(?P\d+),\s+Priority1:\s+(?P\d+),\s+Priority2:\s+(?P\d+),\s+Class:\s+(?P\d+)') - - # Accuracy: 0x21, Offset scaled log variance: 0x4e5d - p10 = re.compile(r'Accuracy:\s+(?P\w+),\s+Offset\s+scaled\s+log\s+variance:\s+(?P\S+)') - - # Steps-removed: 1, Time source: GPS, Timescale: PTP - p11 = re.compile(r'Steps-removed:\s+(?P\d+),\s+Time\s+source:\s+(?P\w+),\s+Timescale:\s+(?P\w+)') - - # Frequency-traceable, Time-traceable - p12 = re.compile(r'(?P\w+-\w+),\s+(?P