Index: /branches/rel_avx_2_7_2/src/webui/webui/htdocs/new/src/avx/models/network/vswitch/__init__.py
===================================================================
--- /branches/rel_avx_2_7_2/src/webui/webui/htdocs/new/src/avx/models/network/vswitch/__init__.py	(revision 8858)
+++ /branches/rel_avx_2_7_2/src/webui/webui/htdocs/new/src/avx/models/network/vswitch/__init__.py	(working copy)
@@ -7,33 +7,51 @@
 from hive.node.model import *
 from hive.utils import get_current_session, andebug
 from hive.model.query import mark_expire_all
-__=_
+# from builtin import ListField, PortFields
+import re
+
+__ = _
 
 child_seq = ['VirtualSwitch']
 
+
 class VirtualSwitch(ANModel):
     name = CharField(verbose_name='Virtual Switch Name', primary_key=True)
 
     mode = EnumField(verbose_name=_('Mode'), values=(
-                                    ('Tune', 'Tune'),
-                                    ('Native', 'Native'),                                  
-                ),default='Native')
-
-    stp = FieldGroup(verbose_name='STP', level=ADVANCED, editable=True,fields={
-        'stp': BooleanField(verbose_name='STP',default=True, optional=True),
-        'priority': IntegerField(verbose_name='Priority',default=32768, condition=ValueCondition('stp',[True]), scope='0..65535', optional=True, help_text='The value must be multiples of 4096.'),
+        ('Tune', 'Tune'),
+        ('Native', 'Native'),
+    ), default='Native')
+
+    # Define the ListField for ports using the above-defined fields
+    ports = ListField(
+        verbose_name=_('Ports'),
+        fields=PortFields(),  # Use the PortFields class
+        optional=True
+    )
+    bonds = ListField(
+        verbose_name=_('Bonds'),
+        fields=PortFields(),  # Use the PortFields class
+        optional=True
+    )
+
+    stp = FieldGroup(verbose_name='STP', level=ADVANCED, editable=True, fields={
+        'stp': BooleanField(verbose_name='STP', default=True, optional=True),
+        'priority': IntegerField(verbose_name='Priority', default=32768, condition=ValueCondition('stp', [True]),
+                                 scope='0..65535', optional=True, help_text='The value must be multiples of 4096.'),
     })
