]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - pkg/iface.py
3 # Copyright 2013. Cumulus Networks, Inc.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
10 """ifupdown2 network interface object
12 It closely resembles the 'iface' object 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 interface object class
135 name Name of the interface
136 addr_family Address family eg, inet, inet6. Can be None to indicate both address families
137 addr_method Address method eg, static, manual or None for static
139 config dictionary of config lines for this interface
140 state Configuration state of an interface as defined by
142 status Configuration status of an interface as defined by
144 flags Internal flags used by iface processing
145 priv_flags private flags owned by module using this class
146 refcnt reference count, indicating number of interfaces
147 dependent on this iface
148 lowerifaces list of interface names lower to this interface or
149 this interface depends on
150 upperifaces list of interface names upper to this interface or
151 the interfaces that depend on this interface
152 auto True if interface belongs to the auto class
153 classes List of classes the interface belongs to
154 env shell environment the interface needs during execution
155 raw_config raw interface config from file
158 # flag to indicate that the object was created from pickled state
164 def __init__(self
, attrsdict
={}):
165 self
._set
_attrs
_from
_dict
(attrsdict
)
166 self
._config
_status
= {}
167 """dict with config status of iface attributes"""
168 self
.state
= ifaceState
.NEW
169 """iface state (of type ifaceState) """
170 self
.status
= ifaceStatus
.UNKNOWN
171 """iface status (of type ifaceStatus) """
174 self
.priv_flags
= 0x0
175 """iface priv flags. can be used by the external object manager """
177 """iface refcnt (incremented for each dependent this interface has) """
178 self
.lowerifaces
= None
179 """lower iface list (in other words: slaves of this interface """
180 self
.upperifaces
= None
181 """upper iface list (in other words: master of this interface """
183 """interface classes this iface belongs to """
185 """environment variable dict required for this interface to run"""
187 """interface config/attributes in raw format (eg: as it appeared in the interfaces file)"""
188 self
.linkstate
= None
189 """linkstate of the interface"""
191 def _set_attrs_from_dict(self
, attrdict
):
192 self
.auto
= attrdict
.get('auto', False)
193 self
.name
= attrdict
.get('name')
194 self
.addr_family
= attrdict
.get('addr_family')
195 self
.addr_method
= attrdict
.get('addr_method')
196 self
.config
= attrdict
.get('config', OrderedDict())
198 def inc_refcnt(self
):
199 """ increment refcnt of the interface. Usually used to indicate that
200 it has dependents """
203 def dec_refcnt(self
):
204 """ decrement refcnt of the interface. Usually used to indicate that
205 it has lost its dependent """
208 def is_config_present(self
):
209 """ returns true if the interface has user provided config,
211 addr_method
= self
.addr_method
212 if addr_method
and addr_method
in ['dhcp', 'dhcp6', 'loopback']:
219 def set_class(self
, classname
):
220 """ appends class to the interfaces class list """
221 self
.classes
.append(classname
)
223 def set_state_n_status(self
, state
, status
):
224 """ sets state and status of an interface """
228 def set_flag(self
, flag
):
231 def clear_flag(self
, flag
):
234 def add_to_upperifaces(self
, upperifacename
):
235 """ add to the list of upperifaces """
237 if upperifacename
not in self
.upperifaces
:
238 self
.upperifaces
.append(upperifacename
)
240 self
.upperifaces
= [upperifacename
]
242 def get_attr_value(self
, attr_name
):
243 """ add to the list of upperifaces """
244 return self
.config
.get(attr_name
)
246 def get_attr_value_first(self
, attr_name
):
247 """ get first value of the specified attr name """
248 attr_value_list
= self
.config
.get(attr_name
)
250 return attr_value_list
[0]
253 def get_attr_value_n(self
, attr_name
, attr_index
):
254 """ get n'th value of the specified attr name """
255 attr_value_list
= self
.config
.get(attr_name
)
258 return attr_value_list
[attr_index
]
265 """ get shell environment variables the interface must execute in """
270 def generate_env(self
):
271 """ generate shell environment variables dict interface must execute
272 in. This is used to support legacy ifupdown scripts
276 env
['IFACE'] = self
.name
277 for attr
, attr_value
in config
.items():
278 attr_env_name
= 'IF_%s' %attr
.upper()
279 env
[attr_env_name
] = attr_value
[0]
283 def update_config(self
, attr_name
, attr_value
):
284 """ add attribute name and value to the interface config """
285 self
.config
.setdefault(attr_name
, []).append(attr_value
)
287 def update_config_dict(self
, attrdict
):
288 self
.config
.update(attrdict
)
290 def update_config_with_status(self
, attr_name
, attr_value
, attr_status
=0):
291 """ add attribute name and value to the interface config and also
292 update the config_status dict with status of this attribute config """
295 self
.config
.setdefault(attr_name
, []).append(attr_value
)
296 self
._config
_status
.setdefault(attr_name
, []).append(attr_status
)
298 # set global iface state
300 self
.status
= ifaceStatus
.ERROR
301 elif self
.status
!= ifaceStatus
.ERROR
:
302 # Not already error, mark success
303 self
.status
= ifaceStatus
.SUCCESS
305 def get_config_attr_status(self
, attr_name
, idx
=0):
306 """ get status of a attribute config on this interface.
308 Looks at the iface _config_status dict"""
309 return self
._config
_status
.get(attr_name
, [])[idx
]
311 def compare(self
, dstiface
):
312 """ compares iface object with iface object passed as argument
314 Returns True if object self is same as dstiface and False otherwise """
316 if self
.name
!= dstiface
.name
: return False
317 if self
.addr_family
!= dstiface
.addr_family
: return False
318 if self
.addr_method
!= dstiface
.addr_method
: return False
319 if self
.auto
!= dstiface
.auto
: return False
320 if self
.classes
!= dstiface
.classes
: return False
321 if any(True for k
in self
.config
if k
not in dstiface
.config
):
323 if any(True for k
,v
in self
.config
.items()
324 if v
!= dstiface
.config
.get(k
)): return False
327 def __getstate__(self
):
328 odict
= self
.__dict
__.copy()
331 del odict
['lowerifaces']
332 del odict
['upperifaces']
334 del odict
['_config_status']
336 del odict
['priv_flags']
337 del odict
['raw_config']
338 del odict
['linkstate']
342 def __setstate__(self
, dict):
343 self
.__dict
__.update(dict)
344 self
._config
_status
= {}
345 self
.state
= ifaceState
.NEW
346 self
.status
= ifaceStatus
.UNKNOWN
349 self
.lowerifaces
= None
350 self
.upperifaces
= None
351 self
.linkstate
= None
355 self
.flags |
= self
._PICKLED
357 def dump_raw(self
, logger
):
360 print 'auto %s' %self
.name
361 print (self
.raw_config
[0])
362 for i
in range(1, len(self
.raw_config
)):
363 print(indent
+ self
.raw_config
[i
])
365 def dump(self
, logger
):
367 logger
.info(self
.name
+ ' : {')
368 logger
.info(indent
+ 'family: %s' %self
.addr_family
)
369 logger
.info(indent
+ 'method: %s' %self
.addr_method
)
370 logger
.info(indent
+ 'flags: %x' %self
.flags
)
371 logger
.info(indent
+ 'state: %s'
372 %ifaceState
.to_str(self
.state
))
373 logger
.info(indent
+ 'status: %s'
374 %ifaceStatus
.to_str(self
.status
))
375 logger
.info(indent
+ 'refcnt: %d' %self
.refcnt
)
378 logger
.info(indent
+ 'lowerdevs: %s' %str
(d
))
380 logger
.info(indent
+ 'lowerdevs: None')
382 logger
.info(indent
+ 'config: ')
385 logger
.info(indent
+ indent
+ str(config
))
388 def dump_pretty(self
, with_status
=False,
389 successstr
='success', errorstr
='error'):
393 outbuf
+= 'auto %s\n' %self
.name
394 outbuf
+= 'iface %s' %self
.name
396 outbuf
+= ' %s' %self
.addr_family
398 outbuf
+= ' %s' %self
.addr_method
400 if (self
.status
== ifaceStatus
.NOTFOUND
or
401 self
.status
== ifaceStatus
.ERROR
):
402 outbuf
+= ' (%s)' %errorstr
403 elif self
.status
== ifaceStatus
.SUCCESS
:
404 outbuf
+= ' (%s)' %successstr
405 if self
.status
== ifaceStatus
.NOTFOUND
:
407 outbuf
= (outbuf
.encode('utf8')
408 if isinstance(outbuf
, unicode) else outbuf
)
414 for cname
, cvaluelist
in config
.items():
416 for cv
in cvaluelist
:
419 s
= self
.get_config_attr_status(cname
, idx
)
421 outbuf
+= (indent
+ '%s %s (%s)\n'
422 %(cname
, cv
, errorstr
))
424 outbuf
+= (indent
+ '%s %s (%s)\n'
425 %(cname
, cv
, successstr
))
427 outbuf
+= indent
+ '%s %s\n' %(cname
, cv
)
430 outbuf
= (outbuf
.encode('utf8')
431 if isinstance(outbuf
, unicode) else outbuf
)