]> git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/ifupdownaddons/mstpctlutil.py
.gitignore: pycharm remote execution update
[mirror_ifupdown2.git] / ifupdown2 / ifupdownaddons / mstpctlutil.py
1 #!/usr/bin/python
2 #
3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
5 #
6
7 try:
8 from ifupdown2.ifupdown.iface import *
9 from ifupdown2.ifupdown.utils import utils
10
11 from ifupdown2.ifupdownaddons.cache import *
12 from ifupdown2.ifupdownaddons.utilsbase import *
13 except ImportError:
14 from ifupdown.iface import *
15 from ifupdown.utils import utils
16
17 from ifupdownaddons.cache import *
18 from ifupdownaddons.utilsbase import *
19
20
21 class mstpctlutil(utilsBase):
22 """ This class contains helper methods to interact with mstpd using
23 mstputils commands """
24
25 _DEFAULT_PORT_PRIO = '128'
26
27 _cache_fill_done = False
28
29 _bridgeattrmap = {'bridgeid' : 'bridge-id',
30 'maxage' : 'max-age',
31 'fdelay' : 'forward-delay',
32 'txholdcount' : 'tx-hold-count',
33 'maxhops' : 'max-hops',
34 'ageing' : 'ageing-time',
35 'hello' : 'hello-time',
36 'forcevers' : 'force-protocol-version'}
37
38 _bridge_jsonAttr_map = {
39 'treeprio': 'bridgeId',
40 'maxage': 'maxAge',
41 'fdelay': 'fwdDelay',
42 'txholdcount': 'txHoldCounter',
43 'maxhops': 'maxHops',
44 'ageing': 'ageingTime',
45 'hello': 'helloTime',
46 'forcevers': 'forceProtocolVersion',
47 }
48
49 _bridgeportattrmap = {'portadminedge' : 'admin-edge-port',
50 'portp2p' : 'admin-point-to-point',
51 'portrestrrole' : 'restricted-role',
52 'portrestrtcn' : 'restricted-TCN',
53 'bpduguard' : 'bpdu-guard-port',
54 'portautoedge' : 'auto-edge-port',
55 'portnetwork' : 'network-port',
56 'portbpdufilter' : 'bpdufilter-port',
57 'portpathcost' : 'external-port-cost',
58 'treeportcost' : 'internal-port-cost'}
59
60 def __init__(self, *args, **kargs):
61 utilsBase.__init__(self, *args, **kargs)
62
63 @classmethod
64 def reset(cls):
65 cls._cache_fill_done = False
66
67 def is_mstpd_running(self):
68 try:
69 utils.exec_command('%s mstpd'%utils.pidof_cmd)
70 except:
71 return False
72 else:
73 return True
74
75 def _extract_bridge_port_prio(self, portid):
76 try:
77 return str(int(portid[0], 16) * 16)
78 except:
79 return mstpctlutil._DEFAULT_PORT_PRIO
80
81 def _get_bridge_and_port_attrs_from_cache(self, bridgename):
82 attrs = MSTPAttrsCache.get(bridgename, None)
83 if attrs is not None:
84 return attrs
85 mstpctl_bridgeport_attrs_dict = {}
86 try:
87 cmd = [utils.mstpctl_cmd,
88 'showportdetail', bridgename, 'json']
89 output = utils.exec_commandl(cmd)
90 if not output:
91 MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict)
92 return mstpctl_bridgeport_attrs_dict
93 except Exception as e:
94 self.logger.info(str(e))
95 return mstpctl_bridgeport_attrs_dict
96 try:
97 mstpctl_bridge_cache = json.loads(output.strip('\n'))
98 for portname in mstpctl_bridge_cache.keys():
99 for portid in mstpctl_bridge_cache[portname].keys():
100 mstpctl_bridgeport_attrs_dict[portname] = {}
101 mstpctl_bridgeport_attrs_dict[portname]['treeportprio'] = self._extract_bridge_port_prio(portid)
102 for jsonAttr in mstpctl_bridge_cache[portname][portid].keys():
103 jsonVal = mstpctl_bridge_cache[portname][portid][jsonAttr]
104 mstpctl_bridgeport_attrs_dict[portname][jsonAttr] = str(jsonVal)
105 MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict)
106 except Exception as e:
107 self.logger.info('%s: cannot fetch mstpctl bridge port attributes: %s' % str(e))
108
109 mstpctl_bridge_attrs_dict = {}
110 try:
111 cmd = [utils.mstpctl_cmd,
112 'showbridge', 'json', bridgename]
113 output = utils.exec_commandl(cmd)
114 if not output:
115 return mstpctl_bridge_attrs_dict
116 except Exception as e:
117 self.logger.info(str(e))
118 return mstpctl_bridge_attrs_dict
119 try:
120 mstpctl_bridge_cache = json.loads(output.strip('\n'))
121 for jsonAttr in mstpctl_bridge_cache[bridgename].keys():
122 mstpctl_bridge_attrs_dict[jsonAttr] = (
123 str(mstpctl_bridge_cache[bridgename][jsonAttr]))
124 mstpctl_bridge_attrs_dict['treeprio'] = '%d' %(
125 int(mstpctl_bridge_attrs_dict.get('bridgeId',
126 '').split('.')[0], base=16) * 4096)
127 del mstpctl_bridge_attrs_dict['bridgeId']
128 MSTPAttrsCache.bridges[bridgename].update(mstpctl_bridge_attrs_dict)
129 except Exception as e:
130 self.logger.info('%s: cannot fetch mstpctl bridge attributes: %s' % str(e))
131 return MSTPAttrsCache.get(bridgename)
132
133 def get_bridge_ports_attrs(self, bridgename):
134 return self._get_bridge_and_port_attrs_from_cache(bridgename)
135
136 def get_bridge_port_attr(self, bridgename, portname, attrname):
137 attrs = self._get_bridge_and_port_attrs_from_cache(bridgename)
138 value = attrs.get(portname, {}).get(attrname, 'no')
139 if value == 'True' or value == 'true':
140 return 'yes'
141 return str(value)
142
143 def update_bridge_port_cache(self, bridgename, portname, attrname, value):
144 attrs = self.get_bridge_ports_attrs(bridgename)
145 if not attrs:
146 attrs = {}
147 if not portname in attrs:
148 attrs[portname] = {}
149 attrs[portname][attrname] = value
150 MSTPAttrsCache.set(bridgename, attrs)
151
152 def update_bridge_cache(self, bridgename, attrname, value):
153 attrs = self.get_bridge_ports_attrs(bridgename)
154 if not attrs:
155 attrs = {}
156 attrs[attrname] = value
157 MSTPAttrsCache.set(bridgename, attrs)
158
159 def set_bridge_port_attr(self, bridgename, portname, attrname, value, json_attr=None):
160 cache_value = self.get_bridge_port_attr(bridgename, portname, json_attr)
161 if cache_value and cache_value == value:
162 return
163 if attrname == 'treeportcost' or attrname == 'treeportprio':
164 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
165 bridgename, portname, '0', value])
166 else:
167 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
168 bridgename, portname, value])
169 if json_attr:
170 self.update_bridge_port_cache(bridgename, portname, json_attr, value)
171
172 def get_bridge_attrs(self, bridgename):
173 bridgeattrs = {}
174 try:
175 bridgeattrs = dict((k, self.get_bridge_attr(bridgename, v))
176 for k,v in self._bridge_jsonAttr_map.items())
177 except Exception, e:
178 self.logger.debug(bridgeattrs)
179 self.logger.debug(str(e))
180 pass
181 return bridgeattrs
182
183 def get_bridge_attr(self, bridgename, attrname):
184 if attrname == 'bridgeId':
185 attrname = 'treeprio'
186 return self._get_bridge_and_port_attrs_from_cache(bridgename).get(attrname)
187
188 def set_bridge_attr(self, bridgename, attrname, attrvalue, check=True):
189
190 if check:
191 if attrname == 'treeprio':
192 attrvalue_curr = self.get_bridge_attr(bridgename, attrname)
193 else:
194 attrvalue_curr = self.get_bridge_attr(bridgename,
195 self._bridge_jsonAttr_map[attrname])
196 if attrvalue_curr and attrvalue_curr == attrvalue:
197 return
198 if attrname == 'treeprio':
199 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
200 '%s' % bridgename, '0', '%s' % attrvalue], stderr=None)
201 self.update_bridge_cache(bridgename, attrname, str(attrvalue))
202 else:
203 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
204 '%s' % bridgename, '%s' % attrvalue], stderr=None)
205 self.update_bridge_cache(bridgename,
206 self._bridge_jsonAttr_map[attrname],
207 str(attrvalue))
208
209 def set_bridge_attrs(self, bridgename, attrdict, check=True):
210 for k, v in attrdict.iteritems():
211 if not v:
212 continue
213 try:
214 self.set_bridge_attr(bridgename, k, v, check)
215 except Exception, e:
216 self.logger.warn('%s: %s' %(bridgename, str(e)))
217
218 def get_bridge_treeprio(self, bridgename):
219 return self.get_bridge_attr(bridgename, 'treeprio')
220
221 def set_bridge_treeprio(self, bridgename, attrvalue, check=True):
222 if check:
223 attrvalue_curr = self.get_bridge_treeprio(bridgename)
224 if attrvalue_curr and attrvalue_curr == attrvalue:
225 return
226 utils.exec_commandl([utils.mstpctl_cmd,
227 'settreeprio', bridgename, '0',
228 str(attrvalue)])
229 self.update_bridge_cache(bridgename, 'treeprio', str(attrvalue))
230
231 def showbridge(self, bridgename=None):
232 if bridgename:
233 return utils.exec_command('%s showbridge %s' %
234 (utils.mstpctl_cmd, bridgename))
235 else:
236 return utils.exec_command('%s showbridge' %utils.mstpctl_cmd)
237
238 def showportdetail(self, bridgename):
239 return utils.exec_command('%s showportdetail %s' %
240 (utils.mstpctl_cmd, bridgename))
241
242 def mstpbridge_exists(self, bridgename):
243 try:
244 utils.exec_command('%s showbridge %s' %
245 (utils.mstpctl_cmd, bridgename))
246 return True
247 except:
248 return False