-    interface = FieldGroup(verbose_name='Interface', level=ADVANCED, editable=True,fields={
-                'interfaces': AssoField2(verbose_name=_('Interface'), tgt='network.interface.TrafficInterface.vswitch_tgt',
-                       mul='*', optional=True, pos='right')
+    interface = FieldGroup(verbose_name='Interface', level=ADVANCED, editable=True, fields={
+        'interfaces': AssoField2(verbose_name=_('Interface'), tgt='network.interface.TrafficInterface.vswitch_tgt',
+                                 mul='*', optional=True, pos='right')
     })
-    va_instance = FieldGroup(verbose_name='VA Instance', level=ADVANCED, editable=True,fields={
-                'va_tgt': AssoField2(verbose_name=_('VA Instance'), tgt='network.vswitch.VirtualSwitchVA.vs_name',
-                       monitorable=True, mul='1', comp={}, pos='left', optional=True),
+    va_instance = FieldGroup(verbose_name='VA Instance', level=ADVANCED, editable=True, fields={
+        'va_tgt': AssoField2(verbose_name=_('VA Instance'), tgt='network.vswitch.VirtualSwitchVA.vs_name',
+                             monitorable=True, mul='1', comp={}, pos='left', optional=True),
     })
     mirror = FieldGroup(verbose_name='Mirror', level=ADVANCED, fields={
-                'mirror_tgt': AssoField2(verbose_name=_('Virtual Switch Mirror'), tgt='network.vswitch.VirtualSwitchMirror.vs_name',
-                       monitorable=True, mul='1', comp={}, pos='left', editable=True, optional=True),
+        'mirror_tgt': AssoField2(verbose_name=_('Virtual Switch Mirror'),
+                                 tgt='network.vswitch.VirtualSwitchMirror.vs_name',
+                                 monitorable=True, mul='1', comp={}, pos='left', editable=True, optional=True),
     })
 
     class Meta:
@@ -42,7 +60,12 @@
     class Manager(CLIManager):
         def _get_query_set(self):
             self.cli.set_enable()
-            output = self.cli.cmd('show switch config')
+            # Get the switch configuration
+            config_cmd_output = self.cli.cmd('show switch config')
+
+            # Parse the switch configuration
+            switch_arr = cli_parse(config_cmd_output, EasyParser('switch name', ['?name']))
+
             """
                 AN#show switch config
                 # Switch Tune Configuration
@@ -66,54 +89,137 @@
                 # Native-mode Virtual Switch Configuration
                 switch name s1
                 switch name test
+
+                switch name vs1:
+
+                AN#show switch status
+                switch name vs3:
+                    port3:
+                        Link detected: no
+                        Speed: Unknown!
+                switch name vs2:
+                    port2:
+                        Link detected: no
+                        Speed: Unknown!
+                    port1:
+                        Link detected: yes
+                        Speed: 10000Mb/s
+                    bond0:
+                        port4:
+                            Link detected: no
+                            Speed: Unknown!
+                        port5:
+                            Link detected: no
+                            Speed: Unknown!
             """
-            result = cli_parse(output, EasyParser('switch name', ['?name']))
-            if output.find('switch tune off') != -1:
-                for each in result:
+            if config_cmd_output.find('switch tune off') != -1:
+                for each in switch_arr:
                     each['mode'] = 'Native'
                     self._model._meta.mark_delay_query(each)
             else:
-                output2 = output.split('# Native-mode Virtual Switch Configuration')[1]
+                output2 = config_cmd_output.split('# Native-mode Virtual Switch Configuration')[1]
                 result2 = cli_parse(output2, EasyParser('switch name', ['?name']))
-                for each in result:
+                for each in switch_arr:
                     each['mode'] = 'Tune'
                     for each2 in result2:
                         if each['name'] == each2['name']:
                             each['mode'] = 'Native'
-                    self._model._meta.mark_delay_query(each)                
-            return QuerySet(self._model, result) 
-			
-        @QueryingFields(['stp','priority'])
-        def _get_stp_setting(self,pk_dict):
-            self.cli.set_enable()
-            result = self.cli.cmd('show switch stp', EasyParser('switch stp', ['?name', '?priority']))
+                    self._model._meta.mark_delay_query(each)
 
-            data={}
-            data['name'] = pk_dict['name']
-            data['stp'] = False
-            if result:
-                for each in result:
-                    if each['name'] == pk_dict['name']:
-                        data['stp'] = True
-                        data['priority'] = each['priority']
-                        break
-            return data
+            # Get the switch status
+            status_cmd_output = self.cli.cmd('show switch status')
 
-        @UpdatingFields(['stp','priority'])
-        def _update_stp_setting(self,instance):
+            # Regex pattern to capture switch, port, and bond details
+            # Regex pattern to capture switch, port, and bond details
+            pattern = re.compile(
+                r'switch name (\S+):'  # Match switch name
+                r'((?:\s+(\S+):\s+Link detected:\s+(\S+)\s*(?:Speed:\s+(\S+))?)*)'  # Match ports with optional speed
+                r'(?:\s+(bond\d+):'  # Match bond name
+                r'((?:\s+(\S+):\s+Link detected:\s+(\S+)\s*(?:Speed:\s+(\S+))?)*)'  # Match bond ports with optional speed
+                r')?'
+            )
+
+            # Find all matches in the output
+            matches = pattern.findall(status_cmd_output)
+            andebug('an.model.cli', 'Matches: {}'.format(matches))
+
+            # Process the matches and prepare the result
+            status_cmd_result = {}
+
+            for match in matches:
+                switch_name = match[0]
+                switch_info = match[1]
+
+                # Initialize switch entry if not already present
+                if switch_name not in status_cmd_result:
+                    status_cmd_result[switch_name] = {
+                        'switch_name': switch_name,
+                        'ports': [],  # List to hold port information
+                        'bonds': []  # List to hold bond information
+                    }
+
+                # Find port details within the matched switch block
+                ports_pattern = re.compile(r'(\S+):\s+Link detected:\s+(\S+)\s+Speed:\s+(\S+)')
+                ports = re.findall(ports_pattern, switch_info)
+                if ports:
+                    for port in ports:
+                        port_name = port[0]
+                        link_detected = port[1]
+                        port_status = 'Up' if link_detected == 'yes' else 'Down'
+                        status_cmd_result[switch_name]['ports'].append({
+                            'port_name': port_name,
+                            'link_status': port_status
+                        })
+
+                # Check for bond information in match[5] and process bond ports
+                bond_name = match[5]
+                bond_info = match[6]
+
+                if bond_name and bond_info:
+                    bond_ports = re.findall(ports_pattern, bond_info)
+                    bond_result = {
+                        'bond_name': bond_name,
+                        'ports_info': []
+                    }
+                    for bond_port in bond_ports:
+                        bond_port_name = bond_port[0]
+                        bond_link_detected = bond_port[1]
+                        bond_result['ports_info'].append({
+                            'port_name': bond_port_name,
+                            'link_status': 'Up' if bond_link_detected == 'yes' else 'Down'
+                        })
+                    status_cmd_result[switch_name]['bonds'].append(bond_result)
+
+            # Combine results
+            result = []
+            for switch in switch_arr:
+                switch_name = switch['name']
+                switch_info = status_cmd_result.get(switch_name, {})
+                switch_result = {
+                    'name': switch_name,
+                    'mode': switch['mode'],
+                    'ports': switch_info.get('ports', []),
+                    'bonds': switch_info.get('bonds', [])
+                }
+                result.append(switch_result)
+
+            return QuerySet(self._model, result)
+
+        @UpdatingFields(['stp', 'priority'])
+        def _update_stp_setting(self, instance):
             self.cli.set_config()
             if instance.stp == True:
-                result = self.cli.cmd('switch stp "%s" %u' % (instance.name, instance.priority), 
-                                   BlankParser(nonblank_exception=CLICmdError, supplement=True))
+                result = self.cli.cmd('switch stp "%s" %u' % (instance.name, instance.priority),
+                                      BlankParser(nonblank_exception=CLICmdError, supplement=True))
             elif instance.stp == False:
-                result = self.cli.cmd('no switch stp "%s"' % instance.name, 
-                                   BlankParser(nonblank_exception=CLICmdError, supplement=True))
+                result = self.cli.cmd('no switch stp "%s"' % instance.name,
+                                      BlankParser(nonblank_exception=CLICmdError, supplement=True))
             return
 
         def _get_interfaces(self, pk_dict):
             self.cli.set_enable(force=True)
             result = self.cli.cmd('show switch config',
-                                    EasyParser('switch interface %s' % pk_dict['name'], ['?interface_name']))
+                                  EasyParser('switch interface %s' % pk_dict['name'], ['?interface_name']))
             return result
 
         def _update_interfaces(self, instance, old_values):
@@ -123,57 +229,64 @@
                 if each not in old_values['interfaces']:
                     output = self.cli.cmd('switch interface "%s" "%s"' % (new_values['name'], each['interface_name']))
                     if output:
-                        roll_back_list = [each_interface for roll_back_index, each_interface in enumerate(new_values['interfaces']) if roll_back_index < index]
+                        roll_back_list = [each_interface for roll_back_index, each_interface in
+                                          enumerate(new_values['interfaces']) if roll_back_index < index]
                         for item in roll_back_list:
                             if item not in old_values['interfaces']:
-                                self.cli.cmd('no switch interface "%s" "%s"' % (new_values['name'], item['interface_name']),
-                                            BlankParser(nonblank_exception=CLICmdError, supplement=True))
+                                self.cli.cmd(
+                                    'no switch interface "%s" "%s"' % (new_values['name'], item['interface_name']),
+                                    BlankParser(nonblank_exception=CLICmdError, supplement=True))
                         raise ModelQueryException(CLICmdError(__(output)))
             for each in old_values['interfaces']:
-                if each not in new_values['interfaces']:                    
+                if each not in new_values['interfaces']:
                     self.cli.cmd('no switch interface "%s" "%s"' % (new_values['name'], each['interface_name']),
-                                BlankParser(nonblank_exception=CLICmdError, supplement=True))
-
+                                 BlankParser(nonblank_exception=CLICmdError, supplement=True))
 
         def _insert(self, instance):
             self.cli.set_config()
-            result = self.cli.cmd('switch name "%s"'%instance.name, 
-                                   BlankParser(nonblank_exception=CLICmdError, supplement=True))
-								   
+            result = self.cli.cmd('switch name "%s"' % instance.name,
+                                  BlankParser(nonblank_exception=CLICmdError, supplement=True))
+
             return
-			
+
         def _delete(self, pk_list):
             self.cli.set_config()
             for each in pk_list:
-                result = self.cli.cmd('no switch name "%s"'%each['name'],
-                                   BlankParser(nonblank_exception=CLICmdError, supplement=True))
-								   
+                result = self.cli.cmd('no switch name "%s"' % each['name'],
+                                      BlankParser(nonblank_exception=CLICmdError, supplement=True))
+
             return
-			
+
+
 class VirtualSwitchVA(ANModel):
     vs_name = AssoField2(verbose_name=_('Virtual Switch Name'), tgt='network.vswitch.VirtualSwitch.va_tgt',
-                              monitorable=True, mul='*', comp={}, pos='right', primary_key=True)
+                         monitorable=True, mul='*', comp={}, pos='right', primary_key=True)
     va = AssoField2(verbose_name=_('VA Instance Name'), tgt='va.instance.VAInstance.va_vswitch',
-                              monitorable=True, mul='*', comp={}, pos='left', primary_key=True)
-    vport = CharField(verbose_name=_('VPort Name'), primary_key=True, pattern='^vport([0-9]+)$', pattern_msg='Virtual port name should be in the range from vport1 to vportN')
+                    monitorable=True, mul='*', comp={}, pos='left', primary_key=True)
+    vport = CharField(verbose_name=_('VPort Name'), primary_key=True, pattern='^vport([0-9]+)$',
+                      pattern_msg='Virtual port name should be in the range from vport1 to vportN')
     tag = IntegerField(verbose_name=_('VLAN Tag'), default=0, optional=True, editable=True)
