Index: /branches/rel_apv_10_7/usr/click/webui/htdocs/new/src/apv/models/admintools/snmp/__init__.py
===================================================================
--- /branches/rel_apv_10_7/usr/click/webui/htdocs/new/src/apv/models/admintools/snmp/__init__.py	(revision 39674)
+++ /branches/rel_apv_10_7/usr/click/webui/htdocs/new/src/apv/models/admintools/snmp/__init__.py	(working copy)
@@ -254,8 +254,8 @@
         def _get_query_set(self):
             self.cli.set_enable()
             result = self.cli.cmd('show snmp',
-                         RegexParser('snmp host (?P<ip>[0-9|\.|:|a-f|A-F]+) (?P<version_id>1|2) "(?P<community>.*?)" "" "" "" "" (?P<port>\d+)', MATCHALL),
-                         RegexParser('snmp host (?P<ip>[0-9|\.|:|a-f|A-F]+) (?P<version_id>3) "(?P<username>.*?)" "(?P<engine_id>.*?)" "(?P<auth_password>.*?)" (?P<level>\w+) "(?P<priv_password>.*?)" (?P<port>\d+)', MATCHALL),                )
+                         RegexParser('snmp host (?P<ip>[0-9|\.|:|a-f|A-F]+) (?P<version_id>1|2) "(?P<community>.*?)"', MATCHALL),
+                         RegexParser('snmp host (?P<ip>[0-9|\.|:|a-f|A-F]+) (?P<version_id>3) "(?P<username>.*?)"', MATCHALL),)
             data = QuerySet(self._model)
             if result[0]:
                 for each  in result[0]:
@@ -278,10 +278,6 @@
                         each['ip'] = {'ipv6':each['ip']}
                     del each['version_id']
                     del each['username']
-                    del each['engine_id']
-                    del each['auth_password']
-                    del each['level']
-                    del each['priv_password']
                     SNMPV3Servers._meta.mark_delay_query(each)
             v3 = QuerySet(SNMPV3Servers, result[1])
             data.merge(v3)
@@ -298,6 +294,100 @@
                             BlankParser(nonblank_exception=CLICmdError, supplement=True))
             return
 
