]>
Commit | Line | Data |
---|---|---|
a6f80f0e | 1 | #!/usr/bin/python |
3e8ee54f | 2 | # |
904908bc | 3 | # Copyright 2014 Cumulus Networks, Inc. All rights reserved. |
3e8ee54f | 4 | # Author: Roopa Prabhu, roopa@cumulusnetworks.com |
5 | # | |
6 | # iface -- | |
7 | # interface object | |
8 | # | |
62ddec8b | 9 | |
10 | """ifupdown2 network interface object | |
11 | ||
904908bc | 12 | It is modeled based on the 'iface' section in /etc/network/interfaces |
62ddec8b | 13 | file. But can be extended to include any other network interface format |
62ddec8b | 14 | """ |
15 | ||
cca03c30 | 16 | from collections import OrderedDict |
d08d5f54 | 17 | import logging |
2cd06f78 | 18 | import json |
a6f80f0e | 19 | |
307e06bb RP |
20 | class ifaceStatusUserStrs(): |
21 | """ This class declares strings user can see during an ifquery --check | |
22 | for example. These strings can be overridden by user defined strings from | |
23 | config file """ | |
fb10449e RP |
24 | SUCCESS = "success", |
25 | FAILURE = "error", | |
26 | UNKNOWN = "unknown" | |
27 | ||
41febf89 | 28 | class ifaceType(): |
2da58137 RP |
29 | UNKNOWN = 0x0 |
30 | IFACE = 0x1 | |
31 | BRIDGE_VLAN = 0x2 | |
41febf89 | 32 | |
0a3bee28 ST |
33 | |
34 | class ifaceRole(): | |
35 | """ ifaceRole is used to classify the ifaceobj.role of | |
36 | MASTER or SLAVE where there is a bond or bridge | |
37 | with bond-slaves or bridge-ports. A bond in a bridge | |
38 | is both a master and slave (0x3) | |
39 | """ | |
40 | UNKNOWN = 0x0 | |
41 | SLAVE = 0x1 | |
42 | MASTER = 0x2 | |
43 | ||
a9ab1b4f | 44 | class ifaceLinkKind(): |
0a3bee28 ST |
45 | """ ifaceLlinkKind is used to identify interfaces |
46 | in the ifaceobj.link_kind attribute. Dependents of the bridge or | |
47 | bond have an ifaceobj.role attribute of SLAVE and the bridge or | |
48 | bond itself has ifaceobj.role of MASTER. | |
49 | """ | |
a9ab1b4f RP |
50 | UNKNOWN = 0x0 |
51 | BRIDGE = 0x1 | |
52 | BOND = 0x2 | |
0a3bee28 ST |
53 | VLAN = 0x4 |
54 | VXLAN = 0x8 | |
7f67f3e5 | 55 | BRIDGE_VLAN_AWARE = 0x10 |
65e0c276 RP |
56 | BRIDGE_PORT = 0x20 |
57 | BOND_SLAVE = 0x40 | |
a9ab1b4f | 58 | |
c416da6a | 59 | class ifaceLinkType(): |
a070c90e | 60 | LINK_UNKNOWN = 0x0 |
c416da6a RP |
61 | LINK_SLAVE = 0x1 |
62 | LINK_MASTER = 0x2 | |
a070c90e | 63 | LINK_NA = 0x3 |
c416da6a | 64 | |
45ca0b6d RP |
65 | class ifaceDependencyType(): |
66 | """ Indicates type of dependency. | |
67 | ||
68 | This class enumerates types of dependency relationships | |
69 | between interfaces. | |
70 | ||
71 | iface dependency relationships can be classified | |
72 | into: | |
73 | - link | |
74 | - master/slave | |
75 | ||
76 | In a 'link' dependency relationship, dependency can be shared | |
77 | between interfaces. example: swp1.100 and | |
78 | swp1.200 can both have 'link' swp1. swp1 is also a dependency | |
79 | of swp1.100 and swp1.200. As you can see dependency | |
80 | swp1 is shared between swp1.100 and swp1.200. | |
81 | ||
82 | In a master/slave relationship like bridge and | |
83 | its ports: eg: bridge br0 and its ports swp1 and swp2. | |
84 | dependency swp1 and swp2 cannot be shared with any other | |
85 | interface with the same dependency relationship. | |
86 | ie, swp1 and swp2 cannot be in a slave relationship | |
87 | with another interface. Understanding the dependency type is | |
88 | required for any semantic checks between dependencies. | |
89 | ||
90 | """ | |
91 | UNKNOWN = 0x0 | |
92 | LINK = 0x1 | |
93 | MASTER_SLAVE = 0x2 | |
94 | ||
a6f80f0e | 95 | class ifaceStatus(): |
62ddec8b | 96 | """Enumerates iface status """ |
97 | ||
a6f80f0e | 98 | UNKNOWN = 0x1 |
99 | SUCCESS = 0x2 | |
100 | ERROR = 0x3 | |
10720a53 | 101 | NOTFOUND = 0x4 |
a6f80f0e | 102 | |
103 | @classmethod | |
104 | def to_str(cls, state): | |
105 | if state == cls.UNKNOWN: | |
106 | return 'unknown' | |
107 | elif state == cls.SUCCESS: | |
108 | return 'success' | |
109 | elif state == cls.ERROR: | |
110 | return 'error' | |
739f665b | 111 | elif state == cls.NOTFOUND: |
69f58278 | 112 | return 'notfound' |
a6f80f0e | 113 | |
114 | @classmethod | |
115 | def from_str(cls, state_str): | |
116 | if state_str == 'unknown': | |
117 | return cls.UNKNOWN | |
118 | elif state_str == 'success': | |
119 | return cls.SUCCESS | |
120 | elif state_str == 'error': | |
121 | return cls.ERROR | |
122 | ||
123 | class ifaceState(): | |
62ddec8b | 124 | """Enumerates iface state """ |
a6f80f0e | 125 | |
a6f80f0e | 126 | UNKNOWN = 0x1 |
127 | NEW = 0x2 | |
128 | PRE_UP = 0x3 | |
129 | UP = 0x4 | |
130 | POST_UP = 0x5 | |
131 | PRE_DOWN = 0x6 | |
132 | DOWN = 0x7 | |
133 | POST_DOWN = 0x8 | |
134 | ||
d08d5f54 | 135 | # Pseudo states |
136 | QUERY_CHECKCURR = 0x9 | |
137 | QUERY_RUNNING = 0xa | |
138 | ||
a6f80f0e | 139 | @classmethod |
140 | def to_str(cls, state): | |
141 | if state == cls.UNKNOWN: | |
142 | return 'unknown' | |
143 | elif state == cls.NEW: | |
144 | return 'new' | |
145 | elif state == cls.PRE_UP: | |
146 | return 'pre-up' | |
147 | elif state == cls.UP: | |
148 | return 'up' | |
149 | elif state == cls.POST_UP: | |
150 | return 'post-up' | |
151 | elif state == cls.PRE_DOWN: | |
152 | return 'pre-down' | |
d08d5f54 | 153 | elif state == cls.DOWN: |
154 | return 'down' | |
a6f80f0e | 155 | elif state == cls.POST_DOWN: |
156 | return 'post-down' | |
d08d5f54 | 157 | elif state == cls.QUERY_CHECKCURR: |
158 | return 'query-checkcurr' | |
159 | elif state == cls.QUERY_RUNNING: | |
160 | return 'query-running' | |
a6f80f0e | 161 | |
162 | @classmethod | |
163 | def from_str(cls, state_str): | |
164 | if state_str == 'unknown': | |
165 | return cls.UNKNOWN | |
166 | elif state_str == 'new': | |
167 | return cls.NEW | |
168 | elif state_str == 'pre-up': | |
169 | return cls.PRE_UP | |
170 | elif state_str == 'up': | |
171 | return cls.UP | |
172 | elif state_str == 'post-up': | |
173 | return cls.POST_UP | |
174 | elif state_str == 'pre-down': | |
175 | return cls.PRE_DOWN | |
d08d5f54 | 176 | elif state_str == 'down': |
177 | return cls.DOWN | |
a6f80f0e | 178 | elif state_str == 'post-down': |
179 | return cls.POST_DOWN | |
d08d5f54 | 180 | elif state_str == 'query-checkcurr': |
181 | return cls.QUERY_CHECKCURR | |
182 | elif state_str == 'query-running': | |
183 | return cls.QUERY_RUNNING | |
a6f80f0e | 184 | |
d08d5f54 | 185 | class ifaceJsonEncoder(json.JSONEncoder): |
f012209e | 186 | def default(self, o): |
83c1f241 | 187 | retconfig = {} |
fb10449e RP |
188 | retifacedict = OrderedDict([]) |
189 | if o.config: | |
f012209e RP |
190 | retconfig = dict((k, (v[0] if len(v) == 1 else v)) |
191 | for k,v in o.config.items()) | |
192 | retifacedict['name'] = o.name | |
193 | if o.addr_method: | |
194 | retifacedict['addr_method'] = o.addr_method | |
195 | if o.addr_family: | |
196 | retifacedict['addr_family'] = o.addr_family | |
197 | retifacedict['auto'] = o.auto | |
198 | retifacedict['config'] = retconfig | |
199 | ||
200 | return retifacedict | |
201 | ||
202 | class ifaceJsonEncoderWithStatus(json.JSONEncoder): | |
203 | def default(self, o): | |
204 | retconfig = {} | |
205 | retconfig_status = {} | |
206 | retifacedict = OrderedDict([]) | |
207 | if o.config: | |
fb10449e RP |
208 | for k,v in o.config.items(): |
209 | idx = 0 | |
210 | vitem_status = [] | |
211 | for vitem in v: | |
212 | s = o.get_config_attr_status(k, idx) | |
213 | if s == -1: | |
307e06bb | 214 | status_str = ifaceStatusUserStrs.UNKNOWN |
fb10449e | 215 | elif s == 1: |
307e06bb | 216 | status_str = ifaceStatusUserStrs.ERROR |
fb10449e | 217 | elif s == 0: |
307e06bb | 218 | status_str = ifaceStatusUserStrs.SUCCESS |
fb10449e RP |
219 | vitem_status.append('%s' %status_str) |
220 | idx += 1 | |
221 | retconfig[k] = v[0] if len(v) == 1 else v | |
222 | retconfig_status[k] = vitem_status[0] if len(vitem_status) == 1 else vitem_status | |
223 | ||
224 | if (o.status == ifaceStatus.NOTFOUND or | |
225 | o.status == ifaceStatus.ERROR): | |
307e06bb | 226 | status = ifaceStatusUserStrs.ERROR |
fb10449e | 227 | else: |
307e06bb | 228 | status = ifaceStatusUserStrs.SUCCESS |
fb10449e RP |
229 | |
230 | retifacedict['name'] = o.name | |
231 | if o.addr_method: | |
232 | retifacedict['addr_method'] = o.addr_method | |
233 | if o.addr_family: | |
234 | retifacedict['addr_family'] = o.addr_family | |
235 | retifacedict['auto'] = o.auto | |
236 | retifacedict['config'] = retconfig | |
237 | retifacedict['config_status'] = retconfig_status | |
238 | retifacedict['status'] = status | |
239 | ||
240 | return retifacedict | |
d08d5f54 | 241 | |
3dcc1d0e | 242 | class ifaceJsonDecoder(): |
243 | @classmethod | |
244 | def json_to_ifaceobj(cls, ifaceattrdict): | |
245 | ifaceattrdict['config'] = OrderedDict([(k, (v if isinstance(v, list) | |
246 | else [v])) | |
247 | for k,v in ifaceattrdict.get('config', | |
248 | OrderedDict()).items()]) | |
249 | return iface(attrsdict=ifaceattrdict) | |
250 | ||
a6f80f0e | 251 | class iface(): |
904908bc | 252 | """ ifupdown2 iface object class |
62ddec8b | 253 | |
254 | Attributes: | |
904908bc RP |
255 | **name** Name of the interface |
256 | ||
257 | **addr_family** Address family eg, inet, inet6. Can be None to | |
258 | indicate both address families | |
259 | ||
260 | **addr_method** Address method eg, static, manual or None for | |
261 | static address method | |
262 | ||
263 | **config** dictionary of config lines for this interface | |
264 | ||
265 | **state** Configuration state of an interface as defined by | |
266 | ifaceState | |
267 | ||
268 | **status** Configuration status of an interface as defined by | |
269 | ifaceStatus | |
270 | ||
271 | **flags** Internal flags used by iface processing | |
272 | ||
273 | **priv_flags** private flags owned by module using this class | |
274 | ||
4c773918 ST |
275 | **module_flags** module flags owned by module using this class |
276 | ||
904908bc RP |
277 | **refcnt** reference count, indicating number of interfaces |
278 | dependent on this iface | |
279 | ||
280 | **lowerifaces** list of interface names lower to this interface or | |
281 | this interface depends on | |
282 | ||
283 | **upperifaces** list of interface names upper to this interface or | |
284 | the interfaces that depend on this interface | |
285 | ||
286 | **auto** True if interface belongs to the auto class | |
287 | ||
288 | **classes** List of classes the interface belongs to | |
289 | ||
290 | **env** shell environment the interface needs during | |
291 | execution | |
292 | ||
293 | **raw_config** raw interface config from file | |
62ddec8b | 294 | """ |
295 | ||
31a5f4c3 | 296 | # flag to indicate that the object was created from pickled state |
0582f185 | 297 | # XXX: Move these flags into a separate iface flags class |
7444feea ST |
298 | _PICKLED = 0x00000001 |
299 | HAS_SIBLINGS = 0x00000010 | |
73c27592 RP |
300 | IFACERANGE_ENTRY = 0x00000100 |
301 | IFACERANGE_START = 0x00001000 | |
7444feea | 302 | OLDEST_SIBLING = 0x00010000 |
0582f185 | 303 | YOUNGEST_SIBLING = 0x00100000 |
a6f80f0e | 304 | |
37c0543d | 305 | version = '0.1' |
306 | ||
3dcc1d0e | 307 | def __init__(self, attrsdict={}): |
308 | self._set_attrs_from_dict(attrsdict) | |
62ddec8b | 309 | self._config_status = {} |
2c0ad8b3 | 310 | """dict with config status of iface attributes""" |
a6f80f0e | 311 | self.state = ifaceState.NEW |
2c0ad8b3 | 312 | """iface state (of type ifaceState) """ |
a6f80f0e | 313 | self.status = ifaceStatus.UNKNOWN |
2c0ad8b3 | 314 | """iface status (of type ifaceStatus) """ |
e1601369 RP |
315 | self.status_str = None |
316 | """iface status str (string representing the status) """ | |
a6f80f0e | 317 | self.flags = 0x0 |
2c0ad8b3 | 318 | """iface flags """ |
dbc018d3 | 319 | self.priv_flags = None |
4c773918 ST |
320 | """iface module flags dictionary with module name: flags""" |
321 | self.module_flags = {} | |
2c0ad8b3 | 322 | """iface priv flags. can be used by the external object manager """ |
a6f80f0e | 323 | self.refcnt = 0 |
2c0ad8b3 | 324 | """iface refcnt (incremented for each dependent this interface has) """ |
41febf89 | 325 | self.lowerifaces = None |
2c0ad8b3 | 326 | """lower iface list (in other words: slaves of this interface """ |
f3215127 | 327 | self.upperifaces = None |
2c0ad8b3 | 328 | """upper iface list (in other words: master of this interface """ |
a6f80f0e | 329 | self.classes = [] |
2c0ad8b3 | 330 | """interface classes this iface belongs to """ |
a6f80f0e | 331 | self.env = None |
2c0ad8b3 | 332 | """environment variable dict required for this interface to run""" |
62ddec8b | 333 | self.raw_config = [] |
2c0ad8b3 | 334 | """interface config/attributes in raw format (eg: as it appeared in the interfaces file)""" |
a6f80f0e | 335 | self.linkstate = None |
2c0ad8b3 | 336 | """linkstate of the interface""" |
41febf89 RP |
337 | self.type = ifaceType.UNKNOWN |
338 | """interface type""" | |
339 | self.priv_data = None | |
0a3bee28 | 340 | self.role = ifaceRole.UNKNOWN |
2da58137 | 341 | self.realname = None |
a070c90e | 342 | self.link_type = ifaceLinkType.LINK_UNKNOWN |
c65c2ccd | 343 | self.link_kind = ifaceLinkKind.UNKNOWN |
a6f80f0e | 344 | |
45ca0b6d RP |
345 | # The below attribute is used to disambiguate between various |
346 | # types of dependencies | |
347 | self.dependency_type = ifaceDependencyType.UNKNOWN | |
0532f0a3 | 348 | self.blacklisted = False |
45ca0b6d | 349 | |
3dcc1d0e | 350 | def _set_attrs_from_dict(self, attrdict): |
351 | self.auto = attrdict.get('auto', False) | |
352 | self.name = attrdict.get('name') | |
353 | self.addr_family = attrdict.get('addr_family') | |
354 | self.addr_method = attrdict.get('addr_method') | |
355 | self.config = attrdict.get('config', OrderedDict()) | |
356 | ||
a6f80f0e | 357 | def inc_refcnt(self): |
2c0ad8b3 RP |
358 | """ increment refcnt of the interface. Usually used to indicate that |
359 | it has dependents """ | |
a6f80f0e | 360 | self.refcnt += 1 |
361 | ||
362 | def dec_refcnt(self): | |
2c0ad8b3 RP |
363 | """ decrement refcnt of the interface. Usually used to indicate that |
364 | it has lost its dependent """ | |
a6f80f0e | 365 | self.refcnt -= 1 |
366 | ||
cca03c30 | 367 | def is_config_present(self): |
2c0ad8b3 RP |
368 | """ returns true if the interface has user provided config, |
369 | false otherwise """ | |
62ddec8b | 370 | addr_method = self.addr_method |
2cd06f78 | 371 | if addr_method and addr_method in ['dhcp', 'dhcp6', 'loopback']: |
372 | return True | |
fe0a57d3 | 373 | if not self.config: |
cca03c30 | 374 | return False |
fe0a57d3 | 375 | else: |
376 | return True | |
cca03c30 | 377 | |
3e8ee54f | 378 | def set_class(self, classname): |
2c0ad8b3 | 379 | """ appends class to the interfaces class list """ |
a6f80f0e | 380 | self.classes.append(classname) |
381 | ||
31a5f4c3 | 382 | def set_state_n_status(self, state, status): |
2c0ad8b3 | 383 | """ sets state and status of an interface """ |
31a5f4c3 | 384 | self.state = state |
385 | self.status = status | |
386 | ||
a6f80f0e | 387 | def set_flag(self, flag): |
388 | self.flags |= flag | |
389 | ||
390 | def clear_flag(self, flag): | |
391 | self.flags &= ~flag | |
392 | ||
f3215127 | 393 | def add_to_upperifaces(self, upperifacename): |
2c0ad8b3 | 394 | """ add to the list of upperifaces """ |
f3215127 | 395 | if self.upperifaces: |
396 | if upperifacename not in self.upperifaces: | |
397 | self.upperifaces.append(upperifacename) | |
398 | else: | |
399 | self.upperifaces = [upperifacename] | |
400 | ||
a6f80f0e | 401 | def get_attr_value(self, attr_name): |
2c0ad8b3 | 402 | """ add to the list of upperifaces """ |
62ddec8b | 403 | return self.config.get(attr_name) |
a6f80f0e | 404 | |
405 | def get_attr_value_first(self, attr_name): | |
2c0ad8b3 | 406 | """ get first value of the specified attr name """ |
62ddec8b | 407 | attr_value_list = self.config.get(attr_name) |
fe0a57d3 | 408 | if attr_value_list: |
a6f80f0e | 409 | return attr_value_list[0] |
a6f80f0e | 410 | return None |
411 | ||
679e6567 RP |
412 | def get_attrs_value_first(self, attrs): |
413 | """ get first value of the first attr in the list. | |
414 | Useful when you have multiple attrs representing the | |
415 | same thing. | |
416 | """ | |
417 | for attr in attrs: | |
418 | attr_value_list = self.config.get(attr) | |
419 | if attr_value_list: | |
420 | return attr_value_list[0] | |
421 | return None | |
422 | ||
a6f80f0e | 423 | def get_attr_value_n(self, attr_name, attr_index): |
2c0ad8b3 | 424 | """ get n'th value of the specified attr name """ |
62ddec8b | 425 | attr_value_list = self.config.get(attr_name) |
fe0a57d3 | 426 | if attr_value_list: |
a6f80f0e | 427 | try: |
428 | return attr_value_list[attr_index] | |
429 | except: | |
430 | return None | |
a6f80f0e | 431 | return None |
432 | ||
62ddec8b | 433 | @property |
a6f80f0e | 434 | def get_env(self): |
2c0ad8b3 | 435 | """ get shell environment variables the interface must execute in """ |
fe0a57d3 | 436 | if not self.env: |
a6f80f0e | 437 | self.generate_env() |
438 | return self.env | |
439 | ||
a6f80f0e | 440 | def generate_env(self): |
2c0ad8b3 RP |
441 | """ generate shell environment variables dict interface must execute |
442 | in. This is used to support legacy ifupdown scripts | |
443 | """ | |
a6f80f0e | 444 | env = {} |
62ddec8b | 445 | config = self.config |
446 | env['IFACE'] = self.name | |
a6f80f0e | 447 | for attr, attr_value in config.items(): |
448 | attr_env_name = 'IF_%s' %attr.upper() | |
449 | env[attr_env_name] = attr_value[0] | |
fe0a57d3 | 450 | if env: |
62ddec8b | 451 | self.env = env |
a6f80f0e | 452 | |
739f665b | 453 | def update_config(self, attr_name, attr_value): |
2c0ad8b3 | 454 | """ add attribute name and value to the interface config """ |
62ddec8b | 455 | self.config.setdefault(attr_name, []).append(attr_value) |
739f665b | 456 | |
d8e3554d RP |
457 | def replace_config(self, attr_name, attr_value): |
458 | """ add attribute name and value to the interface config """ | |
459 | self.config[attr_name] = [attr_value] | |
460 | ||
461 | def delete_config(self, attr_name): | |
462 | """ add attribute name and value to the interface config """ | |
463 | try: | |
464 | del self.config[attr_name] | |
465 | except: | |
466 | pass | |
467 | ||
739f665b | 468 | def update_config_dict(self, attrdict): |
469 | self.config.update(attrdict) | |
470 | ||
471 | def update_config_with_status(self, attr_name, attr_value, attr_status=0): | |
2c0ad8b3 RP |
472 | """ add attribute name and value to the interface config and also |
473 | update the config_status dict with status of this attribute config """ | |
69f58278 | 474 | if not attr_value: |
a6f80f0e | 475 | attr_value = '' |
62ddec8b | 476 | self.config.setdefault(attr_name, []).append(attr_value) |
477 | self._config_status.setdefault(attr_name, []).append(attr_status) | |
69f58278 | 478 | # set global iface state |
e1601369 | 479 | if attr_status == 1: |
62ddec8b | 480 | self.status = ifaceStatus.ERROR |
481 | elif self.status != ifaceStatus.ERROR: | |
69f58278 | 482 | # Not already error, mark success |
62ddec8b | 483 | self.status = ifaceStatus.SUCCESS |
69f58278 | 484 | |
a070c90e | 485 | def check_n_update_config_with_status_many(self, ifaceobjorig, attr_names, |
e1601369 RP |
486 | attr_status=0): |
487 | # set multiple attribute status to zero | |
488 | # also updates status only if the attribute is present | |
489 | for attr_name in attr_names: | |
a070c90e RP |
490 | if not ifaceobjorig.get_attr_value_first(attr_name): |
491 | continue | |
e1601369 RP |
492 | self.config.setdefault(attr_name, []).append('') |
493 | self._config_status.setdefault(attr_name, []).append(attr_status) | |
494 | ||
69f58278 | 495 | def get_config_attr_status(self, attr_name, idx=0): |
2c0ad8b3 RP |
496 | """ get status of a attribute config on this interface. |
497 | ||
498 | Looks at the iface _config_status dict""" | |
62ddec8b | 499 | return self._config_status.get(attr_name, [])[idx] |
69f58278 | 500 | |
ca3f4fc7 | 501 | def compare(self, dstiface): |
2c0ad8b3 | 502 | """ compares iface object with iface object passed as argument |
ca3f4fc7 | 503 | |
504 | Returns True if object self is same as dstiface and False otherwise """ | |
505 | ||
506 | if self.name != dstiface.name: return False | |
84ca006f | 507 | if self.type != dstiface.type: return False |
ca3f4fc7 | 508 | if self.addr_family != dstiface.addr_family: return False |
509 | if self.addr_method != dstiface.addr_method: return False | |
510 | if self.auto != dstiface.auto: return False | |
511 | if self.classes != dstiface.classes: return False | |
acf92644 RP |
512 | if len(self.config) != len(dstiface.config): |
513 | return False | |
37c0543d | 514 | if any(True for k in self.config if k not in dstiface.config): |
ca3f4fc7 | 515 | return False |
37c0543d | 516 | if any(True for k,v in self.config.items() |
ca3f4fc7 | 517 | if v != dstiface.config.get(k)): return False |
518 | return True | |
d08d5f54 | 519 | |
e1601369 | 520 | |
d08d5f54 | 521 | def __getstate__(self): |
522 | odict = self.__dict__.copy() | |
523 | del odict['state'] | |
524 | del odict['status'] | |
f3215127 | 525 | del odict['lowerifaces'] |
c798b0f4 | 526 | del odict['upperifaces'] |
d08d5f54 | 527 | del odict['refcnt'] |
62ddec8b | 528 | del odict['_config_status'] |
5c721925 | 529 | del odict['flags'] |
530 | del odict['priv_flags'] | |
4c773918 | 531 | del odict['module_flags'] |
62ddec8b | 532 | del odict['raw_config'] |
5c721925 | 533 | del odict['linkstate'] |
534 | del odict['env'] | |
c416da6a | 535 | del odict['link_type'] |
a9ab1b4f | 536 | del odict['link_kind'] |
0a3bee28 | 537 | del odict['role'] |
45ca0b6d | 538 | del odict['dependency_type'] |
0532f0a3 | 539 | del odict['blacklisted'] |
d08d5f54 | 540 | return odict |
541 | ||
542 | def __setstate__(self, dict): | |
543 | self.__dict__.update(dict) | |
62ddec8b | 544 | self._config_status = {} |
d08d5f54 | 545 | self.state = ifaceState.NEW |
546 | self.status = ifaceStatus.UNKNOWN | |
547 | self.refcnt = 0 | |
5c721925 | 548 | self.flags = 0 |
f3215127 | 549 | self.lowerifaces = None |
c798b0f4 | 550 | self.upperifaces = None |
d08d5f54 | 551 | self.linkstate = None |
5c721925 | 552 | self.env = None |
0a3bee28 | 553 | self.role = ifaceRole.UNKNOWN |
dbc018d3 | 554 | self.priv_flags = None |
4c773918 | 555 | self.module_flags = {} |
62ddec8b | 556 | self.raw_config = [] |
557 | self.flags |= self._PICKLED | |
f3b69969 | 558 | self.link_type = ifaceLinkType.LINK_NA |
a9ab1b4f | 559 | self.link_kind = ifaceLinkKind.UNKNOWN |
45ca0b6d | 560 | self.dependency_type = ifaceDependencyType.UNKNOWN |
0532f0a3 | 561 | self.blacklisted = False |
3dcc1d0e | 562 | |
a6f80f0e | 563 | def dump_raw(self, logger): |
564 | indent = ' ' | |
53b00224 | 565 | if self.auto: |
566 | print 'auto %s' %self.name | |
62ddec8b | 567 | print (self.raw_config[0]) |
568 | for i in range(1, len(self.raw_config)): | |
53b00224 | 569 | print(indent + self.raw_config[i]) |
a6f80f0e | 570 | |
a6f80f0e | 571 | def dump(self, logger): |
572 | indent = '\t' | |
62ddec8b | 573 | logger.info(self.name + ' : {') |
574 | logger.info(indent + 'family: %s' %self.addr_family) | |
575 | logger.info(indent + 'method: %s' %self.addr_method) | |
31a5f4c3 | 576 | logger.info(indent + 'flags: %x' %self.flags) |
a6f80f0e | 577 | logger.info(indent + 'state: %s' |
62ddec8b | 578 | %ifaceState.to_str(self.state)) |
a6f80f0e | 579 | logger.info(indent + 'status: %s' |
62ddec8b | 580 | %ifaceStatus.to_str(self.status)) |
581 | logger.info(indent + 'refcnt: %d' %self.refcnt) | |
582 | d = self.lowerifaces | |
fe0a57d3 | 583 | if d: |
f3215127 | 584 | logger.info(indent + 'lowerdevs: %s' %str(d)) |
a6f80f0e | 585 | else: |
f3215127 | 586 | logger.info(indent + 'lowerdevs: None') |
739f665b | 587 | |
a6f80f0e | 588 | logger.info(indent + 'config: ') |
62ddec8b | 589 | config = self.config |
fe0a57d3 | 590 | if config: |
a6f80f0e | 591 | logger.info(indent + indent + str(config)) |
592 | logger.info('}') | |
593 | ||
fb10449e | 594 | def dump_pretty(self, with_status=False, use_realname=False): |
a6f80f0e | 595 | indent = '\t' |
cca03c30 | 596 | outbuf = '' |
b48ff1a9 RP |
597 | if use_realname and self.realname: |
598 | name = '%s' %self.realname | |
2da58137 | 599 | else: |
b48ff1a9 | 600 | name = '%s' %self.name |
62ddec8b | 601 | if self.auto: |
2da58137 | 602 | outbuf += 'auto %s\n' %name |
5b4d3044 | 603 | ifaceline = '' |
cb46a208 | 604 | if self.type == ifaceType.BRIDGE_VLAN: |
5b4d3044 | 605 | ifaceline += 'vlan %s' %name |
cb46a208 | 606 | else: |
5b4d3044 | 607 | ifaceline += 'iface %s' %name |
62ddec8b | 608 | if self.addr_family: |
5b4d3044 | 609 | ifaceline += ' %s' %self.addr_family |
62ddec8b | 610 | if self.addr_method: |
5b4d3044 | 611 | ifaceline += ' %s' %self.addr_method |
2cd06f78 | 612 | if with_status: |
5b4d3044 | 613 | status_str = None |
e1601369 RP |
614 | if (self.status == ifaceStatus.ERROR or |
615 | self.status == ifaceStatus.NOTFOUND): | |
616 | if self.status_str: | |
5b4d3044 | 617 | ifaceline += ' (%s)' %self.status_str |
307e06bb | 618 | status_str = '[%s]' %ifaceStatusUserStrs.ERROR |
86fc62e2 | 619 | elif self.status == ifaceStatus.SUCCESS: |
307e06bb | 620 | status_str = '[%s]' %ifaceStatusUserStrs.SUCCESS |
5b4d3044 RP |
621 | if status_str: |
622 | outbuf += '{0:65} {1:>8}'.format(ifaceline, status_str) + '\n' | |
623 | else: | |
624 | outbuf += ifaceline + '\n' | |
2cd06f78 | 625 | if self.status == ifaceStatus.NOTFOUND: |
e1601369 RP |
626 | outbuf = (outbuf.encode('utf8') |
627 | if isinstance(outbuf, unicode) else outbuf) | |
2cd06f78 | 628 | print outbuf + '\n' |
629 | return | |
5b4d3044 RP |
630 | else: |
631 | outbuf += ifaceline + '\n' | |
62ddec8b | 632 | config = self.config |
fe0a57d3 | 633 | if config: |
eab25b7c | 634 | for cname, cvaluelist in config.items(): |
69f58278 | 635 | idx = 0 |
eab25b7c | 636 | for cv in cvaluelist: |
307e06bb | 637 | status_str = None |
69f58278 | 638 | if with_status: |
86fc62e2 | 639 | s = self.get_config_attr_status(cname, idx) |
e1601369 | 640 | if s == -1: |
307e06bb | 641 | status_str = '[%s]' %ifaceStatusUserStrs.UNKNOWN |
e1601369 | 642 | elif s == 1: |
307e06bb | 643 | status_str = '[%s]' %ifaceStatusUserStrs.ERROR |
86fc62e2 | 644 | elif s == 0: |
307e06bb RP |
645 | status_str = '[%s]' %ifaceStatusUserStrs.SUCCESS |
646 | if status_str: | |
5b4d3044 | 647 | outbuf += (indent + '{0:55} {1:>10}'.format( |
307e06bb | 648 | '%s %s' %(cname, cv), status_str)) + '\n' |
69f58278 | 649 | else: |
650 | outbuf += indent + '%s %s\n' %(cname, cv) | |
651 | idx += 1 | |
3dcc1d0e | 652 | if with_status: |
653 | outbuf = (outbuf.encode('utf8') | |
654 | if isinstance(outbuf, unicode) else outbuf) | |
a6f80f0e | 655 | print outbuf |