]> git.proxmox.com Git - mirror_ifupdown2.git/commitdiff
addons: mstpctl: reset (default) bridge mstpctl options when users remove settings
authorNikhil <nikhil@cumulusnetworks.com>
Wed, 7 Dec 2016 17:53:33 +0000 (09:53 -0800)
committerNikhil <nikhil@cumulusnetworks.com>
Wed, 18 Jan 2017 01:19:54 +0000 (17:19 -0800)
Ticket: CM-8401
Reviewed By: Roopa, Julien
Testing Done: tested on all bridge mstpctl attributes.

This patch resets th following bridge attributes to defauls when
users remove settings from interface config file.

mstpctl-treeprio
mstpctl-ageing
mstpctl-fdelay
mstpctl-maxhops
mstpctl-maxage
mstpctl-txholdcount
mstpctl-forcevers
mstpctl-hello

Added an api in policy manager to get policy default value of any
module attribute.

Added a cache for bridge attributes to save some runtime

Signed-off-by: Nikhil <nikhil@cumulusnetworks.com>
addons/mstpctl.py
ifupdown/policymanager.py
ifupdownaddons/mstpctlutil.py

index 54f659d9abcfb79c415c569477bdb18ab48ba146..707103ecb4da3937315415cd77895b72f85bffaa 100644 (file)
@@ -144,7 +144,7 @@ class mstpctl(moduleBase):
                           'validrange' : ['0', '255'],
                           'default' : '2',
                           'required' : False,
-                          'jsonAttr': 'portHelloTime',
+                          'jsonAttr': 'helloTime',
                           'example' : ['mstpctl-hello 2']},
                     'mstpctl-portnetwork' : 
                         { 'help' : 'enable/disable bridge assurance capability for a port',
@@ -329,16 +329,32 @@ class mstpctl(moduleBase):
         try:
             # set bridge attributes
             for attrname, dstattrname in self._attrs_map.items():
+                config_val = ifaceobj.get_attr_value_first(attrname)
+                default_val = policymanager.policymanager_api.get_iface_default(module_name=self.__class__.__name__, ifname=ifaceobj.name, attr=attrname)
+                if not default_val:
+                    default_val = self.get_mod_subattr(attrname,'default')
+                jsonAttr =  self.get_mod_subattr(attrname, 'jsonAttr')
+                try:
+                    running_val = self.mstpctlcmd.get_bridge_attr(
+                                    ifaceobj.name, jsonAttr)
+                except:
+                    self.logger.info('%s: could not get running %s value'
+                                     %(ifaceobj.name, attrname))
+                    running_val = None
+                if (not config_val and default_val and (running_val != default_val)):
+                    # this happens when users remove an attribute from a port
+                    # and expect the default to be restored with ifreload.
+                    config_val = default_val
+                elif not config_val:
+                    # there is nothing configured and no default to reset
+                    continue
                 try:
-                    v = ifaceobj.get_attr_value_first(attrname)
-                    if not v:
-                       continue
                     if attrname == 'mstpctl-treeprio':
                        self.mstpctlcmd.set_bridge_treeprio(ifaceobj.name,
-                                v, check)
+                                config_val, check)
                     else:
                        self.mstpctlcmd.set_bridge_attr(ifaceobj.name,
-                                dstattrname, v, check)
+                                dstattrname, config_val, check)
                 except Exception, e:
                     self.logger.warn('%s' %str(e))
                     pass
@@ -415,7 +431,10 @@ class mstpctl(moduleBase):
             else:
                 return 'yes'
         else:
