]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - pkg/iface.py
3e1b50b4da794f7ae5fdffb34ed5b42abdad3c51
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 The module contains the following public classes:
18 - ifaceState -- enumerates iface object state
20 - ifaceStatus -- enumerates iface object status (success/error)
22 - ifaceJsonEncoder -- Json encoder for the iface object
24 - iface -- network in terface object class
28 from collections
import OrderedDict
33 """Enumerates iface status """
41 def to_str(cls
, state
):
42 if state
== cls
.UNKNOWN
:
44 elif state
== cls
.SUCCESS
:
46 elif state
== cls
.ERROR
:
48 elif state
== cls
.NOTFOUND
:
52 def from_str(cls
, state_str
):
53 if state_str
== 'unknown':
55 elif state_str
== 'success':
57 elif state_str
== 'error':
61 """Enumerates iface state """
77 def to_str(cls
, state
):
78 if state
== cls
.UNKNOWN
:
80 elif state
== cls
.NEW
:
82 elif state
== cls
.PRE_UP
:
86 elif state
== cls
.POST_UP
:
88 elif state
== cls
.PRE_DOWN
:
90 elif state
== cls
.DOWN
:
92 elif state
== cls
.POST_DOWN
:
94 elif state
== cls
.QUERY_CHECKCURR
:
95 return 'query-checkcurr'
96 elif state
== cls
.QUERY_RUNNING
:
97 return 'query-running'
100 def from_str(cls
, state_str
):
101 if state_str
== 'unknown':
103 elif state_str
== 'new':
105 elif state_str
== 'pre-up':
107 elif state_str
== 'up':
109 elif state_str
== 'post-up':
111 elif state_str
== 'pre-down':
113 elif state_str
== 'down':
115 elif state_str
== 'post-down':
117 elif state_str
== 'query-checkcurr':
118 return cls
.QUERY_CHECKCURR
119 elif state_str
== 'query-running':
120 return cls
.QUERY_RUNNING
122 class ifaceJsonEncoder(json
.JSONEncoder
):
123 def default(self
, o
):
126 retconfig
= dict((k
, (v
[0] if len(v
) == 1 else v
))
127 for k
,v
in o
.config
.items())
128 return OrderedDict({'name' : o
.name
,
129 'addr_method' : o
.addr_method
,
130 'addr_family' : o
.addr_family
,
132 'config' : retconfig
})
134 class ifaceJsonDecoder():
136 def json_to_ifaceobj(cls
, ifaceattrdict
):
137 ifaceattrdict
['config'] = OrderedDict([(k
, (v
if isinstance(v
, list)
139 for k
,v
in ifaceattrdict
.get('config',
140 OrderedDict()).items()])
141 return iface(attrsdict
=ifaceattrdict
)
144 """ ifupdown2 interface object class
147 name Name of the interface
148 addr_family Address family eg, inet, inet6. Can be None to indicate both address families
149 addr_method Address method eg, static, manual or None for static
151 config dictionary of config lines for this interface
152 state Configuration state of an interface as defined by
154 status Configuration status of an interface as defined by
156 flags Internal flags used by iface processing
157 priv_flags private flags owned by module using this class
158 refcnt reference count, indicating number of interfaces
159 dependent on this iface
160 lowerifaces list of interface names lower to this interface or
161 this interface depends on
162 upperifaces list of interface names upper to this interface or
163 the interfaces that depend on this interface
164 auto True if interface belongs to the auto class
165 classes List of classes the interface belongs to
166 env shell environment the interface needs during execution
167 raw_config raw interface config from file
170 # flag to indicate that the object was created from pickled state
175 def __init__(self
, attrsdict
={}):
176 self
._set
_attrs
_from
_dict
(attrsdict
)
177 self
._config
_status
= {}
178 self
.state
= ifaceState
.NEW
179 self
.status
= ifaceStatus
.UNKNOWN
181 self
.priv_flags
= 0x0
183 self
.lowerifaces
= None
184 self
.upperifaces
= None
188 self
.linkstate
= None
190 def _set_attrs_from_dict(self
, attrdict
):
191 self
.auto
= attrdict
.get('auto', False)
192 self
.name
= attrdict
.get('name')
193 self
.addr_family
= attrdict
.get('addr_family')
194 self
.addr_method
= attrdict
.get('addr_method')
195 self
.config
= attrdict
.get('config', OrderedDict())
197 def inc_refcnt(self
):
200 def dec_refcnt(self
):
203 def is_config_present(self
):
204 addr_method
= self
.addr_method
205 if addr_method
and addr_method
in ['dhcp', 'dhcp6', 'loopback']:
212 def set_class(self
, classname
):
213 """ Appends a class to the list """
214 self
.classes
.append(classname
)
216 def set_state_n_status(self
, state
, status
):
220 def set_flag(self
, flag
):
223 def clear_flag(self
, flag
):
226 def add_to_upperifaces(self
, upperifacename
):
228 if upperifacename
not in self
.upperifaces
:
229 self
.upperifaces
.append(upperifacename
)
231 self
.upperifaces
= [upperifacename
]
233 def get_attr_value(self
, attr_name
):
234 return self
.config
.get(attr_name
)
236 def get_attr_value_first(self
, attr_name
):
237 attr_value_list
= self
.config
.get(attr_name
)
239 return attr_value_list
[0]
242 def get_attr_value_n(self
, attr_name
, attr_index
):
243 attr_value_list
= self
.config
.get(attr_name
)
246 return attr_value_list
[attr_index
]
257 def generate_env(self
):
260 env
['IFACE'] = self
.name
261 for attr
, attr_value
in config
.items():
262 attr_env_name
= 'IF_%s' %attr
.upper()
263 env
[attr_env_name
] = attr_value
[0]
267 def update_config(self
, attr_name
, attr_value
):
268 self
.config
.setdefault(attr_name
, []).append(attr_value
)
270 def update_config_dict(self
, attrdict
):
271 self
.config
.update(attrdict
)
273 def update_config_with_status(self
, attr_name
, attr_value
, attr_status
=0):
277 self
.config
.setdefault(attr_name
, []).append(attr_value
)
278 self
._config
_status
.setdefault(attr_name
, []).append(attr_status
)
280 # set global iface state
282 self
.status
= ifaceStatus
.ERROR
283 elif self
.status
!= ifaceStatus
.ERROR
:
284 # Not already error, mark success
285 self
.status
= ifaceStatus
.SUCCESS
287 def get_config_attr_status(self
, attr_name
, idx
=0):
288 return self
._config
_status
.get(attr_name
, [])[idx
]
290 def compare(self
, dstiface
):
291 """ Compares two objects
293 Returns True if object self is same as dstiface and False otherwise """
295 if self
.name
!= dstiface
.name
: return False
296 if self
.addr_family
!= dstiface
.addr_family
: return False
297 if self
.addr_method
!= dstiface
.addr_method
: return False
298 if self
.auto
!= dstiface
.auto
: return False
299 if self
.classes
!= dstiface
.classes
: return False
300 if any(True for k
in self
.config
if k
not in dstiface
.config
):
302 if any(True for k
,v
in self
.config
.items()
303 if v
!= dstiface
.config
.get(k
)): return False
306 def __getstate__(self
):
307 odict
= self
.__dict
__.copy()
310 del odict
['lowerifaces']
311 del odict
['upperifaces']
313 del odict
['_config_status']
315 del odict
['priv_flags']
316 del odict
['raw_config']
317 del odict
['linkstate']
321 def __setstate__(self
, dict):
322 self
.__dict
__.update(dict)
323 self
._config
_status
= {}
324 self
.state
= ifaceState
.NEW
325 self
.status
= ifaceStatus
.UNKNOWN
328 self
.lowerifaces
= None
329 self
.upperifaces
= None
330 self
.linkstate
= None
334 self
.flags |
= self
._PICKLED
336 def dump_raw(self
, logger
):
339 print 'auto %s' %self
.name
340 print (self
.raw_config
[0])
341 for i
in range(1, len(self
.raw_config
)):
342 print(indent
+ self
.raw_config
[i
])
344 def dump(self
, logger
):
346 logger
.info(self
.name
+ ' : {')
347 logger
.info(indent
+ 'family: %s' %self
.addr_family
)
348 logger
.info(indent
+ 'method: %s' %self
.addr_method
)
349 logger
.info(indent
+ 'flags: %x' %self
.flags
)
350 logger
.info(indent
+ 'state: %s'
351 %ifaceState
.to_str(self
.state
))
352 logger
.info(indent
+ 'status: %s'
353 %ifaceStatus
.to_str(self
.status
))
354 logger
.info(indent
+ 'refcnt: %d' %self
.refcnt
)
357 logger
.info(indent
+ 'lowerdevs: %s' %str
(d
))
359 logger
.info(indent
+ 'lowerdevs: None')
361 logger
.info(indent
+ 'config: ')
364 logger
.info(indent
+ indent
+ str(config
))
367 def dump_pretty(self
, with_status
=False,
368 successstr
='success', errorstr
='error'):
372 outbuf
+= 'auto %s\n' %self
.name
373 outbuf
+= 'iface %s' %self
.name
375 outbuf
+= ' %s' %self
.addr_family
377 outbuf
+= ' %s' %self
.addr_method
379 if (self
.status
== ifaceStatus
.NOTFOUND
or
380 self
.status
== ifaceStatus
.ERROR
):
381 outbuf
+= ' (%s)' %errorstr
382 elif self
.status
== ifaceStatus
.SUCCESS
:
383 outbuf
+= ' (%s)' %successstr
384 if self
.status
== ifaceStatus
.NOTFOUND
:
386 outbuf
= (outbuf
.encode('utf8')
387 if isinstance(outbuf
, unicode) else outbuf
)
393 for cname
, cvaluelist
in config
.items():
395 for cv
in cvaluelist
:
398 s
= self
.get_config_attr_status(cname
, idx
)
400 outbuf
+= (indent
+ '%s %s (%s)\n'
401 %(cname
, cv
, errorstr
))
403 outbuf
+= (indent
+ '%s %s (%s)\n'
404 %(cname
, cv
, successstr
))
406 outbuf
+= indent
+ '%s %s\n' %(cname
, cv
)
409 outbuf
= (outbuf
.encode('utf8')
410 if isinstance(outbuf
, unicode) else outbuf
)