]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown/iface.py
3 # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
10 """ifupdown2 network interface object
12 It is modeled based on the 'iface' section in /etc/network/interfaces
13 file. But can be extended to include any other network interface format
16 from collections
import OrderedDict
26 """Enumerates iface status """
34 def to_str(cls
, state
):
35 if state
== cls
.UNKNOWN
:
37 elif state
== cls
.SUCCESS
:
39 elif state
== cls
.ERROR
:
41 elif state
== cls
.NOTFOUND
:
45 def from_str(cls
, state_str
):
46 if state_str
== 'unknown':
48 elif state_str
== 'success':
50 elif state_str
== 'error':
54 """Enumerates iface state """
70 def to_str(cls
, state
):
71 if state
== cls
.UNKNOWN
:
73 elif state
== cls
.NEW
:
75 elif state
== cls
.PRE_UP
:
79 elif state
== cls
.POST_UP
:
81 elif state
== cls
.PRE_DOWN
:
83 elif state
== cls
.DOWN
:
85 elif state
== cls
.POST_DOWN
:
87 elif state
== cls
.QUERY_CHECKCURR
:
88 return 'query-checkcurr'
89 elif state
== cls
.QUERY_RUNNING
:
90 return 'query-running'
93 def from_str(cls
, state_str
):
94 if state_str
== 'unknown':
96 elif state_str
== 'new':
98 elif state_str
== 'pre-up':
100 elif state_str
== 'up':
102 elif state_str
== 'post-up':
104 elif state_str
== 'pre-down':
106 elif state_str
== 'down':
108 elif state_str
== 'post-down':
110 elif state_str
== 'query-checkcurr':
111 return cls
.QUERY_CHECKCURR
112 elif state_str
== 'query-running':
113 return cls
.QUERY_RUNNING
115 class ifaceJsonEncoder(json
.JSONEncoder
):
116 def default(self
, o
):
119 retconfig
= dict((k
, (v
[0] if len(v
) == 1 else v
))
120 for k
,v
in o
.config
.items())
121 return OrderedDict({'name' : o
.name
,
122 'addr_method' : o
.addr_method
,
123 'addr_family' : o
.addr_family
,
125 'config' : retconfig
})
127 class ifaceJsonDecoder():
129 def json_to_ifaceobj(cls
, ifaceattrdict
):
130 ifaceattrdict
['config'] = OrderedDict([(k
, (v
if isinstance(v
, list)
132 for k
,v
in ifaceattrdict
.get('config',
133 OrderedDict()).items()])
134 return iface(attrsdict
=ifaceattrdict
)
137 """ ifupdown2 iface object class
140 **name** Name of the interface
142 **addr_family** Address family eg, inet, inet6. Can be None to
143 indicate both address families
145 **addr_method** Address method eg, static, manual or None for
146 static address method
148 **config** dictionary of config lines for this interface
150 **state** Configuration state of an interface as defined by
153 **status** Configuration status of an interface as defined by
156 **flags** Internal flags used by iface processing
158 **priv_flags** private flags owned by module using this class
160 **refcnt** reference count, indicating number of interfaces
161 dependent on this iface
163 **lowerifaces** list of interface names lower to this interface or
164 this interface depends on
166 **upperifaces** list of interface names upper to this interface or
167 the interfaces that depend on this interface
169 **auto** True if interface belongs to the auto class
171 **classes** List of classes the interface belongs to
173 **env** shell environment the interface needs during
176 **raw_config** raw interface config from file
179 # flag to indicate that the object was created from pickled state
182 IFACERANGE_ENTRY
= 0x3
183 IFACERANGE_START
= 0x4
187 def __init__(self
, attrsdict
={}):
188 self
._set
_attrs
_from
_dict
(attrsdict
)
189 self
._config
_status
= {}
190 """dict with config status of iface attributes"""
191 self
.state
= ifaceState
.NEW
192 """iface state (of type ifaceState) """
193 self
.status
= ifaceStatus
.UNKNOWN
194 """iface status (of type ifaceStatus) """
195 self
.status_str
= None
196 """iface status str (string representing the status) """
199 self
.priv_flags
= 0x0
200 """iface priv flags. can be used by the external object manager """
202 """iface refcnt (incremented for each dependent this interface has) """
203 self
.lowerifaces
= None
204 """lower iface list (in other words: slaves of this interface """
205 self
.upperifaces
= None
206 """upper iface list (in other words: master of this interface """
208 """interface classes this iface belongs to """
210 """environment variable dict required for this interface to run"""
212 """interface config/attributes in raw format (eg: as it appeared in the interfaces file)"""
213 self
.linkstate
= None
214 """linkstate of the interface"""
215 self
.type = ifaceType
.UNKNOWN
217 self
.priv_data
= None
220 def _set_attrs_from_dict(self
, attrdict
):
221 self
.auto
= attrdict
.get('auto', False)
222 self
.name
= attrdict
.get('name')
223 self
.addr_family
= attrdict
.get('addr_family')
224 self
.addr_method
= attrdict
.get('addr_method')
225 self
.config
= attrdict
.get('config', OrderedDict())
227 def inc_refcnt(self
):
228 """ increment refcnt of the interface. Usually used to indicate that
229 it has dependents """
232 def dec_refcnt(self
):
233 """ decrement refcnt of the interface. Usually used to indicate that
234 it has lost its dependent """
237 def is_config_present(self
):
238 """ returns true if the interface has user provided config,
240 addr_method
= self
.addr_method
241 if addr_method
and addr_method
in ['dhcp', 'dhcp6', 'loopback']:
248 def set_class(self
, classname
):
249 """ appends class to the interfaces class list """
250 self
.classes
.append(classname
)
252 def set_state_n_status(self
, state
, status
):
253 """ sets state and status of an interface """
257 def set_flag(self
, flag
):
260 def clear_flag(self
, flag
):
263 def add_to_upperifaces(self
, upperifacename
):
264 """ add to the list of upperifaces """
266 if upperifacename
not in self
.upperifaces
:
267 self
.upperifaces
.append(upperifacename
)
269 self
.upperifaces
= [upperifacename
]
271 def get_attr_value(self
, attr_name
):
272 """ add to the list of upperifaces """
273 return self
.config
.get(attr_name
)
275 def get_attr_value_first(self
, attr_name
):
276 """ get first value of the specified attr name """
277 attr_value_list
= self
.config
.get(attr_name
)
279 return attr_value_list
[0]
282 def get_attrs_value_first(self
, attrs
):
283 """ get first value of the first attr in the list.
284 Useful when you have multiple attrs representing the
288 attr_value_list
= self
.config
.get(attr
)
290 return attr_value_list
[0]
293 def get_attr_value_n(self
, attr_name
, attr_index
):
294 """ get n'th value of the specified attr name """
295 attr_value_list
= self
.config
.get(attr_name
)
298 return attr_value_list
[attr_index
]
305 """ get shell environment variables the interface must execute in """
310 def generate_env(self
):
311 """ generate shell environment variables dict interface must execute
312 in. This is used to support legacy ifupdown scripts
316 env
['IFACE'] = self
.name
317 for attr
, attr_value
in config
.items():
318 attr_env_name
= 'IF_%s' %attr
.upper()
319 env
[attr_env_name
] = attr_value
[0]
323 def update_config(self
, attr_name
, attr_value
):
324 """ add attribute name and value to the interface config """
325 self
.config
.setdefault(attr_name
, []).append(attr_value
)
327 def replace_config(self
, attr_name
, attr_value
):
328 """ add attribute name and value to the interface config """
329 self
.config
[attr_name
] = [attr_value
]
331 def delete_config(self
, attr_name
):
332 """ add attribute name and value to the interface config """
334 del self
.config
[attr_name
]
338 def update_config_dict(self
, attrdict
):
339 self
.config
.update(attrdict
)
341 def update_config_with_status(self
, attr_name
, attr_value
, attr_status
=0):
342 """ add attribute name and value to the interface config and also
343 update the config_status dict with status of this attribute config """
346 self
.config
.setdefault(attr_name
, []).append(attr_value
)
347 self
._config
_status
.setdefault(attr_name
, []).append(attr_status
)
348 # set global iface state
350 self
.status
= ifaceStatus
.ERROR
351 elif self
.status
!= ifaceStatus
.ERROR
:
352 # Not already error, mark success
353 self
.status
= ifaceStatus
.SUCCESS
355 def check_n_update_config_with_status_many(self
, attr_names
,
357 # set multiple attribute status to zero
358 # also updates status only if the attribute is present
359 for attr_name
in attr_names
:
360 if not self
.get_attr_value_first(attr_name
):
362 self
.config
.setdefault(attr_name
, []).append('')
363 self
._config
_status
.setdefault(attr_name
, []).append(attr_status
)
365 def get_config_attr_status(self
, attr_name
, idx
=0):
366 """ get status of a attribute config on this interface.
368 Looks at the iface _config_status dict"""
369 return self
._config
_status
.get(attr_name
, [])[idx
]
371 def compare(self
, dstiface
):
372 """ compares iface object with iface object passed as argument
374 Returns True if object self is same as dstiface and False otherwise """
376 if self
.name
!= dstiface
.name
: return False
377 if self
.type != dstiface
.type: return False
378 if self
.addr_family
!= dstiface
.addr_family
: return False
379 if self
.addr_method
!= dstiface
.addr_method
: return False
380 if self
.auto
!= dstiface
.auto
: return False
381 if self
.classes
!= dstiface
.classes
: return False
382 if any(True for k
in self
.config
if k
not in dstiface
.config
):
384 if any(True for k
,v
in self
.config
.items()
385 if v
!= dstiface
.config
.get(k
)): return False
389 def __getstate__(self
):
390 odict
= self
.__dict
__.copy()
393 del odict
['lowerifaces']
394 del odict
['upperifaces']
396 del odict
['_config_status']
398 del odict
['priv_flags']
399 del odict
['raw_config']
400 del odict
['linkstate']
404 def __setstate__(self
, dict):
405 self
.__dict
__.update(dict)
406 self
._config
_status
= {}
407 self
.state
= ifaceState
.NEW
408 self
.status
= ifaceStatus
.UNKNOWN
411 self
.lowerifaces
= None
412 self
.upperifaces
= None
413 self
.linkstate
= None
417 self
.flags |
= self
._PICKLED
419 def dump_raw(self
, logger
):
422 print 'auto %s' %self
.name
423 print (self
.raw_config
[0])
424 for i
in range(1, len(self
.raw_config
)):
425 print(indent
+ self
.raw_config
[i
])
427 def dump(self
, logger
):
429 logger
.info(self
.name
+ ' : {')
430 logger
.info(indent
+ 'family: %s' %self
.addr_family
)
431 logger
.info(indent
+ 'method: %s' %self
.addr_method
)
432 logger
.info(indent
+ 'flags: %x' %self
.flags
)
433 logger
.info(indent
+ 'state: %s'
434 %ifaceState
.to_str(self
.state
))
435 logger
.info(indent
+ 'status: %s'
436 %ifaceStatus
.to_str(self
.status
))
437 logger
.info(indent
+ 'refcnt: %d' %self
.refcnt
)
440 logger
.info(indent
+ 'lowerdevs: %s' %str
(d
))
442 logger
.info(indent
+ 'lowerdevs: None')
444 logger
.info(indent
+ 'config: ')
447 logger
.info(indent
+ indent
+ str(config
))
450 def dump_pretty(self
, with_status
=False,
451 successstr
='success', errorstr
='error',
452 unknownstr
='unknown', use_realname
=False):
460 outbuf
+= 'auto %s\n' %name
461 if self
.type == ifaceType
.BRIDGE_VLAN
:
462 outbuf
+= 'vlan %s' %name
464 outbuf
+= 'iface %s' %name
466 outbuf
+= ' %s' %self
.addr_family
468 outbuf
+= ' %s' %self
.addr_method
470 if (self
.status
== ifaceStatus
.ERROR
or
471 self
.status
== ifaceStatus
.NOTFOUND
):
473 outbuf
+= ' [%s]' %self
.status_str
474 outbuf
+= ' %s' %errorstr
475 elif self
.status
== ifaceStatus
.SUCCESS
:
476 outbuf
+= ' %s' %successstr
477 if self
.status
== ifaceStatus
.NOTFOUND
:
478 outbuf
= (outbuf
.encode('utf8')
479 if isinstance(outbuf
, unicode) else outbuf
)
485 for cname
, cvaluelist
in config
.items():
487 for cv
in cvaluelist
:
489 s
= self
.get_config_attr_status(cname
, idx
)
491 outbuf
+= (indent
+ '%s %s %s\n'
492 %(cname
, cv
, unknownstr
))
494 outbuf
+= (indent
+ '%s %s %s\n'
495 %(cname
, cv
, errorstr
))
497 outbuf
+= (indent
+ '%s %s %s\n'
498 %(cname
, cv
, successstr
))
500 outbuf
+= indent
+ '%s %s\n' %(cname
, cv
)
503 outbuf
= (outbuf
.encode('utf8')
504 if isinstance(outbuf
, unicode) else outbuf
)