-            return self.get_mod_subattr(attr,'default')
+            default_val = policymanager.policymanager_api.get_iface_default(module_name=self.__class__.__name__, ifname=ifaceobj.name, attr=attr)
+            if not default_val:
+                return self.get_mod_subattr(attr,'default')
+            return default_val
 
     def _apply_bridge_port_settings(self, ifaceobj, bridgename=None,
                                     bridgeifaceobj=None,
index b5f31233fd8f185b7135f10d172d54c1a2f3b373..c624c18318c6a0c276d33b919be8c8933f33b753 100644 (file)
@@ -210,4 +210,5 @@ class policymanager():
 
         return mod_array
 
+
 policymanager_api = policymanager()
index 1b069b5cc10e14a3ea7878de3382df76d4278f3a..c9dcee9e730a489effa20639be22797867f14c5c 100644 (file)
@@ -28,6 +28,17 @@ class mstpctlutil(utilsBase):
                      'hello' : 'hello-time',
                      'forcevers' : 'force-protocol-version'}
 
+    _bridge_jsonAttr_map = {
+                            'treeprio': 'bridgeId',
+                            'maxage': 'maxAge',
+                            'fdelay': 'fwdDelay',
+                            'txholdcount': 'txHoldCounter',
+                            'maxhops': 'maxHops',
+                            'ageing': 'ageingTime',
+                            'hello': 'helloTime',
+                            'forcevers': 'forceProtocolVersion',
+                            }
+
     _bridgeportattrmap = {'portadminedge' : 'admin-edge-port',
                      'portp2p' : 'admin-point-to-point',
                      'portrestrrole' : 'restricted-role',
@@ -83,6 +94,33 @@ class mstpctlutil(utilsBase):
             self.logger.info('%s: cannot fetch mstpctl bridge port attributes: %s' % str(e))
         return mstpctl_bridgeport_attrs_dict
 
+    def _get_bridge_attrs_from_cache(self, bridgename):
+        attrs = MSTPAttrsCache.get(bridgename)
+        if attrs:
+            return attrs
+        mstpctl_bridge_attrs_dict = {}
+        try:
+            cmd = ['/sbin/mstpctl', 'showbridge', 'json', bridgename]
+            output = utils.exec_commandl(cmd)
+            if not output:
+                return mstpctl_bridge_attrs_dict
+        except Exception as e:
+            self.logger.info(str(e))
+            return mstpctl_bridge_attrs_dict
+        try:
+            mstpctl_bridge_cache = json.loads(output.strip('\n'))
+            for jsonAttr in mstpctl_bridge_cache[bridgename].keys():
+                mstpctl_bridge_attrs_dict[jsonAttr] = (
+                    str(mstpctl_bridge_cache[bridgename][jsonAttr]))
+            mstpctl_bridge_attrs_dict['treeprio'] = '%d' %(
+                                   int(mstpctl_bridge_attrs_dict.get('bridgeId',
+                                   '').split('.')[0], base=16) * 4096)
+            del mstpctl_bridge_attrs_dict['bridgeId']
+            MSTPAttrsCache.set(bridgename, mstpctl_bridge_attrs_dict)
+        except Exception as e:
+            self.logger.info('%s: cannot fetch mstpctl bridge attributes: %s' % str(e))
+        return mstpctl_bridge_attrs_dict
+
     def get_bridge_ports_attrs(self, bridgename):
         return self._get_bridge_port_attrs_from_cache(bridgename)
 
@@ -93,7 +131,7 @@ class mstpctlutil(utilsBase):
             return 'yes'
         return str(value)
 
-    def update_cache(self, bridgename, portname, attrname, value):
+    def update_bridge_port_cache(self, bridgename, portname, attrname, value):
         attrs = self.get_bridge_ports_attrs(bridgename)
         if not attrs:
             attrs = {}
@@ -102,6 +140,13 @@ class mstpctlutil(utilsBase):
         attrs[portname][attrname] = value
         MSTPAttrsCache.set(bridgename, attrs)
 
+    def update_bridge_cache(self, bridgename, attrname, value):
+        attrs = self.get_bridge_ports_attrs(bridgename)
+        if not attrs:
+            attrs = {}
+        attrs[attrname] = value
+        MSTPAttrsCache.set(bridgename, attrs)
+
     def set_bridge_port_attr(self, bridgename, portname, attrname, value, json_attr=None):
         cache_value = self.get_bridge_port_attr(bridgename, portname, json_attr)
         if cache_value and cache_value == value:
@@ -113,16 +158,13 @@ class mstpctlutil(utilsBase):
             utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname,
                                  bridgename, portname, value])
         if json_attr:
