From bd873274d462f43d4e7ed100726930326139ee74 Mon Sep 17 00:00:00 2001
From: Viacheslav Hletenko <v.gletenko@vyos.io>
Date: Wed, 15 Nov 2023 23:48:58 +0000
Subject: T5747: op-mode add MAC and MTU for show interfaces summary

Add op-mode "show interfaces summary"
Add MAC, VRF and MTU options:

vyos@r4# run show interfaces summary
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface    IP Address         MAC                VRF        MTU  S/L    Description
-----------  -----------------  -----------------  -------  -----  -----  -------------
dum0         203.0.113.1/32     96:44:ad:c5:a1:a5  default   1500  u/u
eth0         192.168.122.14/24  52:54:00:f1:fd:77  default   1500  u/u    WAN
eth1         192.0.2.1/24       52:54:00:04:33:2b  foo       1500  u/u    LAN-eth1
eth2         -                  52:54:00:40:2e:af  default   1504  u/u    LAN-eth2
eth3         -                  52:54:00:09:a4:b4  default   1500  A/D

(cherry picked from commit dc3906f04fbfe8014531e092a77c1c8c2d10dfe0)
---
 op-mode-definitions/show-interfaces.xml.in |  6 ++++
 python/vyos/ifconfig/interface.py          | 10 ++++++
 src/op_mode/interfaces.py                  | 56 ++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+)

diff --git a/op-mode-definitions/show-interfaces.xml.in b/op-mode-definitions/show-interfaces.xml.in
index dc61a6f5c..b58e0efea 100644
--- a/op-mode-definitions/show-interfaces.xml.in
+++ b/op-mode-definitions/show-interfaces.xml.in
@@ -20,6 +20,12 @@
             </properties>
             <command>${vyos_op_scripts_dir}/interfaces.py show</command>
           </leafNode>
+          <leafNode name="summary">
+            <properties>
+              <help>Show summary information of all interfaces</help>
+            </properties>
+            <command>${vyos_op_scripts_dir}/interfaces.py show_summary_extended</command>
+          </leafNode>
         </children>
       </node>
     </children>
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 41ce352ad..b8f947d65 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -569,6 +569,16 @@ class Interface(Control):
 
         self.set_interface('netns', netns)
 
+    def get_vrf(self):
+        """
+        Get VRF from interface
+
+        Example:
+        >>> from vyos.ifconfig import Interface
+        >>> Interface('eth0').get_vrf()
+        """
+        return self.get_interface('vrf')
+
     def set_vrf(self, vrf):
         """
         Add/Remove interface from given VRF instance.
diff --git a/src/op_mode/interfaces.py b/src/op_mode/interfaces.py
index 782e178c6..c626535b5 100755
--- a/src/op_mode/interfaces.py
+++ b/src/op_mode/interfaces.py
@@ -243,6 +243,9 @@ def _get_summary_data(ifname: typing.Optional[str],
         res_intf['admin_state'] = interface.get_admin_state()
         res_intf['addr'] = [_ for _ in interface.get_addr() if not _.startswith('fe80::')]
         res_intf['description'] = interface.get_alias()
+        res_intf['mtu'] = interface.get_mtu()
+        res_intf['mac'] = interface.get_mac()
+        res_intf['vrf'] = interface.get_vrf()
 
         ret.append(res_intf)
 
@@ -372,6 +375,51 @@ def _format_show_summary(data):
 
     return 0
 
+@catch_broken_pipe
+def _format_show_summary_extended(data):
+    headers = ["Interface", "IP Address", "MAC", "VRF", "MTU", "S/L", "Description"]
+    table_data = []
+
+    print('Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down')
+
+    for intf in data:
+        if 'unhandled' in intf:
+            continue
+
+        ifname = intf['ifname']
+        oper_state = 'u' if intf['oper_state'] in ('up', 'unknown') else 'D'
+        admin_state = 'u' if intf['admin_state'] in ('up', 'unknown') else 'A'
+        addrs = intf['addr'] or ['-']
+        description = '\n'.join(_split_text(intf['description'], 0))
+        mac = intf['mac'] if intf['mac'] else 'n/a'
+        mtu = intf['mtu'] if intf['mtu'] else 'n/a'
+        vrf = intf['vrf'] if intf['vrf'] else 'default'
+
+        ip_addresses = '\n'.join(ip for ip in addrs)
+
+        # Create a row for the table
+        row = [
+            ifname,
+            ip_addresses,
+            mac,
+            vrf,
+            mtu,
+            f"{admin_state}/{oper_state}",
+            description,
+        ]
+
+        # Append the row to the table data
+        table_data.append(row)
+
+    for intf in data:
+        if 'unhandled' in intf:
+            string = {'C': 'u/D', 'D': 'A/D'}[intf['state']]
+            table_data.append([intf['ifname'], '', '', '', '', string, ''])
+
+    print(tabulate(table_data, headers))
+
+    return 0
+
 @catch_broken_pipe
 def _format_show_counters(data: list):
     data_entries = []
@@ -408,6 +456,14 @@ def show_summary(raw: bool, intf_name: typing.Optional[str],
         return data
     return _format_show_summary(data)
 
+def show_summary_extended(raw: bool, intf_name: typing.Optional[str],
+                            intf_type: typing.Optional[str],
+                            vif: bool, vrrp: bool):
+    data = _get_summary_data(intf_name, intf_type, vif, vrrp)
+    if raw:
+        return data
+    return _format_show_summary_extended(data)
+
 def show_counters(raw: bool, intf_name: typing.Optional[str],
                              intf_type: typing.Optional[str],
                              vif: bool, vrrp: bool):
-- 
cgit v1.2.3