]> git.proxmox.com Git - mirror_ifupdown2.git/blame - ifupdown2/ifupdownaddons/mstpctlutil.py
addons: address: new l3_intf_default_gateway_set_onlink policy closes #54
[mirror_ifupdown2.git] / ifupdown2 / ifupdownaddons / mstpctlutil.py
CommitLineData
15ef32ea
RP
1#!/usr/bin/python
2#
d486dd0d 3# Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
15ef32ea
RP
4# Author: Roopa Prabhu, roopa@cumulusnetworks.com
5#
6
d486dd0d
JF
7try:
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 *
13except ImportError:
14 from ifupdown.iface import *
15 from ifupdown.utils import utils
16
17 from ifupdownaddons.cache import *
18 from ifupdownaddons.utilsbase import *
19
15ef32ea
RP
20
21class mstpctlutil(utilsBase):
22 """ This class contains helper methods to interact with mstpd using
23 mstputils commands """
24
bfceb635
JF
25 _DEFAULT_PORT_PRIO = '128'
26
15ef32ea
RP
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
e3089aa8
N
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
15ef32ea 49 _bridgeportattrmap = {'portadminedge' : 'admin-edge-port',
2ca1b884 50 'portp2p' : 'admin-point-to-point',
15ef32ea
RP
51 'portrestrrole' : 'restricted-role',
52 'portrestrtcn' : 'restricted-TCN',
53 'bpduguard' : 'bpdu-guard-port',
54 'portautoedge' : 'auto-edge-port',
55 'portnetwork' : 'network-port',
22945dd6
N
56 'portbpdufilter' : 'bpdufilter-port',
57 'portpathcost' : 'external-port-cost',
58 'treeportcost' : 'internal-port-cost'}
15ef32ea
RP
59
60 def __init__(self, *args, **kargs):
61 utilsBase.__init__(self, *args, **kargs)
62
d486dd0d
JF
63 @classmethod
64 def reset(cls):
65 cls._cache_fill_done = False
66
15ef32ea
RP
67 def is_mstpd_running(self):
68 try:
d486dd0d 69 utils.exec_command('%s mstpd'%utils.pidof_cmd)
15ef32ea
RP
70 except:
71 return False
72 else:
73 return True
74
bfceb635
JF
75 def _extract_bridge_port_prio(self, portid):
76 try:
77 return str(int(portid[0], 16) * 16)
78 except:
9d3f53c6 79 return mstpctlutil._DEFAULT_PORT_PRIO
bfceb635 80
d03b0695 81 def _get_bridge_and_port_attrs_from_cache(self, bridgename):
80d56a07
JF
82 attrs = MSTPAttrsCache.get(bridgename, None)
83 if attrs is not None:
9d3f53c6
JF
84 return attrs
85 mstpctl_bridgeport_attrs_dict = {}
86 try:
d486dd0d
JF
87 cmd = [utils.mstpctl_cmd,
88 'showportdetail', bridgename, 'json']
9d3f53c6
JF
89 output = utils.exec_commandl(cmd)
90 if not output:
80d56a07 91 MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict)
b47ce90d 92 return mstpctl_bridgeport_attrs_dict
9d3f53c6
JF
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))
9d3f53c6 108
e3089aa8
N
109 mstpctl_bridge_attrs_dict = {}
110 try:
d486dd0d
JF
111 cmd = [utils.mstpctl_cmd,
112 'showbridge', 'json', bridgename]
e3089aa8
N
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']
d03b0695 128 MSTPAttrsCache.bridges[bridgename].update(mstpctl_bridge_attrs_dict)
e3089aa8
N
129 except Exception as e:
130 self.logger.info('%s: cannot fetch mstpctl bridge attributes: %s' % str(e))
d03b0695 131 return MSTPAttrsCache.get(bridgename)
e3089aa8 132
9d3f53c6 133 def get_bridge_ports_attrs(self, bridgename):
d03b0695 134 return self._get_bridge_and_port_attrs_from_cache(bridgename)
9d3f53c6
JF
135
136 def get_bridge_port_attr(self, bridgename, portname, attrname):
d03b0695 137 attrs = self._get_bridge_and_port_attrs_from_cache(bridgename)
9d3f53c6
JF
138 value = attrs.get(portname, {}).get(attrname, 'no')
139 if value == 'True' or value == 'true':
140 return 'yes'
141 return str(value)
142
e3089aa8 143 def update_bridge_port_cache(self, bridgename, portname, attrname, value):
9d3f53c6 144 attrs = self.get_bridge_ports_attrs(bridgename)
b47ce90d 145 if not attrs:
9d3f53c6
JF
146 attrs = {}
147 if not portname in attrs:
148 attrs[portname] = {}
149 attrs[portname][attrname] = value
150 MSTPAttrsCache.set(bridgename, attrs)
151
e3089aa8
N
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
9d3f53c6
JF
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
15ef32ea 163 if attrname == 'treeportcost' or attrname == 'treeportprio':
d486dd0d 164 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
9d3f53c6 165 bridgename, portname, '0', value])
15ef32ea 166 else:
d486dd0d 167 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
9d3f53c6
JF
168 bridgename, portname, value])
169 if json_attr:
e3089aa8 170 self.update_bridge_port_cache(bridgename, portname, json_attr, value)
15ef32ea
RP
171
172 def get_bridge_attrs(self, bridgename):
173 bridgeattrs = {}
174 try:
e3089aa8
N
175 bridgeattrs = dict((k, self.get_bridge_attr(bridgename, v))
176 for k,v in self._bridge_jsonAttr_map.items())
15ef32ea 177 except Exception, e:
2ca1b884
RP
178 self.logger.debug(bridgeattrs)
179 self.logger.debug(str(e))
15ef32ea
RP
180 pass
181 return bridgeattrs
182
183 def get_bridge_attr(self, bridgename, attrname):
e3089aa8
N
184 if attrname == 'bridgeId':
185 attrname = 'treeprio'
d03b0695 186 return self._get_bridge_and_port_attrs_from_cache(bridgename).get(attrname)
15ef32ea
RP
187
188 def set_bridge_attr(self, bridgename, attrname, attrvalue, check=True):
189
190 if check:
e3089aa8
N
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])
15ef32ea
RP
196 if attrvalue_curr and attrvalue_curr == attrvalue:
197 return
198 if attrname == 'treeprio':
d486dd0d
JF
199 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
200 '%s' % bridgename, '0', '%s' % attrvalue], stderr=None)
e3089aa8 201 self.update_bridge_cache(bridgename, attrname, str(attrvalue))
15ef32ea 202 else:
d486dd0d
JF
203 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
204 '%s' % bridgename, '%s' % attrvalue], stderr=None)
e3089aa8
N
205 self.update_bridge_cache(bridgename,
206 self._bridge_jsonAttr_map[attrname],
207 str(attrvalue))
15ef32ea
RP
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)))
15ef32ea
RP
217
218 def get_bridge_treeprio(self, bridgename):
e3089aa8 219 return self.get_bridge_attr(bridgename, 'treeprio')
15ef32ea
RP
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
d486dd0d
JF
226 utils.exec_commandl([utils.mstpctl_cmd,
227 'settreeprio', bridgename, '0',
a193d8d1 228 str(attrvalue)])
e3089aa8 229 self.update_bridge_cache(bridgename, 'treeprio', str(attrvalue))
15ef32ea
RP
230
231 def showbridge(self, bridgename=None):
232 if bridgename:
d486dd0d
JF
233 return utils.exec_command('%s showbridge %s' %
234 (utils.mstpctl_cmd, bridgename))
15ef32ea 235 else:
d486dd0d 236 return utils.exec_command('%s showbridge' %utils.mstpctl_cmd)
15ef32ea
RP
237
238 def showportdetail(self, bridgename):
d486dd0d
JF
239 return utils.exec_command('%s showportdetail %s' %
240 (utils.mstpctl_cmd, bridgename))
15ef32ea
RP
241
242 def mstpbridge_exists(self, bridgename):
243 try:
d486dd0d
JF
244 utils.exec_command('%s showbridge %s' %
245 (utils.mstpctl_cmd, bridgename))
15ef32ea
RP
246 return True
247 except:
248 return False