-            self.update_cache(bridgename, portname, json_attr, value)
+            self.update_bridge_port_cache(bridgename, portname, json_attr, value)
 
     def get_bridge_attrs(self, bridgename):
         bridgeattrs = {}
         try:
-            bridgeattrs = dict((k, self.get_bridge_attr(bridgename, k))
-                                 for k in self._bridgeattrmap.keys())
-            bridgeattrs['treeprio'] = '%d' %(int(bridgeattrs.get('bridgeid',
-                                     '').split('.')[0], base=16) * 4096)
-            del bridgeattrs['bridgeid']
+            bridgeattrs = dict((k, self.get_bridge_attr(bridgename, v))
+                                 for k,v in self._bridge_jsonAttr_map.items())
         except Exception, e:
             self.logger.debug(bridgeattrs)
             self.logger.debug(str(e))
@@ -130,28 +172,32 @@ class mstpctlutil(utilsBase):
         return bridgeattrs
 
     def get_bridge_attr(self, bridgename, attrname):
-        try:
-            cmdl = ['/sbin/mstpctl', 'showbridge', bridgename,
-                    self._bridgeattrmap[attrname]]
-            return utils.exec_commandl(cmdl).strip('\n')
-        except Exception, e:
-            pass
-        return None
+        if attrname == 'bridgeId':
+            attrname = 'treeprio'
+        return self._get_bridge_attrs_from_cache(bridgename).get(attrname)
 
     def set_bridge_attr(self, bridgename, attrname, attrvalue, check=True):
 
         if check:
-            attrvalue_curr = self.get_bridge_attr(bridgename, attrname)
+            if attrname == 'treeprio':
+                attrvalue_curr = self.get_bridge_attr(bridgename, attrname)
+            else:
+                attrvalue_curr = self.get_bridge_attr(bridgename,
+                                        self._bridge_jsonAttr_map[attrname])
             if attrvalue_curr and attrvalue_curr == attrvalue:
                 return
         if attrname == 'treeprio':
             utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname,
                                  '%s' % bridgename, '0', '%s' % attrvalue],
                                 stdout=False, stderr=None)
+            self.update_bridge_cache(bridgename, attrname, str(attrvalue))
         else:
             utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname,
                                  '%s' % bridgename, '%s' % attrvalue],
                                 stdout=False, stderr=None)
+            self.update_bridge_cache(bridgename,
+                                     self._bridge_jsonAttr_map[attrname],
+                                     str(attrvalue))
 
     def set_bridge_attrs(self, bridgename, attrdict, check=True):
         for k, v in attrdict.iteritems():
@@ -163,17 +209,7 @@ class mstpctlutil(utilsBase):
                 self.logger.warn('%s: %s' %(bridgename, str(e)))
 
     def get_bridge_treeprio(self, bridgename):
-        try:
-            cmdl = ['/sbin/mstpctl',
-                    'showbridge',
-                    bridgename,
-                    self._bridgeattrmap['bridgeid']]
-
-            bridgeid = utils.exec_commandl(cmdl).strip('\n')
-            return '%d' %(int(bridgeid.split('.')[0], base=16) * 4096)
-        except:
-            pass
-        return None
+        return self.get_bridge_attr(bridgename, 'treeprio')
 
     def set_bridge_treeprio(self, bridgename, attrvalue, check=True):
         if check:
@@ -182,6 +218,7 @@ class mstpctlutil(utilsBase):
                 return
         utils.exec_commandl(['/sbin/mstpctl', 'settreeprio', bridgename, '0',
                              str(attrvalue)])
+        self.update_bridge_cache(bridgename, 'treeprio', str(attrvalue))
 
     def showbridge(self, bridgename=None):
         if bridgename: