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