-    number = IntegerField(verbose_name=_('Number of Enabled Queues'), default=1, help_text='The value can not be greater than the number of vCPUs assigned to the VA instance.', optional=True)
+    number = IntegerField(verbose_name=_('Number of Enabled Queues'), default=1,
+                          help_text='The value can not be greater than the number of vCPUs assigned to the VA instance.',
+                          optional=True)
 
     class Meta:
-        verbose_name=_('VA Instance Binding')
-    
+        verbose_name = _('VA Instance Binding')
+
     class Manager(CLIManager):
         def _get_query_set(self):
             self.cli.set_enable()
-            result = self.cli.cmd('show switch config', 
-                                    RegexParser('switch va (?P<vs_name>.*?) (?P<va>.*?) (?P<vport>\w+) (?P<tag>[0-9]+) (?P<number>[0-9]+)', MATCHALL))
-			
+            result = self.cli.cmd('show switch config',
+                                  RegexParser(
+                                      'switch va (?P<vs_name>.*?) (?P<va>.*?) (?P<vport>\w+) (?P<tag>[0-9]+) (?P<number>[0-9]+)',
+                                      MATCHALL))
+
             for each_result in result:
-                each_result['vs_name'] = [{'name':each_result['vs_name']}]
-                each_result['va'] = [{'va_name':each_result['va']}]
-				
+                each_result['vs_name'] = [{'name': each_result['vs_name']}]
+                each_result['va'] = [{'va_name': each_result['va']}]
+
             return QuerySet(self._model, result)
