]> git.proxmox.com Git - mirror_ifupdown2.git/blame - pkg/iface.py
Support for manual method + rearrange some code
[mirror_ifupdown2.git] / pkg / iface.py
CommitLineData
a6f80f0e 1#!/usr/bin/python
3e8ee54f 2#
3# Copyright 2013. Cumulus Networks, Inc.
4# Author: Roopa Prabhu, roopa@cumulusnetworks.com
5#
6# iface --
7# interface object
8#
cca03c30 9from collections import OrderedDict
d08d5f54 10#from json import *
551a3627 11import json
d08d5f54 12import logging
a6f80f0e 13
d08d5f54 14tickmark = ' (' + u'\u2713'.encode('utf8') + ')'
15crossmark = ' (' + u'\u2717'.encode('utf8') + ')'
a6f80f0e 16
d08d5f54 17class ifaceFlags():
a6f80f0e 18 NONE = 0x1
19 FOLLOW_DEPENDENTS = 0x2
20
21class ifaceStatus():
a6f80f0e 22 """iface status """
23 UNKNOWN = 0x1
24 SUCCESS = 0x2
25 ERROR = 0x3
10720a53 26 NOTFOUND = 0x4
a6f80f0e 27
28 @classmethod
29 def to_str(cls, state):
30 if state == cls.UNKNOWN:
31 return 'unknown'
32 elif state == cls.SUCCESS:
33 return 'success'
34 elif state == cls.ERROR:
35 return 'error'
739f665b 36 elif state == cls.NOTFOUND:
37 return 'not found'
a6f80f0e 38
39 @classmethod
40 def from_str(cls, state_str):
41 if state_str == 'unknown':
42 return cls.UNKNOWN
43 elif state_str == 'success':
44 return cls.SUCCESS
45 elif state_str == 'error':
46 return cls.ERROR
47
48class ifaceState():
49
50 """ iface states """
51 UNKNOWN = 0x1
52 NEW = 0x2
53 PRE_UP = 0x3
54 UP = 0x4
55 POST_UP = 0x5
56 PRE_DOWN = 0x6
57 DOWN = 0x7
58 POST_DOWN = 0x8
59
d08d5f54 60 # Pseudo states
61 QUERY_CHECKCURR = 0x9
62 QUERY_RUNNING = 0xa
63
a6f80f0e 64 @classmethod
65 def to_str(cls, state):
66 if state == cls.UNKNOWN:
67 return 'unknown'
68 elif state == cls.NEW:
69 return 'new'
70 elif state == cls.PRE_UP:
71 return 'pre-up'
72 elif state == cls.UP:
73 return 'up'
74 elif state == cls.POST_UP:
75 return 'post-up'
76 elif state == cls.PRE_DOWN:
77 return 'pre-down'
d08d5f54 78 elif state == cls.DOWN:
79 return 'down'
a6f80f0e 80 elif state == cls.POST_DOWN:
81 return 'post-down'
d08d5f54 82 elif state == cls.QUERY_CHECKCURR:
83 return 'query-checkcurr'
84 elif state == cls.QUERY_RUNNING:
85 return 'query-running'
a6f80f0e 86
87 @classmethod
88 def from_str(cls, state_str):
89 if state_str == 'unknown':
90 return cls.UNKNOWN
91 elif state_str == 'new':
92 return cls.NEW
93 elif state_str == 'pre-up':
94 return cls.PRE_UP
95 elif state_str == 'up':
96 return cls.UP
97 elif state_str == 'post-up':
98 return cls.POST_UP
99 elif state_str == 'pre-down':
100 return cls.PRE_DOWN
d08d5f54 101 elif state_str == 'down':
102 return cls.DOWN
a6f80f0e 103 elif state_str == 'post-down':
104 return cls.POST_DOWN
d08d5f54 105 elif state_str == 'query-checkcurr':
106 return cls.QUERY_CHECKCURR
107 elif state_str == 'query-running':
108 return cls.QUERY_RUNNING
a6f80f0e 109
110
d08d5f54 111class ifaceJsonEncoder(json.JSONEncoder):
112 def default(self, o):
83c1f241 113 retconfig = {}
114 if o.config:
115 for k, v in o.config.items():
116 if len(v) == 1:
117 retconfig[k] = v[0]
118 else:
119 retconfig[k] = v
120
75730152 121 return OrderedDict({'name' : o.name,
122 'addr_method' : o.addr_method,
123 'addr_family' : o.addr_family,
124 'auto' : o.auto,
83c1f241 125 'config' : retconfig})
d08d5f54 126
a6f80f0e 127class iface():
128 """ config flags """
129 AUTO = 0x1
130 HOT_PLUG = 0x2
131
37c0543d 132 version = '0.1'
133
a6f80f0e 134 def __init__(self):
135 self.name = None
136 self.addr_family = None
137 self.addr_method = None
cca03c30 138 self.config = OrderedDict()
a6f80f0e 139 self.state = ifaceState.NEW
140 self.status = ifaceStatus.UNKNOWN
d08d5f54 141 self.errstr = ''
a6f80f0e 142 self.flags = 0x0
37c0543d 143 self.priv_flags = 0x0
a6f80f0e 144 self.refcnt = 0
f3215127 145 self.lowerifaces = None
146 self.upperifaces = None
a6f80f0e 147 self.auto = False
148 self.classes = []
149 self.env = None
150 self.config_current = {}
151 self.raw_lines = []
152 self.linkstate = None
153
154 def inc_refcnt(self):
a6f80f0e 155 self.refcnt += 1
156
157 def dec_refcnt(self):
158 self.refcnt -= 1
159
160 def get_refcnt(self):
161 return self.refcnt
162
163 def set_refcnt(self, cnt):
164 self.refcnt = 0
165
166 def set_name(self, name):
167 self.name = name
168
169 def get_name(self):
170 return self.name
171
172 def set_addr_family(self, family):
173 self.addr_family = family
174
175 def get_addr_family(self):
176 return self.addr_family
177
178 def set_addr_method(self, method):
179 self.addr_method = method
180
181 def get_addr_method(self):
182 return self.addr_method
183
184 def set_config(self, config_dict):
185 self.config = config_dict
186
187 def get_config(self):
188 return self.config
189
cca03c30 190 def is_config_present(self):
37c0543d 191 addr_method = self.get_addr_method()
192 if addr_method is not None:
193 if (addr_method.find('dhcp') != -1 or
194 addr_method.find('dhcp6') != -1):
195 return True
196
cca03c30 197 if self.config is None:
198 return False
199
200 return (len(self.config) != 0)
201
a6f80f0e 202 def set_config_current(self, config_current):
203 self.config_current = config_current
204
205 def get_config_current(self):
206 return self.config_current
207
208 def get_auto(self):
209 return self.auto
210
211 def set_auto(self):
212 self.auto = True
213
214 def reset_auto(self):
215 self.auto = False
216
217 def get_classes(self):
218 return self.classes
219
3e8ee54f 220 def set_classes(self, classes):
221 """ sets interface class list to the one passed as arg """
222 self.classes = classes
223
224 def set_class(self, classname):
225 """ Appends a class to the list """
a6f80f0e 226 self.classes.append(classname)
227
228 def belongs_to_class(self, intfclass):
229 if intfclass in self.classes:
230 return True
231
232 return False
233
a6f80f0e 234 def get_state(self):
235 return self.state
236
237 def get_state_str(self):
238 return ifaceState.to_str(self.state)
239
240 def set_state(self, state):
241 self.state = state
242
243 def get_status(self):
244 return self.status
245
246 def get_status_str(self):
247 return ifaceStatus.to_str(self.status)
248
249 def set_status(self, status):
250 self.status = status
251
252 def state_str_to_hex(self, state_str):
253 return self.state_str_map.get(state_str)
254
255 def set_flag(self, flag):
256 self.flags |= flag
257
258 def clear_flag(self, flag):
259 self.flags &= ~flag
260
f3215127 261 def set_lowerifaces(self, dlist):
262 self.lowerifaces = dlist
a6f80f0e 263
f3215127 264 def get_lowerifaces(self):
265 return self.lowerifaces
a6f80f0e 266
f3215127 267 def set_upperifaces(self, dlist):
268 self.upperifaces = dlist
739f665b 269
f3215127 270 def add_to_upperifaces(self, upperifacename):
271 if self.upperifaces:
272 if upperifacename not in self.upperifaces:
273 self.upperifaces.append(upperifacename)
274 else:
275 self.upperifaces = [upperifacename]
276
277 def get_upperifaces(self):
278 return self.upperifaces
739f665b 279
a6f80f0e 280 def set_linkstate(self, l):
281 self.linkstate = l
282
283 def get_linkstate(self):
284 return self.linkstate
285
a6f80f0e 286 def get_attr_value(self, attr_name):
287 config = self.get_config()
288
289 return config.get(attr_name)
290
291 def get_attr_value_first(self, attr_name):
292 config = self.get_config()
a6f80f0e 293 attr_value_list = config.get(attr_name)
294 if attr_value_list is not None:
295 return attr_value_list[0]
a6f80f0e 296 return None
297
298 def get_attr_value_n(self, attr_name, attr_index):
299 config = self.get_config()
300
301 attr_value_list = config.get(attr_name)
302 if attr_value_list is not None:
303 try:
304 return attr_value_list[attr_index]
305 except:
306 return None
307
308 return None
309
310 def get_env(self):
311 if self.env is None or len(self.env) == 0:
312 self.generate_env()
313 return self.env
314
315 def set_env(self, env):
316 self.env = env
317
318 def generate_env(self):
319 env = {}
320 config = self.get_config()
321 env['IFACE'] = self.get_name()
322 for attr, attr_value in config.items():
323 attr_env_name = 'IF_%s' %attr.upper()
324 env[attr_env_name] = attr_value[0]
325
326 if len(env) > 0:
327 self.set_env(env)
328
739f665b 329 def update_config(self, attr_name, attr_value):
330 if self.config.get(attr_name) is None:
331 self.config[attr_name] = [attr_value]
332 else:
333 self.config[attr_name].append(attr_value)
334
335 def update_config_dict(self, attrdict):
336 self.config.update(attrdict)
337
338 def update_config_with_status(self, attr_name, attr_value, attr_status=0):
a6f80f0e 339 if attr_value is None:
340 attr_value = ''
d08d5f54 341 if attr_status:
eab25b7c 342 self.set_status(ifaceStatus.ERROR)
d08d5f54 343 new_attr_value = '%s (%s)' %(attr_value, crossmark)
eab25b7c 344 else:
d08d5f54 345 new_attr_value = '%s (%s)' %(attr_value, tickmark)
eab25b7c 346 if self.get_status() != ifaceStatus.ERROR:
347 self.set_status(ifaceStatus.SUCCESS)
348 if self.config.get(attr_name) is not None:
d08d5f54 349 self.config[attr_name].append(new_attr_value)
eab25b7c 350 else:
d08d5f54 351 self.config[attr_name] = [new_attr_value]
a6f80f0e 352
37c0543d 353 def is_different(self, dstiface):
354 if self.name != dstiface.name: return True
355 if self.addr_family != dstiface.addr_family: return True
356 if self.addr_method != dstiface.addr_method: return True
357 if self.auto != dstiface.auto: return True
358 if self.classes != dstiface.classes: return True
359
360 if any(True for k in self.config if k not in dstiface.config):
361 return True
362
363 if any(True for k,v in self.config.items()
364 if v != dstiface.config.get(k)): return True
365
37c0543d 366 return False
d08d5f54 367
368 def __getstate__(self):
369 odict = self.__dict__.copy()
370 del odict['state']
371 del odict['status']
f3215127 372 del odict['lowerifaces']
d08d5f54 373 del odict['refcnt']
374
375 return odict
376
377 def __setstate__(self, dict):
378 self.__dict__.update(dict)
379 self.state = ifaceState.NEW
380 self.status = ifaceStatus.UNKNOWN
381 self.refcnt = 0
f3215127 382 self.lowerifaces = None
d08d5f54 383 self.linkstate = None
37c0543d 384
a6f80f0e 385 def dump_raw(self, logger):
386 indent = ' '
387 print (self.raw_lines[0])
388 for i in range(1, len(self.raw_lines)):
389 print (indent + self.raw_lines[i])
390
a6f80f0e 391 def dump(self, logger):
392 indent = '\t'
393 logger.info(self.get_name() + ' : {')
394 logger.info(indent + 'family: %s' %self.get_addr_family())
395 logger.info(indent + 'method: %s' %self.get_addr_method())
396 logger.info(indent + 'state: %s'
397 %ifaceState.to_str(self.get_state()))
398 logger.info(indent + 'status: %s'
399 %ifaceStatus.to_str(self.get_status()))
400 logger.info(indent + 'refcnt: %d' %self.get_refcnt())
f3215127 401 d = self.get_lowerdevs()
a6f80f0e 402 if d is not None:
f3215127 403 logger.info(indent + 'lowerdevs: %s' %str(d))
a6f80f0e 404 else:
f3215127 405 logger.info(indent + 'lowerdevs: None')
739f665b 406
a6f80f0e 407 logger.info(indent + 'config: ')
408 config = self.get_config()
409 if config is not None:
410 logger.info(indent + indent + str(config))
411 logger.info('}')
412
d08d5f54 413 def dump_pretty(self):
a6f80f0e 414 indent = '\t'
cca03c30 415 outbuf = ''
416 if self.get_auto():
417 outbuf += 'auto %s\n' %self.get_name()
418 outbuf += 'iface %s' %self.get_name()
a6f80f0e 419 if self.get_addr_family() is not None:
420 outbuf += ' %s' %self.get_addr_family()
421
422 if self.get_addr_method() is not None:
423 outbuf += ' %s' %self.get_addr_method()
424
425 outbuf += '\n'
426
427 config = self.get_config()
428 if config is not None:
eab25b7c 429 for cname, cvaluelist in config.items():
430 for cv in cvaluelist:
431 outbuf += indent + '%s' %cname + ' %s\n' %cv
a6f80f0e 432
a6f80f0e 433 print outbuf
551a3627 434
d08d5f54 435 def dump_json(self):
75730152 436 print json.dumps(self, cls=ifaceJsonEncoder, indent=4)