+        def get_data_by_version(self, cli, version):
+            cli.set_enable()
+            # handle Regex parsing string for different version
+            if version != '3':
+                # version 1 or 2
+                host_regex = 'snmp host (?P<ip>[0-9|\.|:|a-f|A-F]+) (?P<version_id>1|2) "(?P<community>.*?)"'
+            else:
+                # version 3
+                host_regex = 'snmp host (?P<ip>[0-9|\.|:|a-f|A-F]+) 3 "(?P<username>.*?)"'
+            result = cli.cmd('show snmp',
+                RegexParser(host_regex, MATCHALL),
+                RegexParser('snmp auth (?P<ip>\S+) (?P<auth_data>.*)', MATCHALL),
+            )
+            res_data = []
+            for each  in result[0]:
+                if version != '3':
+                    each['type'] = 'v1v2'
+                else:
+                    each['type'] = 'v3'
+                    each ['auth_password'] = '********'
+                """
+                Each auth info corresponds to one server info for version 3 is:
+                ip "engine_id" "auth_password" level "priv_password" port "auth_protocol" ["priv_protocol"]
+                so auth in for loop is:
+                "engine_id" "auth_password" level "priv_password" port "auth_protocol" ["priv_protocol"]
+                If level is authNopriv, there is no priv_protocol in CLI return
+                Besides, there is no "auth_protocol" ["priv_protocol"] for version 1 or 2 in auth info
+                """
+                for auth in result[1]:
+                    if each['ip'] == auth['ip']:
+                        if is_ipv4(each['ip']):
+                            each['ip'] = {'ipv4':each['ip']}
+                        else:
+                            each['ip'] = {'ipv6':each['ip']}
+                        auth_parts = auth['auth_data'].split()
+                        each['port'] = int(auth_parts[4])
+                        if version == '3':
+                            each['engine_id'] = auth_parts[0].strip('"')
+                            each['level'] = auth_parts[2]
+                            each['auth_protocol'] = auth_parts[5].strip('"')
+                            if each['level'] == 'authPriv':
+                                each['priv_password'] = '********'
+                            else:
+                                each['priv_password'] = ''
+                            if len(auth_parts) > 6:
+                                each['priv_protocol'] = auth_parts[6].strip('"')
+                            else:
+                                each['priv_protocol'] = ''
+                        break
+                res_data.append(each)
+                self._model._meta.mark_delay_query(each)
+            return res_data
+
+        def insert_by_version(self, cli, instance):
+            data = instance.get_field_dict()
+            data['ip_str'] = data['ip'].values()[0]
+            cli.set_config()
+            # handle CLI string for different version
+            if hasattr(instance, 'version_id') and instance.version_id != '3':
+                # version 1 or 2
+                host_cli = 'snmp host %(ip_str)s %(version_id)s "%(community)s"' % data
+            else:
+                # version 3
+                host_cli = 'snmp host %(ip_str)s 3 "%(username)s"' % data
+            cli.cmd(host_cli,
+                    BlankParser(nonblank_exception=CLICmdError, supplement=True, ignore_msg=["please run \"snmp auth\" for trap version 3 to be functional"]))
+            # handle auth CLI param for different version
+            auth_data = [
+                '%(ip_str)s',
+                '"%(engine_id)s"',
+                '"%(auth_password)s"',
+                '%(level)s',
+                '"%(priv_password)s"',
+                '%(port)u',
+            ]
+            if hasattr(instance, 'engine_id') and instance.engine_id:
+                # version 3
+                auth_data.append('%(auth_protocol)s')
+                auth_data.append('%(priv_protocol)s')
+                if data['level'] == 'authNopriv':
+                    data['priv_password'] = ''
+                    data['priv_protocol'] = ''
+            else:
+                # version 1 or 2
+                data['engine_id'] = ''
+                data['auth_password'] = ''
+                data['level'] = ''
+                data['priv_password'] = ''
+            auth_param = " ".join(auth_data)
+            result = cli.cmd('snmp auth {cli_param}'.format(cli_param=auth_param).strip() % data,
+                            RegexParser("the length of authoritative engine id for SNMPv3 can't be odd number", match_msg=__("The length of Authoritative Engine ID for SNMPv3 cannot be an odd number."), match_exception=CLICmdWarning, exclusive=True),
+                            BlankParser(nonblank_exception=CLICmdError, supplement=True, ignore_msg=["Warning: This command only applicable for SNMP trap version v3!"]))
+            return result
+
 class SNMPV1V2Servers(Server):
     type = DerivedField(value='v1v2')
     version_id = EnumField(verbose_name='Version ID',values=(
@@ -311,28 +401,16 @@
 
     class Manager(CLIManager):
         def _get_query_set(self):
-            self.cli.set_enable()
-            result = self.cli.cmd('show snmp',
-                         RegexParser('snmp host (?P<ip>[0-9|\.|:|a-f|A-F]+) (?P<version_id>1|2) "(?P<community>.*?)" "" "" "" "" (?P<port>\d+)', MATCHALL),
-                )
-            for each  in result:
-                each['type'] = 'v1v2'
-                if is_ipv4(each['ip']):
-                    each['ip'] = {'ipv4':each['ip']}
-                else:
-                    each['ip'] = {'ipv6':each['ip']}
-                self._model._meta.mark_delay_query(each)
-            return QuerySet(self._model, result)
+            server_manager = Server.get_manager(self._session)
+            res_data = server_manager.get_data_by_version(self.cli, '1or2')
+            return QuerySet(self._model, res_data)
 
         def _filter(self, filter_dict):
             return self.all()
 
         def _insert(self, instance):
-            data = instance.get_field_dict()
-            data['ip_str'] = data['ip'].values()[0]
-            self.cli.set_config()
-            result = self.cli.cmd('snmp host %(ip_str)s %(version_id)s "%(community)s" "" "" "" "" %(port)u' % data,
-                            BlankParser(nonblank_exception=CLICmdError, supplement=True))
+            server_manager = Server.get_manager(self._session)
+            result = server_manager.insert_by_version(self.cli, instance)
             return result
 
 
@@ -362,39 +440,16 @@
 
     class Manager(CLIManager):
         def _get_query_set(self):
-            self.cli.set_enable()
-            result = self.cli.cmd('show snmp', EasyParser('snmp host', ['?ip', '=3', '?username', '?engine_id', '?auth_password', '?level', '?priv_password','?port','?auth_protocol','?priv_protocol']))
-            res_data = []
-            for each in result:
-                each['type'] = 'v3'
-                each ['auth_password'] = '********'
-                if is_ipv4(each['ip']):
-                    each['ip'] = {'ipv4':each['ip']}
-                else:
-                    each['ip'] = {'ipv6':each['ip']}
-                if 'priv_password' not in each:
-                    each['priv_password'] = ''
-                else:
-                    each['priv_password'] = '********'
-                res_data.append(each)
-                self._model._meta.mark_delay_query(each)
+            server_manager = Server.get_manager(self._session)
+            res_data = server_manager.get_data_by_version(self.cli, '3')
             return QuerySet(self._model, res_data)
 
         def _filter(self, filter_dict):
             return self.all()
 
         def _insert(self, instance):
-            data = instance.get_field_dict()
-            data['ip_str'] = data['ip'].values()[0]
-            self.cli.set_config()
-            if data['level'] == 'authNopriv':
-                result = self.cli.cmd('snmp host %(ip_str)s 3 "%(username)s" "%(engine_id)s" "%(auth_password)s" %(level)s "" %(port)u  %(auth_protocol)s' % data,
-                                RegexParser("the length of authoritative engine id for SNMPv3 can't be odd number", match_msg=__("The length of Authoritative Engine ID for SNMPv3 cannot be an odd number."), match_exception=CLICmdWarning, exclusive=True),
-                                BlankParser(nonblank_exception=CLICmdError, supplement=True))
-            else:
-                result = self.cli.cmd('snmp host %(ip_str)s 3 "%(username)s" "%(engine_id)s" "%(auth_password)s" %(level)s "%(priv_password)s" %(port)u %(auth_protocol)s %(priv_protocol)s' % data,
-                                RegexParser("the length of authoritative engine id for SNMPv3 can't be odd number", match_msg=__("The length of Authoritative Engine ID for SNMPv3 cannot be an odd number."), match_exception=CLICmdWarning, exclusive=True),
-                                BlankParser(nonblank_exception=CLICmdError, supplement=True))
+            server_manager = Server.get_manager(self._session)
+            result = server_manager.insert_by_version(self.cli, instance)
             return result
 
 
