153 lines
5.4 KiB
Python
153 lines
5.4 KiB
Python
import copy
|
|
|
|
from six.moves.urllib import request
|
|
import xmltodict
|
|
|
|
from vapor.settings import logger
|
|
|
|
|
|
__all__ = ['ContrailVRouterAgentClient']
|
|
|
|
|
|
class ClientContrailVRouterAgentBase(object):
|
|
def __init__(self, agent_ip, agent_port):
|
|
self.ip = agent_ip
|
|
self.port = agent_port
|
|
|
|
def get_snh_dict_data(self, data):
|
|
key = next(iter(data.keys()))
|
|
if key.startswith(r'__'):
|
|
data = data[key]
|
|
data = self.del_unused_key(data)
|
|
return {k: self.get_data(v) for k, v in data.items()}
|
|
|
|
def get_resource(self, path):
|
|
url = 'http://%s:%s/%s' % (self.ip, self.port, path)
|
|
try:
|
|
response = request.urlopen(url)
|
|
xmldata = response.read()
|
|
except Exception as e:
|
|
logger.error('get_xml exception: {} url: {}'.format(e, url))
|
|
raise
|
|
xml_dict = xmltodict.parse(xmldata)
|
|
return xml_dict
|
|
|
|
@staticmethod
|
|
def del_unused_key(data):
|
|
key_list = ['@type', '@identifier', '@size', 'more',
|
|
'Pagination', 'OvsdbPageResp', 'next_batch']
|
|
return {k: v for (k, v) in data.items() if k not in key_list}
|
|
|
|
def get_data(self, data):
|
|
if isinstance(data, list):
|
|
data_list = []
|
|
for item in data:
|
|
data_dict = self.get_data(item)
|
|
data_list.append(data_dict)
|
|
return_data = data_list
|
|
else:
|
|
if '@type' in data:
|
|
if data['@type'] == 'sandesh':
|
|
data = self.del_unused_key(data)
|
|
return_data = {k: self.get_data(v)
|
|
for k, v in data.items()}
|
|
elif data['@type'] == 'list':
|
|
data = self.del_unused_key(data)
|
|
key = next(iter(data.keys()))
|
|
data = data[key]
|
|
return_data = self.get_data(data)
|
|
elif data['@type'] == 'struct':
|
|
is_list = '@size' in data
|
|
data = self.del_unused_key(data)
|
|
if len(data) == 0:
|
|
return ''
|
|
value = next(iter(data.values()))
|
|
if is_list and not (isinstance(value, list)):
|
|
value = [value]
|
|
return_data = self.get_data(value)
|
|
elif data['@type'] in ['i64', 'i32', 'i16', 'u64', 'u32',
|
|
'u16', 'double', 'string', 'bool']:
|
|
if '#text' in data:
|
|
return_data = data['#text']
|
|
else:
|
|
return_data = ''
|
|
elif 'element' in data:
|
|
return_data = data['#text']
|
|
else:
|
|
data = self.del_unused_key(data)
|
|
return_data = {k: self.get_data(v) for k, v in data.items()}
|
|
return return_data
|
|
|
|
def find_ifmap_list(self, data):
|
|
except_keys = ['@type', '@identifier', '@size',
|
|
'table_size', 'next_batch', 'more']
|
|
for k in data:
|
|
if not isinstance(data[k], list):
|
|
if k not in except_keys:
|
|
return self.find_ifmap_list(data[k])
|
|
else:
|
|
temp_list = data[k]
|
|
return copy.copy(temp_list)
|
|
|
|
def merge_ifmap_list(self, data, next_list):
|
|
except_keys = ['@type', '@identifier', '@size', 'table_size',
|
|
'next_batch', 'more']
|
|
for k in data:
|
|
if not isinstance(data[k], list):
|
|
if k not in except_keys:
|
|
return self.merge_ifmap_list(data[k], next_list)
|
|
else:
|
|
data[k] += next_list
|
|
return data
|
|
|
|
def get_snhdict(self, path):
|
|
data = self.get_resource(path)
|
|
# Check all data link
|
|
all_path = None
|
|
try:
|
|
top_key = next(iter(data.keys()))
|
|
url = data[top_key]['Pagination']['req']['PageReqData']['all']['#text'] # noqa
|
|
all_path = 'Snh_PageReq?x=%s' % url
|
|
except KeyError:
|
|
pass
|
|
try:
|
|
top_key = next(iter(data.keys()))
|
|
url = data[top_key]['OvsdbPageResp']['req']['OvsdbPageRespData']['all']['#text'] # noqa
|
|
all_path = 'Snh_OvsdbPageReq?x=%s' % url
|
|
except KeyError:
|
|
pass
|
|
if all_path:
|
|
data = self.get_resource(all_path)
|
|
# Check pagination
|
|
key = next(iter(data.keys()))
|
|
while 'next_batch' in data[key]:
|
|
old_data = data.copy()
|
|
path1 = data[key]['next_batch']['@link']
|
|
path2 = data[key]['next_batch']['#text']
|
|
path = 'Snh_%s?x=%s' % (path1, path2)
|
|
data = self.get_resource(path)
|
|
old_list = self.find_ifmap_list(old_data)
|
|
data = self.merge_ifmap_list(data, old_list)
|
|
return data
|
|
|
|
def get_path_to_dict(self, path):
|
|
# Return path directory info by dict
|
|
rsp = self.get_snhdict(path)
|
|
snh_data = self.get_snh_dict_data(rsp)
|
|
return snh_data
|
|
|
|
|
|
class ContrailVRouterAgentClient(ClientContrailVRouterAgentBase):
|
|
|
|
def get_itfs(self):
|
|
data = self.get_path_to_dict('Snh_ItfReq')
|
|
return data
|
|
|
|
def get_itf_by_name(self, interface_name):
|
|
data = self.get_path_to_dict('Snh_ItfReq?x={}'.format(interface_name))
|
|
return data
|
|
|
|
def get_sg_list(self):
|
|
data = self.get_path_to_dict('Snh_SgListReq')
|
|
return data
|