# iface --
# interface object
#
-
from collections import OrderedDict
-import logging
+#from json import *
import json
+import logging
-class ifaceFlags():
+tickmark = ' (' + u'\u2713'.encode('utf8') + ')'
+crossmark = ' (' + u'\u2717'.encode('utf8') + ')'
+class ifaceFlags():
NONE = 0x1
FOLLOW_DEPENDENTS = 0x2
class ifaceStatus():
-
"""iface status """
UNKNOWN = 0x1
SUCCESS = 0x2
elif state == cls.ERROR:
return 'error'
elif state == cls.NOTFOUND:
- return 'not found'
+ return 'notfound'
@classmethod
def from_str(cls, state_str):
DOWN = 0x7
POST_DOWN = 0x8
+ # Pseudo states
+ QUERY_CHECKCURR = 0x9
+ QUERY_RUNNING = 0xa
+
@classmethod
def to_str(cls, state):
if state == cls.UNKNOWN:
return 'post-up'
elif state == cls.PRE_DOWN:
return 'pre-down'
+ elif state == cls.DOWN:
+ return 'down'
elif state == cls.POST_DOWN:
return 'post-down'
+ elif state == cls.QUERY_CHECKCURR:
+ return 'query-checkcurr'
+ elif state == cls.QUERY_RUNNING:
+ return 'query-running'
@classmethod
def from_str(cls, state_str):
return cls.POST_UP
elif state_str == 'pre-down':
return cls.PRE_DOWN
+ elif state_str == 'down':
+ return cls.DOWN
elif state_str == 'post-down':
return cls.POST_DOWN
-
+ elif state_str == 'query-checkcurr':
+ return cls.QUERY_CHECKCURR
+ elif state_str == 'query-running':
+ return cls.QUERY_RUNNING
+
+class ifaceJsonEncoder(json.JSONEncoder):
+ def default(self, o):
+ retconfig = {}
+ if o.config:
+ for k, v in o.config.items():
+ if len(v) == 1:
+ retconfig[k] = v[0]
+ else:
+ retconfig[k] = v
+
+ return OrderedDict({'name' : o.name,
+ 'addr_method' : o.addr_method,
+ 'addr_family' : o.addr_family,
+ 'auto' : o.auto,
+ 'config' : retconfig})
class iface():
- """ config flags """
- AUTO = 0x1
- HOT_PLUG = 0x2
+ """ flags """
+ # flag to indicate that the object was created from pickled state
+ PICKLED = 0x1
+
+ version = '0.1'
-
def __init__(self):
self.name = None
self.addr_family = None
self.addr_method = None
self.config = OrderedDict()
- self.children = []
+ self.config_status = {}
self.state = ifaceState.NEW
self.status = ifaceStatus.UNKNOWN
self.flags = 0x0
+ self.priv_flags = 0x0
self.refcnt = 0
- # dependents that are listed as in the
- # config file
- self.dependents = None
- # All dependents (includes dependents that
- # are not listed in the config file)
- self.realdev_dependents = None
+ self.lowerifaces = None
+ self.upperifaces = None
self.auto = False
self.classes = []
self.env = None
- self.config_current = {}
self.raw_lines = []
self.linkstate = None
return self.config
def is_config_present(self):
- if self.config is None:
+ addr_method = self.get_addr_method()
+ if addr_method:
+ if (addr_method.find('dhcp') != -1 or
+ addr_method.find('dhcp6') != -1):
+ return True
+ if not self.config:
return False
-
- return (len(self.config) != 0)
-
- def set_config_current(self, config_current):
- self.config_current = config_current
-
- def get_config_current(self):
- return self.config_current
+ else:
+ return True
def get_auto(self):
return self.auto
def belongs_to_class(self, intfclass):
if intfclass in self.classes:
return True
-
return False
- def add_child(self, child_iface_obj):
- self.children.append(child_iface_obj)
+ def set_priv_flags(self, priv_flags):
+ self.priv_flags = priv_flags
+
+ def get_priv_flags(self):
+ return self.priv_flags
def get_state(self):
return self.state
def set_status(self, status):
self.status = status
+ def set_state_n_status(self, state, status):
+ self.state = state
+ self.status = status
+
def state_str_to_hex(self, state_str):
return self.state_str_map.get(state_str)
def clear_flag(self, flag):
self.flags &= ~flag
- def set_dependents(self, dlist):
- self.dependents = dlist
+ def set_lowerifaces(self, dlist):
+ self.lowerifaces = dlist
+
+ def get_lowerifaces(self):
+ return self.lowerifaces
- def get_dependents(self):
- return self.dependents
+ def set_upperifaces(self, dlist):
+ self.upperifaces = dlist
- def set_realdev_dependents(self, dlist):
- self.realdev_dependents = dlist
+ def add_to_upperifaces(self, upperifacename):
+ if self.upperifaces:
+ if upperifacename not in self.upperifaces:
+ self.upperifaces.append(upperifacename)
+ else:
+ self.upperifaces = [upperifacename]
- def get_realdev_dependents(self):
- return self.realdev_dependents
+ def get_upperifaces(self):
+ return self.upperifaces
def set_linkstate(self, l):
self.linkstate = l
def get_attr_value_first(self, attr_name):
config = self.get_config()
-
attr_value_list = config.get(attr_name)
- if attr_value_list is not None:
+ if attr_value_list:
return attr_value_list[0]
-
return None
def get_attr_value_n(self, attr_name, attr_index):
config = self.get_config()
attr_value_list = config.get(attr_name)
- if attr_value_list is not None:
+ if attr_value_list:
try:
return attr_value_list[attr_index]
except:
return None
-
return None
def get_env(self):
- if self.env is None or len(self.env) == 0:
+ if not self.env:
self.generate_env()
return self.env
attr_env_name = 'IF_%s' %attr.upper()
env[attr_env_name] = attr_value[0]
- if len(env) > 0:
+ if env:
self.set_env(env)
def update_config(self, attr_name, attr_value):
- if self.config.get(attr_name) is None:
+ if not self.config.get(attr_name):
self.config[attr_name] = [attr_value]
else:
self.config[attr_name].append(attr_value)
self.config.update(attrdict)
def update_config_with_status(self, attr_name, attr_value, attr_status=0):
- if attr_value is None:
+ if not attr_value:
attr_value = ''
- if attr_status != 0:
- self.set_status(ifaceStatus.ERROR)
- else:
- if self.get_status() != ifaceStatus.ERROR:
- self.set_status(ifaceStatus.SUCCESS)
- if self.config.get(attr_name) is not None:
+ if self.config.get(attr_name):
self.config[attr_name].append(attr_value)
+ self.config_status[attr_name].append(attr_status)
else:
self.config[attr_name] = [attr_value]
+ self.config_status[attr_name] = [attr_status]
+
+ # set global iface state
+ if attr_status:
+ self.set_status(ifaceStatus.ERROR)
+ elif self.get_status() != ifaceStatus.ERROR:
+ # Not already error, mark success
+ self.set_status(ifaceStatus.SUCCESS)
+
+ def get_config_attr_status(self, attr_name, idx=0):
+ self.config_status.get(attr_name, [])[idx]
+
+ def get_config_attr_status_str(self, attr_name, idx=0):
+ ret = self.config_status.get(attr_name, [])[idx]
+ if ret:
+ return crossmark
+ else:
+ return tickmark
+
+ def is_different(self, dstiface):
+ if self.name != dstiface.name: return True
+ if self.addr_family != dstiface.addr_family: return True
+ if self.addr_method != dstiface.addr_method: return True
+ if self.auto != dstiface.auto: return True
+ if self.classes != dstiface.classes: return True
+
+ if any(True for k in self.config if k not in dstiface.config):
+ return True
+
+ if any(True for k,v in self.config.items()
+ if v != dstiface.config.get(k)): return True
- """ XXX: If status needs to be encoded in the query string
- if attr_status == 0:
- self.set_status(attr
- attr_status_str = ''
- elif attr_status == 0:
- attr_status_str = ' (success)'
- elif attr_status != 0:
- attr_status_str = ' (error)'
- self.config[attr_name] = attr_value + attr_status_str """
+ return False
+ def __getstate__(self):
+ odict = self.__dict__.copy()
+ del odict['state']
+ del odict['status']
+ del odict['lowerifaces']
+ del odict['upperifaces']
+ del odict['refcnt']
+ del odict['config_status']
+ del odict['flags']
+ del odict['priv_flags']
+ del odict['raw_lines']
+ del odict['linkstate']
+ del odict['env']
+ return odict
+
+ def __setstate__(self, dict):
+ self.__dict__.update(dict)
+ self.config_status = {}
+ self.state = ifaceState.NEW
+ self.status = ifaceStatus.UNKNOWN
+ self.refcnt = 0
+ self.flags = 0
+ self.lowerifaces = None
+ self.upperifaces = None
+ self.linkstate = None
+ self.env = None
+ self.priv_flags = 0
+ self.raw_lines = []
+ self.flags |= self.PICKLED
+
def dump_raw(self, logger):
indent = ' '
print (self.raw_lines[0])
logger.info(self.get_name() + ' : {')
logger.info(indent + 'family: %s' %self.get_addr_family())
logger.info(indent + 'method: %s' %self.get_addr_method())
+ logger.info(indent + 'flags: %x' %self.flags)
logger.info(indent + 'state: %s'
%ifaceState.to_str(self.get_state()))
logger.info(indent + 'status: %s'
%ifaceStatus.to_str(self.get_status()))
logger.info(indent + 'refcnt: %d' %self.get_refcnt())
- d = self.get_dependents()
- if d is not None:
- logger.info(indent + 'dependents: %s' %str(d))
+ d = self.get_lowerifaces()
+ if d:
+ logger.info(indent + 'lowerdevs: %s' %str(d))
else:
- logger.info(indent + 'dependents: None')
-
- logger.info(indent + 'realdev dependents: %s'
- %str(self.get_realdev_dependents()))
+ logger.info(indent + 'lowerdevs: None')
logger.info(indent + 'config: ')
config = self.get_config()
- if config is not None:
+ if config:
logger.info(indent + indent + str(config))
logger.info('}')
- def dump_pretty(self, logger):
+ def dump_pretty(self, with_status=False):
indent = '\t'
outbuf = ''
if self.get_auto():
outbuf += 'auto %s\n' %self.get_name()
outbuf += 'iface %s' %self.get_name()
- if self.get_addr_family() is not None:
+ if self.get_addr_family():
outbuf += ' %s' %self.get_addr_family()
-
- if self.get_addr_method() is not None:
+ if self.get_addr_method():
outbuf += ' %s' %self.get_addr_method()
-
outbuf += '\n'
-
config = self.get_config()
- if config is not None:
+ if config:
for cname, cvaluelist in config.items():
+ idx = 0
for cv in cvaluelist:
- outbuf += indent + '%s' %cname + ' %s\n' %cv
-
- #outbuf += ('%s' %indent + '%s' %self.get_state_str() +
- # ' %s' %self.get_status_str())
+ if with_status:
+ outbuf += indent + '%s %s %s\n' %(cname, cv,
+ self.get_config_attr_status_str(cname, idx))
+ else:
+ outbuf += indent + '%s %s\n' %(cname, cv)
+ idx += 1
print outbuf
- def dump_json(self, logger):
- json.dumps(self)
+ def dump_json(self, with_status=False):
+ print json.dumps(self, cls=ifaceJsonEncoder, indent=4)