-			
+
         def _insert(self, instance):
             data = instance.get_field_dict()
             self.cli.set_config()
@@ -183,17 +296,20 @@
                                   RegexParser('has been assigned to VA', match_exception=CLICmdNormal, exclusive=True),
                                   BlankParser(nonblank_exception=CLICmdError, supplement=True))
             return result
-            
+
         def _delete(self, pk_list):
             self.cli.set_config()
             for data in pk_list:
                 data['vs_name'] = data['vs_name'][0]['name']
                 data['va'] = data['va'][0]['va_name']
                 result = self.cli.cmd('no switch va "%(vs_name)s" "%(va)s" %(vport)s\nYES\n' % data,
-                                  RegexParser('has been deleted from VA', match_exception=CLICmdNormal, exclusive=True),
-                                  RegexParser('System error occurred.', MATCHALL, match_exception=CLICmdError, match_msg=__('System error occurred.')),
-                                  RegexParser('The VA has been running', MATCHALL, match_exception=CLICmdError, match_msg=__('The VA has been running.')),
-                                  BlankParser(nonblank_exception=CLICmdError, supplement=True))
+                                      RegexParser('has been deleted from VA', match_exception=CLICmdNormal,
+                                                  exclusive=True),
+                                      RegexParser('System error occurred.', MATCHALL, match_exception=CLICmdError,
+                                                  match_msg=__('System error occurred.')),
+                                      RegexParser('The VA has been running', MATCHALL, match_exception=CLICmdError,
+                                                  match_msg=__('The VA has been running.')),
+                                      BlankParser(nonblank_exception=CLICmdError, supplement=True))
             mark_expire_all(VirtualSwitchMirror)
             return result
 
