]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/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
21 """Enumerates iface status """
29 def to_str(cls
, state
):
30 if state
== cls
.UNKNOWN
:
32 elif state
== cls
.SUCCESS
:
34 elif state
== cls
.ERROR
:
36 elif state
== cls
.NOTFOUND
:
40 def from_str(cls
, state_str
):
41 if state_str
== 'unknown':
43 elif state_str
== 'success':
45 elif state_str
== 'error':
49 """Enumerates iface state """
65 def to_str(cls
, state
):
66 if state
== cls
.UNKNOWN
:
68 elif state
== cls
.NEW
:
70 elif state
== cls
.PRE_UP
:
74 elif state
== cls
.POST_UP
:
76 elif state
== cls
.PRE_DOWN
:
78 elif state
== cls
.DOWN
:
80 elif state
== cls
.POST_DOWN
:
82 elif state
== cls
.QUERY_CHECKCURR
:
83 return 'query-checkcurr'
84 elif state
== cls
.QUERY_RUNNING
:
85 return 'query-running'
88 def from_str(cls
, state_str
):
89 if state_str
== 'unknown':
91 elif state_str
== 'new':
93 elif state_str
== 'pre-up':
95 elif state_str
== 'up':
97 elif state_str
== 'post-up':
99 elif state_str
== 'pre-down':
101 elif state_str
== 'down':
103 elif state_str
== 'post-down':
105 elif state_str
== 'query-checkcurr':
106 return cls
.QUERY_CHECKCURR
107 elif state_str
== 'query-running':
108 return cls
.QUERY_RUNNING
110 class ifaceJsonEncoder(json
.JSONEncoder
):
111 def default(self
, o
):
114 retconfig
= dict((k
, (v
[0] if len(v
) == 1 else v
))
115 for k
,v
in o
.config
.items())
116 return OrderedDict({'name' : o
.name
,
117 'addr_method' : o
.addr_method
,
118 'addr_family' : o
.addr_family
,
120 'config' : retconfig
})
122 class ifaceJsonDecoder():
124 def json_to_ifaceobj(cls
, ifaceattrdict
):
125 ifaceattrdict
['config'] = OrderedDict([(k
, (v
if isinstance(v
, list)
127 for k
,v
in ifaceattrdict
.get('config',
128 OrderedDict()).items()])
129 return iface(attrsdict
=ifaceattrdict
)
132 """ ifupdown2 iface object class
135 **name** Name of the interface
137 **addr_family** Address family eg, inet, inet6. Can be None to
138 indicate both address families
140 **addr_method** Address method eg, static, manual or None for
141 static address method
143 **config** dictionary of config lines for this interface
145 **state** Configuration state of an interface as defined by
148 **status** Configuration status of an interface as defined by
151 **flags** Internal flags used by iface processing
153 **priv_flags** private flags owned by module using this class
155 **refcnt** reference count, indicating number of interfaces
156 dependent on this iface
158 **lowerifaces** list of interface names lower to this interface or
159 this interface depends on
161 **upperifaces** list of interface names upper to this interface or
162 the interfaces that depend on this interface
164 **auto** True if interface belongs to the auto class
166 **classes** List of classes the interface belongs to
168 **env** shell environment the interface needs during
171 **raw_config** raw interface config from file
174 # flag to indicate that the object was created from pickled state
180 def __init__(self
, attrsdict
={}):
181 self
._set
_attrs
_from
_dict
(attrsdict
)
182 self
._config
_status
= {}
183 """dict with config status of iface attributes"""
184 self
.state
= ifaceState
.NEW
185 """iface state (of type ifaceState) """
186 self
.status
= ifaceStatus
.UNKNOWN
187 """iface status (of type ifaceStatus) """
190 self
.priv_flags
= 0x0
191 """iface priv flags. can be used by the external object manager """
193 """iface refcnt (incremented for each dependent this interface has) """
194 self
.lowerifaces
= None
195 """lower iface list (in other words: slaves of this interface """
196 self
.upperifaces
= None
197 """upper iface list (in other words: master of this interface """
199 """interface classes this iface belongs to """
201 """environment variable dict required for this interface to run"""
203 """interface config/attributes in raw format (eg: as it appeared in the interfaces file)"""
204 self
.linkstate
= None
205 """linkstate of the interface"""
207 def _set_attrs_from_dict(self
, attrdict
):
208 self
.auto
= attrdict
.get('auto', False)
209 self
.name
= attrdict
.get('name')
210 self
.addr_family
= attrdict
.get('addr_family')
211 self
.addr_method
= attrdict
.get('addr_method')
212 self
.config
= attrdict
.get('config', OrderedDict())
214 def inc_refcnt(self
):
215 """ increment refcnt of the interface. Usually used to indicate that
216 it has dependents """
219 def dec_refcnt(self
):
220 """ decrement refcnt of the interface. Usually used to indicate that
221 it has lost its dependent """
224 def is_config_present(self
):
225 """ returns true if the interface has user provided config,
227 addr_method
= self
.addr_method
228 if addr_method
and addr_method
in ['dhcp', 'dhcp6', 'loopback']:
235 def set_class(self
, classname
):
236 """ appends class to the interfaces class list """
237 self
.classes
.append(classname
)
239 def set_state_n_status(self
, state
, status
):
240 """ sets state and status of an interface """
244 def set_flag(self
, flag
):
247 def clear_flag(self
, flag
):
250 def add_to_upperifaces(self
, upperifacename
):
251 """ add to the list of upperifaces """
253 if upperifacename
not in self
.upperifaces
:
254 self
.upperifaces
.append(upperifacename
)
256 self
.upperifaces
= [upperifacename
]
258 def get_attr_value(self
, attr_name
):
259 """ add to the list of upperifaces """
260 return self
.config
.get(attr_name
)
262 def get_attr_value_first(self
, attr_name
):
263 """ get first value of the specified attr name """
264 attr_value_list
= self
.config
.get(attr_name
)
266 return attr_value_list
[0]
269 def get_attr_value_n(self
, attr_name
, attr_index
):
270 """ get n'th value of the specified attr name """
271 attr_value_list
= self
.config
.get(attr_name
)
274 return attr_value_list
[attr_index
]
281 """ get shell environment variables the interface must execute in """
286 def generate_env(self
):
287 """ generate shell environment variables dict interface must execute
288 in. This is used to support legacy ifupdown scripts
292 env
['IFACE'] = self
.name
293 for attr
, attr_value
in config
.items():
294 attr_env_name
= 'IF_%s' %attr
.upper()
295 env
[attr_env_name
] = attr_value
[0]
299 def update_config(self
, attr_name
, attr_value
):
300 """ add attribute name and value to the interface config """
301 self
.config
.setdefault(attr_name
, []).append(attr_value
)
303 def update_config_dict(self
, attrdict
):
304 self
.config
.update(attrdict
)
306 def update_config_with_status(self
, attr_name
, attr_value
, attr_status
=0):
307 """ add attribute name and value to the interface config and also
308 update the config_status dict with status of this attribute config """
311 self
.config
.setdefault(attr_name
, []).append(attr_value
)
312 self
._config
_status
.setdefault(attr_name
, []).append(attr_status
)
314 # set global iface state
316 self
.status
= ifaceStatus
.ERROR
317 elif self
.status
!= ifaceStatus
.ERROR
:
318 # Not already error, mark success
319 self
.status
= ifaceStatus
.SUCCESS
321 def get_config_attr_status(self
, attr_name
, idx
=0):
322 """ get status of a attribute config on this interface.
324 Looks at the iface _config_status dict"""
325 return self
._config
_status
.get(attr_name
, [])[idx
]
327 def compare(self
, dstiface
):
328 """ compares iface object with iface object passed as argument
330 Returns True if object self is same as dstiface and False otherwise """
332 if self
.name
!= dstiface
.name
: return False
333 if self
.addr_family
!= dstiface
.addr_family
: return False
334 if self
.addr_method
!= dstiface
.addr_method
: return False
335 if self
.auto
!= dstiface
.auto
: return False
336 if self
.classes
!= dstiface
.classes
: return False
337 if any(True for k
in self
.config
if k
not in dstiface
.config
):
339 if any(True for k
,v
in self
.config
.items()
340 if v
!= dstiface
.config
.get(k
)): return False
343 def __getstate__(self
):
344 odict
= self
.__dict
__.copy()
347 del odict
['lowerifaces']
348 del odict
['upperifaces']
350 del odict
['_config_status']
352 del odict
['priv_flags']
353 del odict
['raw_config']
354 del odict
['linkstate']
358 def __setstate__(self
, dict):
359 self
.__dict
__.update(dict)
360 self
._config
_status
= {}
361 self
.state
= ifaceState
.NEW
362 self
.status
= ifaceStatus
.UNKNOWN
365 self
.lowerifaces
= None
366 self
.upperifaces
= None
367 self
.linkstate
= None
371 self
.flags |
= self
._PICKLED
373 def dump_raw(self
, logger
):
376 print 'auto %s' %self
.name
377 print (self
.raw_config
[0])
378 for i
in range(1, len(self
.raw_config
)):
379 print(indent
+ self
.raw_config
[i
])
381 def dump(self
, logger
):
383 logger
.info(self
.name
+ ' : {')
384 logger
.info(indent
+ 'family: %s' %self
.addr_family
)
385 logger
.info(indent
+ 'method: %s' %self
.addr_method
)
386 logger
.info(indent
+ 'flags: %x' %self
.flags
)
387 logger
.info(indent
+ 'state: %s'
388 %ifaceState
.to_str(self
.state
))
389 logger
.info(indent
+ 'status: %s'
390 %ifaceStatus
.to_str(self
.status
))
391 logger
.info(indent
+ 'refcnt: %d' %self
.refcnt
)
394 logger
.info(indent
+ 'lowerdevs: %s' %str
(d
))
396 logger
.info(indent
+ 'lowerdevs: None')
398 logger
.info(indent
+ 'config: ')
401 logger
.info(indent
+ indent
+ str(config
))
404 def dump_pretty(self
, with_status
=False,
405 successstr
='success', errorstr
='error'):
409 outbuf
+= 'auto %s\n' %self
.name
410 outbuf
+= 'iface %s' %self
.name
412 outbuf
+= ' %s' %self
.addr_family
414 outbuf
+= ' %s' %self
.addr_method
416 if (self
.status
== ifaceStatus
.NOTFOUND
or
417 self
.status
== ifaceStatus
.ERROR
):
418 outbuf
+= ' (%s)' %errorstr
419 elif self
.status
== ifaceStatus
.SUCCESS
:
420 outbuf
+= ' (%s)' %successstr
421 if self
.status
== ifaceStatus
.NOTFOUND
:
423 outbuf
= (outbuf
.encode('utf8')
424 if isinstance(outbuf
, unicode) else outbuf
)
430 for cname
, cvaluelist
in config
.items():
432 for cv
in cvaluelist
:
435 s
= self
.get_config_attr_status(cname
, idx
)
437 outbuf
+= (indent
+ '%s %s (%s)\n'
438 %(cname
, cv
, errorstr
))
440 outbuf
+= (indent
+ '%s %s (%s)\n'
441 %(cname
, cv
, successstr
))
443 outbuf
+= indent
+ '%s %s\n' %(cname
, cv
)
446 outbuf
= (outbuf
.encode('utf8')
447 if isinstance(outbuf
, unicode) else outbuf
)