2013-11-04 06:06:11 -08:00
|
|
|
#!/usr/bin/python
|
2013-11-13 16:07:15 -08:00
|
|
|
#
|
|
|
|
# Copyright 2013. Cumulus Networks, Inc.
|
|
|
|
# Author: Roopa Prabhu, roopa@cumulusnetworks.com
|
|
|
|
#
|
|
|
|
# iface --
|
|
|
|
# interface object
|
|
|
|
#
|
2014-01-17 23:10:12 -08:00
|
|
|
from collections import OrderedDict
|
2014-02-08 09:05:32 -08:00
|
|
|
#from json import *
|
2013-11-30 23:52:30 -08:00
|
|
|
import json
|
2014-02-08 09:05:32 -08:00
|
|
|
import logging
|
2013-11-04 06:06:11 -08:00
|
|
|
|
2014-02-08 09:05:32 -08:00
|
|
|
tickmark = ' (' + u'\u2713'.encode('utf8') + ')'
|
|
|
|
crossmark = ' (' + u'\u2717'.encode('utf8') + ')'
|
2013-11-04 06:06:11 -08:00
|
|
|
|
2014-02-08 09:05:32 -08:00
|
|
|
class ifaceFlags():
|
2013-11-04 06:06:11 -08:00
|
|
|
NONE = 0x1
|
|
|
|
FOLLOW_DEPENDENTS = 0x2
|
|
|
|
|
|
|
|
class ifaceStatus():
|
|
|
|
"""iface status """
|
|
|
|
UNKNOWN = 0x1
|
|
|
|
SUCCESS = 0x2
|
|
|
|
ERROR = 0x3
|
2013-11-13 23:00:02 -08:00
|
|
|
NOTFOUND = 0x4
|
2013-11-04 06:06:11 -08:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def to_str(cls, state):
|
|
|
|
if state == cls.UNKNOWN:
|
|
|
|
return 'unknown'
|
|
|
|
elif state == cls.SUCCESS:
|
|
|
|
return 'success'
|
|
|
|
elif state == cls.ERROR:
|
|
|
|
return 'error'
|
2014-01-16 06:46:17 -08:00
|
|
|
elif state == cls.NOTFOUND:
|
2014-02-18 22:25:48 -08:00
|
|
|
return 'notfound'
|
2013-11-04 06:06:11 -08:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def from_str(cls, state_str):
|
|
|
|
if state_str == 'unknown':
|
|
|
|
return cls.UNKNOWN
|
|
|
|
elif state_str == 'success':
|
|
|
|
return cls.SUCCESS
|
|
|
|
elif state_str == 'error':
|
|
|
|
return cls.ERROR
|
|
|
|
|
|
|
|
class ifaceState():
|
|
|
|
|
|
|
|
""" iface states """
|
|
|
|
UNKNOWN = 0x1
|
|
|
|
NEW = 0x2
|
|
|
|
PRE_UP = 0x3
|
|
|
|
UP = 0x4
|
|
|
|
POST_UP = 0x5
|
|
|
|
PRE_DOWN = 0x6
|
|
|
|
DOWN = 0x7
|
|
|
|
POST_DOWN = 0x8
|
|
|
|
|
2014-02-08 09:05:32 -08:00
|
|
|
# Pseudo states
|
|
|
|
QUERY_CHECKCURR = 0x9
|
|
|
|
QUERY_RUNNING = 0xa
|
|
|
|
|
2013-11-04 06:06:11 -08:00
|
|
|
@classmethod
|
|
|
|
def to_str(cls, state):
|
|
|
|
if state == cls.UNKNOWN:
|
|
|
|
return 'unknown'
|
|
|
|
elif state == cls.NEW:
|
|
|
|
return 'new'
|
|
|
|
elif state == cls.PRE_UP:
|
|
|
|
return 'pre-up'
|
|
|
|
elif state == cls.UP:
|
|
|
|
return 'up'
|
|
|
|
elif state == cls.POST_UP:
|
|
|
|
return 'post-up'
|
|
|
|
elif state == cls.PRE_DOWN:
|
|
|
|
return 'pre-down'
|
2014-02-08 09:05:32 -08:00
|
|
|
elif state == cls.DOWN:
|
|
|
|
return 'down'
|
2013-11-04 06:06:11 -08:00
|
|
|
elif state == cls.POST_DOWN:
|
|
|
|
return 'post-down'
|
2014-02-08 09:05:32 -08:00
|
|
|
elif state == cls.QUERY_CHECKCURR:
|
|
|
|
return 'query-checkcurr'
|
|
|
|
elif state == cls.QUERY_RUNNING:
|
|
|
|
return 'query-running'
|
2013-11-04 06:06:11 -08:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def from_str(cls, state_str):
|
|
|
|
if state_str == 'unknown':
|
|
|
|
return cls.UNKNOWN
|
|
|
|
elif state_str == 'new':
|
|
|
|
return cls.NEW
|
|
|
|
elif state_str == 'pre-up':
|
|
|
|
return cls.PRE_UP
|
|
|
|
elif state_str == 'up':
|
|
|
|
return cls.UP
|
|
|
|
elif state_str == 'post-up':
|
|
|
|
return cls.POST_UP
|
|
|
|
elif state_str == 'pre-down':
|
|
|
|
return cls.PRE_DOWN
|
2014-02-08 09:05:32 -08:00
|
|
|
elif state_str == 'down':
|
|
|
|
return cls.DOWN
|
2013-11-04 06:06:11 -08:00
|
|
|
elif state_str == 'post-down':
|
|
|
|
return cls.POST_DOWN
|
2014-02-08 09:05:32 -08:00
|
|
|
elif state_str == 'query-checkcurr':
|
|
|
|
return cls.QUERY_CHECKCURR
|
|
|
|
elif state_str == 'query-running':
|
|
|
|
return cls.QUERY_RUNNING
|
2013-11-04 06:06:11 -08:00
|
|
|
|
2014-02-08 09:05:32 -08:00
|
|
|
class ifaceJsonEncoder(json.JSONEncoder):
|
|
|
|
def default(self, o):
|
2014-02-15 21:39:13 -08:00
|
|
|
retconfig = {}
|
|
|
|
if o.config:
|
|
|
|
for k, v in o.config.items():
|
|
|
|
if len(v) == 1:
|
|
|
|
retconfig[k] = v[0]
|
|
|
|
else:
|
|
|
|
retconfig[k] = v
|
|
|
|
|
2014-02-11 06:00:07 -08:00
|
|
|
return OrderedDict({'name' : o.name,
|
|
|
|
'addr_method' : o.addr_method,
|
|
|
|
'addr_family' : o.addr_family,
|
|
|
|
'auto' : o.auto,
|
2014-02-15 21:39:13 -08:00
|
|
|
'config' : retconfig})
|
2014-02-08 09:05:32 -08:00
|
|
|
|
2013-11-04 06:06:11 -08:00
|
|
|
class iface():
|
2014-02-24 11:07:59 -08:00
|
|
|
""" flags """
|
|
|
|
# flag to indicate that the object was created from pickled state
|
|
|
|
PICKLED = 0x1
|
2013-11-04 06:06:11 -08:00
|
|
|
|
2014-01-30 22:36:41 -08:00
|
|
|
version = '0.1'
|
|
|
|
|
2013-11-04 06:06:11 -08:00
|
|
|
def __init__(self):
|
|
|
|
self.name = None
|
|
|
|
self.addr_family = None
|
|
|
|
self.addr_method = None
|
2014-01-17 23:10:12 -08:00
|
|
|
self.config = OrderedDict()
|
2014-02-18 22:25:48 -08:00
|
|
|
self.config_status = {}
|
2013-11-04 06:06:11 -08:00
|
|
|
self.state = ifaceState.NEW
|
|
|
|
self.status = ifaceStatus.UNKNOWN
|
|
|
|
self.flags = 0x0
|
2014-01-30 22:36:41 -08:00
|
|
|
self.priv_flags = 0x0
|
2013-11-04 06:06:11 -08:00
|
|
|
self.refcnt = 0
|
2014-02-12 22:29:41 -08:00
|
|
|
self.lowerifaces = None
|
|
|
|
self.upperifaces = None
|
2013-11-04 06:06:11 -08:00
|
|
|
self.auto = False
|
|
|
|
self.classes = []
|
|
|
|
self.env = None
|
|
|
|
self.raw_lines = []
|
|
|
|
self.linkstate = None
|
|
|
|
|
|
|
|
def inc_refcnt(self):
|
|
|
|
self.refcnt += 1
|
|
|
|
|
|
|
|
def dec_refcnt(self):
|
|
|
|
self.refcnt -= 1
|
|
|
|
|
|
|
|
def get_refcnt(self):
|
|
|
|
return self.refcnt
|
|
|
|
|
|
|
|
def set_refcnt(self, cnt):
|
|
|
|
self.refcnt = 0
|
|
|
|
|
|
|
|
def set_name(self, name):
|
|
|
|
self.name = name
|
|
|
|
|
|
|
|
def get_name(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
def set_addr_family(self, family):
|
|
|
|
self.addr_family = family
|
|
|
|
|
|
|
|
def get_addr_family(self):
|
|
|
|
return self.addr_family
|
|
|
|
|
|
|
|
def set_addr_method(self, method):
|
|
|
|
self.addr_method = method
|
|
|
|
|
|
|
|
def get_addr_method(self):
|
|
|
|
return self.addr_method
|
|
|
|
|
|
|
|
def set_config(self, config_dict):
|
|
|
|
self.config = config_dict
|
|
|
|
|
|
|
|
def get_config(self):
|
|
|
|
return self.config
|
|
|
|
|
2014-01-17 23:10:12 -08:00
|
|
|
def is_config_present(self):
|
2014-01-30 22:36:41 -08:00
|
|
|
addr_method = self.get_addr_method()
|
2014-02-19 21:30:55 -08:00
|
|
|
if addr_method:
|
2014-01-30 22:36:41 -08:00
|
|
|
if (addr_method.find('dhcp') != -1 or
|
|
|
|
addr_method.find('dhcp6') != -1):
|
|
|
|
return True
|
2014-02-19 21:30:55 -08:00
|
|
|
if not self.config:
|
2014-01-17 23:10:12 -08:00
|
|
|
return False
|
2014-02-19 21:30:55 -08:00
|
|
|
else:
|
|
|
|
return True
|
2014-01-17 23:10:12 -08:00
|
|
|
|
2013-11-04 06:06:11 -08:00
|
|
|
def get_auto(self):
|
|
|
|
return self.auto
|
|
|
|
|
|
|
|
def set_auto(self):
|
|
|
|
self.auto = True
|
|
|
|
|
|
|
|
def reset_auto(self):
|
|
|
|
self.auto = False
|
|
|
|
|
|
|
|
def get_classes(self):
|
|
|
|
return self.classes
|
|
|
|
|
2013-11-13 16:07:15 -08:00
|
|
|
def set_classes(self, classes):
|
|
|
|
""" sets interface class list to the one passed as arg """
|
|
|
|
self.classes = classes
|
|
|
|
|
|
|
|
def set_class(self, classname):
|
|
|
|
""" Appends a class to the list """
|
2013-11-04 06:06:11 -08:00
|
|
|
self.classes.append(classname)
|
|
|
|
|
|
|
|
def belongs_to_class(self, intfclass):
|
|
|
|
if intfclass in self.classes:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2014-02-18 22:25:48 -08:00
|
|
|
def set_priv_flags(self, priv_flags):
|
|
|
|
self.priv_flags = priv_flags
|
|
|
|
|
|
|
|
def get_priv_flags(self):
|
|
|
|
return self.priv_flags
|
|
|
|
|
2013-11-04 06:06:11 -08:00
|
|
|
def get_state(self):
|
|
|
|
return self.state
|
|
|
|
|
|
|
|
def get_state_str(self):
|
|
|
|
return ifaceState.to_str(self.state)
|
|
|
|
|
|
|
|
def set_state(self, state):
|
|
|
|
self.state = state
|
|
|
|
|
|
|
|
def get_status(self):
|
|
|
|
return self.status
|
|
|
|
|
|
|
|
def get_status_str(self):
|
|
|
|
return ifaceStatus.to_str(self.status)
|
|
|
|
|
|
|
|
def set_status(self, status):
|
|
|
|
self.status = status
|
|
|
|
|
2014-02-24 11:07:59 -08:00
|
|
|
def set_state_n_status(self, state, status):
|
|
|
|
self.state = state
|
|
|
|
self.status = status
|
|
|
|
|
2013-11-04 06:06:11 -08:00
|
|
|
def state_str_to_hex(self, state_str):
|
|
|
|
return self.state_str_map.get(state_str)
|
|
|
|
|
|
|
|
def set_flag(self, flag):
|
|
|
|
self.flags |= flag
|
|
|
|
|
|
|
|
def clear_flag(self, flag):
|
|
|
|
self.flags &= ~flag
|
|
|
|
|
2014-02-12 22:29:41 -08:00
|
|
|
def set_lowerifaces(self, dlist):
|
|
|
|
self.lowerifaces = dlist
|
2013-11-04 06:06:11 -08:00
|
|
|
|
2014-02-12 22:29:41 -08:00
|
|
|
def get_lowerifaces(self):
|
|
|
|
return self.lowerifaces
|
2013-11-04 06:06:11 -08:00
|
|
|
|
2014-02-12 22:29:41 -08:00
|
|
|
def set_upperifaces(self, dlist):
|
|
|
|
self.upperifaces = dlist
|
2014-01-16 06:46:17 -08:00
|
|
|
|
2014-02-12 22:29:41 -08:00
|
|
|
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_upperifaces(self):
|
|
|
|
return self.upperifaces
|
2014-01-16 06:46:17 -08:00
|
|
|
|
2013-11-04 06:06:11 -08:00
|
|
|
def set_linkstate(self, l):
|
|
|
|
self.linkstate = l
|
|
|
|
|
|
|
|
def get_linkstate(self):
|
|
|
|
return self.linkstate
|
|
|
|
|
|
|
|
def get_attr_value(self, attr_name):
|
|
|
|
config = self.get_config()
|
|
|
|
|
|
|
|
return config.get(attr_name)
|
|
|
|
|
|
|
|
def get_attr_value_first(self, attr_name):
|
|
|
|
config = self.get_config()
|
|
|
|
attr_value_list = config.get(attr_name)
|
2014-02-19 21:30:55 -08:00
|
|
|
if attr_value_list:
|
2013-11-04 06:06:11 -08:00
|
|
|
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)
|
2014-02-19 21:30:55 -08:00
|
|
|
if attr_value_list:
|
2013-11-04 06:06:11 -08:00
|
|
|
try:
|
|
|
|
return attr_value_list[attr_index]
|
|
|
|
except:
|
|
|
|
return None
|
|
|
|
return None
|
|
|
|
|
|
|
|
def get_env(self):
|
2014-02-19 21:30:55 -08:00
|
|
|
if not self.env:
|
2013-11-04 06:06:11 -08:00
|
|
|
self.generate_env()
|
|
|
|
return self.env
|
|
|
|
|
|
|
|
def set_env(self, env):
|
|
|
|
self.env = env
|
|
|
|
|
|
|
|
def generate_env(self):
|
|
|
|
env = {}
|
|
|
|
config = self.get_config()
|
|
|
|
env['IFACE'] = self.get_name()
|
|
|
|
for attr, attr_value in config.items():
|
|
|
|
attr_env_name = 'IF_%s' %attr.upper()
|
|
|
|
env[attr_env_name] = attr_value[0]
|
|
|
|
|
2014-02-19 21:30:55 -08:00
|
|
|
if env:
|
2013-11-04 06:06:11 -08:00
|
|
|
self.set_env(env)
|
|
|
|
|
2014-01-16 06:46:17 -08:00
|
|
|
def update_config(self, attr_name, attr_value):
|
2014-02-19 21:30:55 -08:00
|
|
|
if not self.config.get(attr_name):
|
2014-01-16 06:46:17 -08:00
|
|
|
self.config[attr_name] = [attr_value]
|
|
|
|
else:
|
|
|
|
self.config[attr_name].append(attr_value)
|
|
|
|
|
|
|
|
def update_config_dict(self, attrdict):
|
|
|
|
self.config.update(attrdict)
|
|
|
|
|
|
|
|
def update_config_with_status(self, attr_name, attr_value, attr_status=0):
|
2014-02-18 22:25:48 -08:00
|
|
|
if not attr_value:
|
2013-11-04 06:06:11 -08:00
|
|
|
attr_value = ''
|
2014-02-18 22:25:48 -08:00
|
|
|
|
|
|
|
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
|
2014-02-08 09:05:32 -08:00
|
|
|
if attr_status:
|
2013-11-10 22:35:40 -08:00
|
|
|
self.set_status(ifaceStatus.ERROR)
|
2014-02-18 22:25:48 -08:00
|
|
|
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
|
2013-11-10 22:35:40 -08:00
|
|
|
else:
|
2014-02-18 22:25:48 -08:00
|
|
|
return tickmark
|
2013-11-04 06:06:11 -08:00
|
|
|
|
2014-01-30 22:36:41 -08:00
|
|
|
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
|
|
|
|
|
|
|
|
return False
|
2014-02-08 09:05:32 -08:00
|
|
|
|
|
|
|
def __getstate__(self):
|
|
|
|
odict = self.__dict__.copy()
|
|
|
|
del odict['state']
|
|
|
|
del odict['status']
|
2014-02-12 22:29:41 -08:00
|
|
|
del odict['lowerifaces']
|
2014-02-08 09:05:32 -08:00
|
|
|
del odict['refcnt']
|
2014-03-06 06:41:28 -08:00
|
|
|
del odict['config_status']
|
|
|
|
del odict['flags']
|
|
|
|
del odict['priv_flags']
|
|
|
|
del odict['raw_lines']
|
|
|
|
del odict['linkstate']
|
|
|
|
del odict['env']
|
2014-02-08 09:05:32 -08:00
|
|
|
return odict
|
|
|
|
|
|
|
|
def __setstate__(self, dict):
|
|
|
|
self.__dict__.update(dict)
|
2014-03-06 06:41:28 -08:00
|
|
|
self.config_status = {}
|
2014-02-08 09:05:32 -08:00
|
|
|
self.state = ifaceState.NEW
|
|
|
|
self.status = ifaceStatus.UNKNOWN
|
|
|
|
self.refcnt = 0
|
2014-03-06 06:41:28 -08:00
|
|
|
self.flags = 0
|
2014-02-12 22:29:41 -08:00
|
|
|
self.lowerifaces = None
|
2014-02-08 09:05:32 -08:00
|
|
|
self.linkstate = None
|
2014-03-06 06:41:28 -08:00
|
|
|
self.env = None
|
|
|
|
self.priv_flags = 0
|
|
|
|
self.raw_lines = []
|
2014-02-24 11:07:59 -08:00
|
|
|
self.flags |= self.PICKLED
|
2014-01-30 22:36:41 -08:00
|
|
|
|
2013-11-04 06:06:11 -08:00
|
|
|
def dump_raw(self, logger):
|
|
|
|
indent = ' '
|
|
|
|
print (self.raw_lines[0])
|
|
|
|
for i in range(1, len(self.raw_lines)):
|
|
|
|
print (indent + self.raw_lines[i])
|
|
|
|
|
|
|
|
def dump(self, logger):
|
|
|
|
indent = '\t'
|
|
|
|
logger.info(self.get_name() + ' : {')
|
|
|
|
logger.info(indent + 'family: %s' %self.get_addr_family())
|
|
|
|
logger.info(indent + 'method: %s' %self.get_addr_method())
|
2014-02-24 11:07:59 -08:00
|
|
|
logger.info(indent + 'flags: %x' %self.flags)
|
2013-11-04 06:06:11 -08:00
|
|
|
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())
|
2014-02-24 11:07:59 -08:00
|
|
|
d = self.get_lowerifaces()
|
2014-02-19 21:30:55 -08:00
|
|
|
if d:
|
2014-02-12 22:29:41 -08:00
|
|
|
logger.info(indent + 'lowerdevs: %s' %str(d))
|
2013-11-04 06:06:11 -08:00
|
|
|
else:
|
2014-02-12 22:29:41 -08:00
|
|
|
logger.info(indent + 'lowerdevs: None')
|
2014-01-16 06:46:17 -08:00
|
|
|
|
2013-11-04 06:06:11 -08:00
|
|
|
logger.info(indent + 'config: ')
|
|
|
|
config = self.get_config()
|
2014-02-19 21:30:55 -08:00
|
|
|
if config:
|
2013-11-04 06:06:11 -08:00
|
|
|
logger.info(indent + indent + str(config))
|
|
|
|
logger.info('}')
|
|
|
|
|
2014-02-18 22:25:48 -08:00
|
|
|
def dump_pretty(self, with_status=False):
|
2013-11-04 06:06:11 -08:00
|
|
|
indent = '\t'
|
2014-01-17 23:10:12 -08:00
|
|
|
outbuf = ''
|
|
|
|
if self.get_auto():
|
|
|
|
outbuf += 'auto %s\n' %self.get_name()
|
|
|
|
outbuf += 'iface %s' %self.get_name()
|
2014-02-19 21:30:55 -08:00
|
|
|
if self.get_addr_family():
|
2013-11-04 06:06:11 -08:00
|
|
|
outbuf += ' %s' %self.get_addr_family()
|
2014-02-19 21:30:55 -08:00
|
|
|
if self.get_addr_method():
|
2013-11-04 06:06:11 -08:00
|
|
|
outbuf += ' %s' %self.get_addr_method()
|
|
|
|
outbuf += '\n'
|
|
|
|
config = self.get_config()
|
2014-02-19 21:30:55 -08:00
|
|
|
if config:
|
2013-11-10 22:35:40 -08:00
|
|
|
for cname, cvaluelist in config.items():
|
2014-02-18 22:25:48 -08:00
|
|
|
idx = 0
|
2013-11-10 22:35:40 -08:00
|
|
|
for cv in cvaluelist:
|
2014-02-18 22:25:48 -08:00
|
|
|
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
|
2013-11-04 06:06:11 -08:00
|
|
|
|
|
|
|
print outbuf
|
2013-11-30 23:52:30 -08:00
|
|
|
|
2014-02-18 22:25:48 -08:00
|
|
|
def dump_json(self, with_status=False):
|
2014-02-11 06:00:07 -08:00
|
|
|
print json.dumps(self, cls=ifaceJsonEncoder, indent=4)
|