@@ -202,29 +318,34 @@
             result = self.cli.cmd('switch vlan %s %d' % (instance.vport, instance.tag),
                                   BlankParser(nonblank_exception=CLICmdError, supplement=True))
             return
-			
+
+
 class VirtualSwitchMirror(ANModel):
     vs_name = AssoField2(verbose_name=_('Virtual Switch Name'), tgt='network.vswitch.VirtualSwitch.mirror_tgt',
-                              monitorable=True, mul='*', comp={}, pos='right', primary_key=True)
-    vport_dst = CharField(verbose_name=_('Desination VPort'),pattern='^vport([0-9]+)$', pattern_msg='Virtual port name should be in the range from vport1 to vportN')
-    vport_src = CharField(verbose_name=_('Source VPort'),pattern='^vport([0-9]+)$', pattern_msg='Virtual port name should be in the range from vport1 to vportN')
+                         monitorable=True, mul='*', comp={}, pos='right', primary_key=True)
+    vport_dst = CharField(verbose_name=_('Desination VPort'), pattern='^vport([0-9]+)$',
+                          pattern_msg='Virtual port name should be in the range from vport1 to vportN')
+    vport_src = CharField(verbose_name=_('Source VPort'), pattern='^vport([0-9]+)$',
+                          pattern_msg='Virtual port name should be in the range from vport1 to vportN')
     mode = EnumField(verbose_name=_('Mirror Mode'), values=(
-                                    ('0', '0', 'Mirror all packets of the mirror source vport'),
-                                    ('1', '1', 'Mirror incoming packets sent of the mirror source vport'),
-                                    ('2', '2', 'Mirror outgoing packets the mirror source vport'),                                    
-                ))
-				
+        ('0', '0', 'Mirror all packets of the mirror source vport'),
+        ('1', '1', 'Mirror incoming packets sent of the mirror source vport'),
+        ('2', '2', 'Mirror outgoing packets the mirror source vport'),
+    ))
+
     class Meta:
         verbose_name = _('Mirror')
 
     class Manager(CLIManager):
         def _get_query_set(self):
             self.cli.set_enable()
-            result = self.cli.cmd('show switch mirror', 
-                                    RegexParser('switch mirror (?P<vs_name>.*?) (?P<vport_dst>\w+) (?P<vport_src>\w+) (?P<mode>0|1|2)', MATCHALL))
+            result = self.cli.cmd('show switch mirror',
+                                  RegexParser(
+                                      'switch mirror (?P<vs_name>.*?) (?P<vport_dst>\w+) (?P<vport_src>\w+) (?P<mode>0|1|2)',
+                                      MATCHALL))
 
             return QuerySet(self._model, result)
-			
+
         def _insert(self, instance):
             data = instance.get_field_dict()
             self.cli.set_config()
@@ -232,18 +353,18 @@
             result = self.cli.cmd('switch mirror "%(vs_name)s" "%(vport_dst)s" %(vport_src)s %(mode)s' % data,
                                   BlankParser(nonblank_exception=CLICmdError, supplement=True))
             return result
-            
+
         def _delete(self, pk_list):
             self.cli.set_config()
             for data in pk_list:
                 data['vs_name'] = data['vs_name'][0]['name']
                 result = self.cli.cmd('no switch mirror "%(vs_name)s"' % data,
-                                  BlankParser(nonblank_exception=CLICmdError, supplement=True))
+                                      BlankParser(nonblank_exception=CLICmdError, supplement=True))
             return result
 
 
 class VirtualSwitchGlobalSettings(ANModel):
-    enable = BooleanField(verbose_name='Enable', lexical=('on','off'))
+    enable = BooleanField(verbose_name='Enable', lexical=('on', 'off'))
     native_queue_size = IntegerField(verbose_name='Native-mode Quene Size', scope='256..16384', default=256)
     tune_queue_size = IntegerField(verbose_name='Tune-mode Quene Size', scope='256..16384', default=1024)
 
@@ -271,25 +392,24 @@
         profile = True
         verbose_name = ('Virtual Switch')
         show_im_export_button = False
-        
 
     class Manager(CLIManager):
         def _get_query_set(self):
             self.cli.set_config()
             result1 = self.cli.cmd('show switch config',
-                         RegexParser('switch tune (?P<enable>on|off)', MATCHONE),
-                )
+                                   RegexParser('switch tune (?P<enable>on|off)', MATCHONE),
+                                   )
             result2 = self.cli.cmd('show system tune vportqueue',
-                         RegexParser('system tune vportqueue native (?P<native_queue_size>[0-9]+)', MATCHONE),
-                         RegexParser('system tune vportqueue tune (?P<tune_queue_size>[0-9]+)', MATCHONE),
-                )
+                                   RegexParser('system tune vportqueue native (?P<native_queue_size>[0-9]+)', MATCHONE),
+                                   RegexParser('system tune vportqueue tune (?P<tune_queue_size>[0-9]+)', MATCHONE),
+                                   )
             data = {
                 'enable': True if result1['enable'] == 'on' else False,
                 'native_queue_size': result2[0]['native_queue_size'],
                 'tune_queue_size': result2[1]['tune_queue_size']
             }
             self._model._meta.mark_delay_query(data)
-            return QuerySet(self._model, [data]) 
+            return QuerySet(self._model, [data])
 
         def _update_enable(self, instance, old_values):
             if instance.enable == old_values['enable']:
@@ -297,9 +417,12 @@
             self.cli.set_config()
             on_or_off = 'on' if instance.enable else 'off'
             result = self.cli.cmd('switch tune %s\nYES\n' % on_or_off,
-                                  RegexParser('no CPU thread is assigned', MATCHONE, match_exception=CLICmdError, exclusive=True),
-                                  RegexParser('has not been cleared', MATCHONE, match_exception=CLICmdError, exclusive=True),
-                                  RegexParser('Enter "YES" to confirm the operation', match_exception=CLICmdNormal, exclusive=True),
+                                  RegexParser('no CPU thread is assigned', MATCHONE, match_exception=CLICmdError,
+                                              exclusive=True),
+                                  RegexParser('has not been cleared', MATCHONE, match_exception=CLICmdError,
+                                              exclusive=True),
+                                  RegexParser('Enter "YES" to confirm the operation', match_exception=CLICmdNormal,
+                                              exclusive=True),
                                   BlankParser(nonblank_exception=CLICmdError, supplement=True))
             return
 
@@ -336,20 +459,20 @@
 
 class CPUBorrow(ANModel):
     domain = EnumField(verbose_name=_("Domain"), values=(
-                (1, 1),
-                (2, 2),
-            ), primary_key=True)
+        (1, 1),
+        (2, 2),
+    ), primary_key=True)
     cpu_thread = EnumField(verbose_name=_("Number of CPU threads"), values=(
-                (1, 1),
-                (2, 2),
-                (4, 4),
-                (8, 8),
-            ), optional=True)
+        (1, 1),
+        (2, 2),
+        (4, 4),
+        (8, 8),
+    ), optional=True)
     cpu_thread_total = IntegerField(verbose_name=_('CPU threads'), configurable=False, default=0)
 
     class Meta:
         verbose_name = _('System Tune Switch CPU Borrow')
-        
+
     class Manager(CLIManager):
         def _get_query_set(self):
             self.cli.set_enable()
@@ -360,5 +483,6 @@
             Total: 2
             """
             result = self.cli.cmd('show system tune switch cpuborrow',
-                  RegexParser('Domain(?P<domain>[1|2]): (?P<cpu_thread_total>[0-9]+)', MATCHALL, reflags=re.S))
-            return  QuerySet(self._model, result)
+                                  RegexParser('Domain(?P<domain>[1|2]): (?P<cpu_thread_total>[0-9]+)', MATCHALL,
+                                              reflags=re.S))
+            return QuerySet(self._model, result)
\ No newline at end of file
Index: /branches/rel_avx_2_7_2/src/webui/webui/htdocs/new/src/client/app/modules/network/submenu/virtual_switch/vs_list.html
===================================================================
--- /branches/rel_avx_2_7_2/src/webui/webui/htdocs/new/src/client/app/modules/network/submenu/virtual_switch/vs_list.html	(revision 8858)
+++ /branches/rel_avx_2_7_2/src/webui/webui/htdocs/new/src/client/app/modules/network/submenu/virtual_switch/vs_list.html	(working copy)
@@ -1,4 +1,4 @@
-<div class="container-fluid"> 
+<div class="container-fluid">
     <div class="row">
         <rd-widget>
             <rd-widget-header title="{{'Virtual Switch'|T}}">
@@ -6,8 +6,10 @@
             <div class="table-toolbar">
                 <div class="">
                     <div class="btn-group">
-                        <button title="{{'Refresh'|T}}" class="btn btn-link hive_enable_active" ng-click="virtualSwitch.refreshVirtualSwitch()"><i class="fa fa-refresh"></i></button>
-                        <button title="{{'Add Virtual Switch'|T}}" class="btn btn-link" ng-click="virtualSwitch.addVirtualSwitch()"><i class="fa fa-plus-circle"></i></button>
+                        <button title="{{'Refresh'|T}}" class="btn btn-link hive_enable_active"
+                                ng-click="virtualSwitch.refreshVirtualSwitch()"><i class="fa fa-refresh"></i></button>
+                        <button title="{{'Add Virtual Switch'|T}}" class="btn btn-link"
+                                ng-click="virtualSwitch.addVirtualSwitch()"><i class="fa fa-plus-circle"></i></button>
                     </div>
                 </div>
                 <div class="btn-group pull-right"></div>
@@ -20,12 +22,14 @@
                             <th>#</th>
                             <th st-sort="name">{{'Virtual Switch Name'|T}}</th>
                             <th st-sort="mode">{{'Mode'|T}}</th>
+                            <th>{{'Link Status'}}</th>
                             <th>{{'Action'|T}}</th>
                         </tr>
                         <tr>
                             <th></th>
                             <th>
-                                <input st-search="name" placeholder="{{'Search by Name'|T}}" class="input-sm form-control" type="search"/>
+                                <input st-search="name" placeholder="{{'Search by Name'|T}}"
+                                       class="input-sm form-control" type="search"/>
                             </th>
                             <th></th>
                             <th></th>
@@ -34,18 +38,44 @@
                         <tbody>
                         <tr ng-repeat="row in displayedCollection">
                             <td>{{$index + 1}}</td>
-                            <td><a ui-sref="index.network.virtual_switch.detail({name:row.name})" class="active">{{row.name}}</a></td>
+                            <td><a ui-sref="index.network.virtual_switch.detail({name:row.name})" class="active">{{row.name}}</a>
+                            </td>
                             <td>{{row.mode|T}}</td>
                             <td>
+                                <div ng-if="row.ports.length > 0 || row.bonds.length > 0"></div>
+                                <div ng-repeat="port in row.ports">
+                                    <div>
+                                        &nbsp;{{port.port_name|T}}: {{port.link_status|T}}
+                                    </div>
+                                    <br ng-if="!$last"/>
+                                </div>
+                                <div ng-repeat="bond in row.bonds">
+                                    <div>
+                                        &nbsp;{{bond.bond_name|T}}: <br>
+                                        <div ng-repeat="port_info in bond.ports_info">
+                                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{port_info.port_name|T}}:
+                                            {{port_info.link_status|T}}
+                                        </div>
+                                    </div>
+                                    <br ng-if="!$last"/>
+                                </div>
+                                <div ng-if="row.ports.length === 0 && row.bonds.length === 0">
+                                    {{'N/A'|T}}
+                                </div>
+                            </td>
+                            <td>
                                 <div class="btn-group">
-                                    <button ng-show="allow_config" title="{{'Delete'|T}}" class="btn btn-link" ng-click="virtualSwitch.delete(row.name)"><i class="fa fa-times-circle"></i></button>
+                                    <button ng-show="allow_config" title="{{'Delete'|T}}" class="btn btn-link"
+                                            ng-click="virtualSwitch.delete(row.name)"><i class="fa fa-times-circle"></i>
+                                    </button>
                                 </div>
                             </td>
                         </tr>
                         </tbody>
                     </table>
                 </div>
-                <div style="margin-bottom: 15px;text-align: center" ng-hide="virtualSwitch.virtualSwitchList"><img src="app/images/loading.gif"></div>
+                <div style="margin-bottom: 15px;text-align: center" ng-hide="virtualSwitch.virtualSwitchList"><img
+                    src="app/images/loading.gif"></div>
                 <div class="table-pagination">
                     <div class="pagination-detail"></div>
                     <div class="pagination" st-pagination="" st-items-by-page="10"></div>
Index: /branches/rel_avx_2_7_2/src/webui/webui/htdocs/new/src/hive/model/fields/builtin.py
===================================================================
--- /branches/rel_avx_2_7_2/src/webui/webui/htdocs/new/src/hive/model/fields/builtin.py	(revision 8858)
+++ /branches/rel_avx_2_7_2/src/webui/webui/htdocs/new/src/hive/model/fields/builtin.py	(working copy)
@@ -2105,3 +2105,53 @@
                 bias -= 1
         length = len(self.values)
         return self.values[bias%length][0]
+
+
+class PortFields(Field):
+    type_name = 'PortFields'
+
+    def __init__(self, verbose_name=None, **kwargs):
+        super(PortFields, self).__init__(verbose_name, **kwargs)
+        self.fields = {
+            'port_name': CharField(verbose_name=_('Port Name')),
+            'bond_name': CharField(verbose_name=_('Bond Name')),
+            'link_status': CharField(verbose_name=_('Link Status'))
+        }
+
+    def to_python(self, value):
+        if not isinstance(value, dict):
+            raise exceptions.ValidationError('PortFields value must be a dictionary')
+        for field_name, field in self.fields.items():
+            if field_name in value:
+                value[field_name] = field.to_python(value[field_name])
+        return value
+
+    def validate(self, value, model_instance):
+        if not isinstance(value, dict):
+            raise exceptions.ValidationError('PortFields value must be a dictionary')
+        for field_name, field in self.fields.items():
+            if field_name in value:
+                field.validate(value[field_name], model_instance)
+
+    def init_sub_fields(self):
+        for field_name, field in self.fields.items():
+            field._set_attributes_from_name(field_name)
+
+    def get_sub_fields(self):
+        return self.fields.values()
+
+    def value_to_rest(self, obj=None, val=None):
+        if val is None:
+            val = self._get_val_from_obj_or_val(obj)
+        return {field_name: field.value_to_rest(val=value) for field_name, field in self.fields.items() if
+                field_name in val}
+
+    def _value_to_display(self, obj=None, val=None, style=True, text=True):
+        if val is None:
+            val = self._get_val_from_obj_or_val(obj)
+        display_str = '<ul>' if style else ''
+        for field_name, field in self.fields.items():
+            if field_name in val:
+                display_str += '<li>{}: {}</li>'.format(field_name, field._value_to_display(val=val[field_name]))
+        display_str += '</ul>' if style else ''
+        return display_str
\ No newline at end of file
