Merge "Add test_security_group_on_vrouter"
This commit is contained in:
commit
2b3aa395b5
|
@ -28,12 +28,17 @@ def client_contrail_analytics(session):
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def client_contrail_vrouter_agent(contrail_vrouter_agent_endpoint):
|
def client_contrail_vrouter_agents(contrail_vrouter_agent_endpoints):
|
||||||
LOGGER.debug('VRouter endpoint: {0}'.format(
|
endpoints = contrail_vrouter_agent_endpoints
|
||||||
contrail_vrouter_agent_endpoint))
|
port = endpoints['port']
|
||||||
return clients.ContrailVRouterAgentClient(
|
_clients = {}
|
||||||
agent_ip=contrail_vrouter_agent_endpoint['ip'],
|
for node in endpoints['nodes']:
|
||||||
agent_port=contrail_vrouter_agent_endpoint['port'])
|
LOGGER.debug('VRouter `{node}` endpoint: {ip}:{port}'.format(
|
||||||
|
node=node['fqdn'], ip=node['ip'], port=port))
|
||||||
|
_clients[node['fqdn']] = clients.ContrailVRouterAgentClient(
|
||||||
|
agent_ip=node['ip'], agent_port=endpoints['port'])
|
||||||
|
|
||||||
|
return _clients
|
||||||
|
|
||||||
|
|
||||||
def get_nodes_fixture(cmd, scope='function'):
|
def get_nodes_fixture(cmd, scope='function'):
|
||||||
|
@ -86,18 +91,53 @@ def contrail_api_endpoint(os_faults_steps):
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='module')
|
@pytest.fixture(scope='module')
|
||||||
def contrail_vrouter_agent_endpoint(contrail_services_http_introspect_ports):
|
def contrail_vrouter_agent_endpoints(contrail_services_http_introspect_ports):
|
||||||
"""Return contrail agent endpoint."""
|
"""Return contrail agent endpoints info.
|
||||||
|
|
||||||
|
Return format:
|
||||||
|
{
|
||||||
|
'port': 8100,
|
||||||
|
'nodes': [
|
||||||
|
{
|
||||||
|
'ip': '1.22.3.4',
|
||||||
|
'fqdn': 'cmp001.mcp.local'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'ip': '1.22.3.5',
|
||||||
|
'fqdn': 'cmp002.mcp.local'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
service_name = 'contrail-vrouter-agent'
|
service_name = 'contrail-vrouter-agent'
|
||||||
ip = contrail_services_http_introspect_ports[service_name]['nodes'][0][
|
return contrail_services_http_introspect_ports[service_name]
|
||||||
'ip']
|
|
||||||
port = contrail_services_http_introspect_ports[service_name]['port']
|
|
||||||
return {'ip': ip, 'port': port}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='module')
|
@pytest.fixture(scope='module')
|
||||||
def contrail_services_http_introspect_ports(os_faults_steps, contrail_nodes):
|
def contrail_services_http_introspect_ports(os_faults_steps, contrail_nodes):
|
||||||
"""Return contrail services ips and ports."""
|
"""Return contrail services ips and ports.
|
||||||
|
|
||||||
|
Return format:
|
||||||
|
{
|
||||||
|
'contrail-vrouter-agent':{
|
||||||
|
'port': 8100,
|
||||||
|
'nodes': [
|
||||||
|
{
|
||||||
|
'ip': '1.22.3.4',
|
||||||
|
'fqdn': 'cmp001.mcp.local'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'ip': '1.22.3.5',
|
||||||
|
'fqdn': 'cmp002.mcp.local'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'contrail-opserver': {...},
|
||||||
|
....
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
default_ports = {
|
default_ports = {
|
||||||
'contrail-config-nodemgr': 8100,
|
'contrail-config-nodemgr': 8100,
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
import six
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
from six.moves.urllib import request
|
||||||
import xmltodict
|
import xmltodict
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
from vapor.settings import logger
|
from vapor.settings import logger
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
from urllib2 import Request, urlopen
|
|
||||||
else:
|
|
||||||
from urllib.request import Request, urlopen
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['ContrailVRouterAgentClient']
|
__all__ = ['ContrailVRouterAgentClient']
|
||||||
|
|
||||||
|
@ -20,21 +15,16 @@ class ClientContrailVRouterAgentBase(object):
|
||||||
self.port = agent_port
|
self.port = agent_port
|
||||||
|
|
||||||
def get_snh_dict_data(self, data):
|
def get_snh_dict_data(self, data):
|
||||||
key = data.keys()
|
key = next(iter(data.keys()))
|
||||||
if key[0].find(r'__') == 0:
|
if key.startswith(r'__'):
|
||||||
data = data[key[0]]
|
data = data[key]
|
||||||
data = self.del_unused_key(data)
|
data = self.del_unused_key(data)
|
||||||
return_dict = {}
|
return {k: self.get_data(v) for k, v in data.items()}
|
||||||
key = data.keys()
|
|
||||||
for i in key:
|
|
||||||
return_dict[i] = self.get_data(data[i])
|
|
||||||
return return_dict
|
|
||||||
|
|
||||||
def get_resource(self, path):
|
def get_resource(self, path):
|
||||||
url = 'http://%s:%s/%s' % (self.ip, self.port, path)
|
url = 'http://%s:%s/%s' % (self.ip, self.port, path)
|
||||||
req = Request(url)
|
|
||||||
try:
|
try:
|
||||||
response = urlopen(req)
|
response = request.urlopen(url)
|
||||||
xmldata = response.read()
|
xmldata = response.read()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error('get_xml exception: {} url: {}'.format(e, url))
|
logger.error('get_xml exception: {} url: {}'.format(e, url))
|
||||||
|
@ -46,38 +36,35 @@ class ClientContrailVRouterAgentBase(object):
|
||||||
def del_unused_key(data):
|
def del_unused_key(data):
|
||||||
key_list = ['@type', '@identifier', '@size', 'more',
|
key_list = ['@type', '@identifier', '@size', 'more',
|
||||||
'Pagination', 'OvsdbPageResp', 'next_batch']
|
'Pagination', 'OvsdbPageResp', 'next_batch']
|
||||||
return OrderedDict({k: v for (k, v) in data.items()
|
return {k: v for (k, v) in data.items() if k not in key_list}
|
||||||
if k not in key_list})
|
|
||||||
|
|
||||||
def get_data(self, data):
|
def get_data(self, data):
|
||||||
if isinstance(data, list):
|
if isinstance(data, list):
|
||||||
data_list = []
|
data_list = []
|
||||||
for i in data:
|
for item in data:
|
||||||
data_dict = self.get_data(i)
|
data_dict = self.get_data(item)
|
||||||
data_list.append(data_dict)
|
data_list.append(data_dict)
|
||||||
return_data = data_list
|
return_data = data_list
|
||||||
else:
|
else:
|
||||||
if '@type' in data:
|
if '@type' in data:
|
||||||
if data['@type'] == 'sandesh':
|
if data['@type'] == 'sandesh':
|
||||||
sandesh_dict = {}
|
|
||||||
data = self.del_unused_key(data)
|
data = self.del_unused_key(data)
|
||||||
key = data.keys()
|
return_data = {k: self.get_data(v)
|
||||||
for i in key:
|
for k, v in data.items()}
|
||||||
sandesh_dict[i] = self.get_data(data[i])
|
|
||||||
return_data = sandesh_dict
|
|
||||||
elif data['@type'] == 'list':
|
elif data['@type'] == 'list':
|
||||||
data = self.del_unused_key(data)
|
data = self.del_unused_key(data)
|
||||||
key = data.keys()
|
key = next(iter(data.keys()))
|
||||||
data = data[key[0]]
|
data = data[key]
|
||||||
return_data = self.get_data(data)
|
return_data = self.get_data(data)
|
||||||
elif data['@type'] == 'struct':
|
elif data['@type'] == 'struct':
|
||||||
|
is_list = '@size' in data
|
||||||
data = self.del_unused_key(data)
|
data = self.del_unused_key(data)
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
return ''
|
return ''
|
||||||
keys = data.keys()
|
value = next(iter(data.values()))
|
||||||
for i in keys:
|
if is_list and not (isinstance(value, list)):
|
||||||
sdata = self.get_data(data[i])
|
value = [value]
|
||||||
return_data = sdata
|
return_data = self.get_data(value)
|
||||||
elif data['@type'] in ['i64', 'i32', 'i16', 'u64', 'u32',
|
elif data['@type'] in ['i64', 'i32', 'i16', 'u64', 'u32',
|
||||||
'u16', 'double', 'string', 'bool']:
|
'u16', 'double', 'string', 'bool']:
|
||||||
if '#text' in data:
|
if '#text' in data:
|
||||||
|
@ -87,11 +74,8 @@ class ClientContrailVRouterAgentBase(object):
|
||||||
elif 'element' in data:
|
elif 'element' in data:
|
||||||
return_data = data['#text']
|
return_data = data['#text']
|
||||||
else:
|
else:
|
||||||
data_dict = {}
|
|
||||||
data = self.del_unused_key(data)
|
data = self.del_unused_key(data)
|
||||||
for i in data:
|
return_data = {k: self.get_data(v) for k, v in data.items()}
|
||||||
data_dict[i] = self.get_data(data[i])
|
|
||||||
return_data = data_dict
|
|
||||||
return return_data
|
return return_data
|
||||||
|
|
||||||
def find_ifmap_list(self, data):
|
def find_ifmap_list(self, data):
|
||||||
|
@ -118,34 +102,32 @@ class ClientContrailVRouterAgentBase(object):
|
||||||
|
|
||||||
def get_snhdict(self, path):
|
def get_snhdict(self, path):
|
||||||
data = self.get_resource(path)
|
data = self.get_resource(path)
|
||||||
all_path = ''
|
# Check all data link
|
||||||
|
all_path = None
|
||||||
try:
|
try:
|
||||||
top_key = data.keys()
|
top_key = next(iter(data.keys()))
|
||||||
url = data[top_key[0]]['Pagination']['req']['PageReqData']['all']['#text'] # noqa
|
url = data[top_key]['Pagination']['req']['PageReqData']['all']['#text'] # noqa
|
||||||
all_path = 'Snh_PageReq?x=%s' % url
|
all_path = 'Snh_PageReq?x=%s' % url
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
top_key = data.keys()
|
top_key = next(iter(data.keys()))
|
||||||
url = data[top_key[0]]['OvsdbPageResp']['req']['OvsdbPageRespData']['all']['#text'] # noqa
|
url = data[top_key]['OvsdbPageResp']['req']['OvsdbPageRespData']['all']['#text'] # noqa
|
||||||
all_path = 'Snh_OvsdbPageReq?x=%s' % url
|
all_path = 'Snh_OvsdbPageReq?x=%s' % url
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
if all_path != '':
|
if all_path:
|
||||||
data = self.get_resource(all_path)
|
data = self.get_resource(all_path)
|
||||||
keys = data.keys()
|
# Check pagination
|
||||||
if 'next_batch' in data[keys[0]]:
|
key = next(iter(data.keys()))
|
||||||
while True:
|
while 'next_batch' in data[key]:
|
||||||
if 'next_batch' in data[keys[0]]:
|
old_data = data.copy()
|
||||||
old_data = data.copy()
|
path1 = data[key]['next_batch']['@link']
|
||||||
path1 = data[keys[0]]['next_batch']['@link']
|
path2 = data[key]['next_batch']['#text']
|
||||||
path2 = data[keys[0]]['next_batch']['#text']
|
path = 'Snh_%s?x=%s' % (path1, path2)
|
||||||
path = 'Snh_%s?x=%s' % (path1, path2)
|
data = self.get_resource(path)
|
||||||
data = self.get_resource(path)
|
old_list = self.find_ifmap_list(old_data)
|
||||||
old_list = self.find_ifmap_list(old_data)
|
data = self.merge_ifmap_list(data, old_list)
|
||||||
self.merge_ifmap_list(data, old_list)
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_path_to_dict(self, path):
|
def get_path_to_dict(self, path):
|
||||||
|
@ -164,3 +146,7 @@ class ContrailVRouterAgentClient(ClientContrailVRouterAgentBase):
|
||||||
def get_itf_by_name(self, interface_name):
|
def get_itf_by_name(self, interface_name):
|
||||||
data = self.get_path_to_dict('Snh_ItfReq?x={}'.format(interface_name))
|
data = self.get_path_to_dict('Snh_ItfReq?x={}'.format(interface_name))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def get_sg_list(self):
|
||||||
|
data = self.get_path_to_dict('Snh_SgListReq')
|
||||||
|
return data
|
||||||
|
|
|
@ -647,7 +647,8 @@ def test_update_vm_ip(server, subnet, port_steps, server_steps):
|
||||||
[dict(ips=('10.0.0.10', '10.0.0.20'))],
|
[dict(ips=('10.0.0.10', '10.0.0.20'))],
|
||||||
indirect=True)
|
indirect=True)
|
||||||
def test_diff_proj_same_vn_vm_add_delete(different_tenants_resources,
|
def test_diff_proj_same_vn_vm_add_delete(different_tenants_resources,
|
||||||
client_contrail_vrouter_agent):
|
client_contrail_vrouter_agents,
|
||||||
|
os_faults_steps):
|
||||||
"""Test to validate that a VN and VM with the same name and same subnet
|
"""Test to validate that a VN and VM with the same name and same subnet
|
||||||
can be created in two different projects.
|
can be created in two different projects.
|
||||||
|
|
||||||
|
@ -661,7 +662,13 @@ def test_diff_proj_same_vn_vm_add_delete(different_tenants_resources,
|
||||||
"""
|
"""
|
||||||
resources = different_tenants_resources
|
resources = different_tenants_resources
|
||||||
|
|
||||||
itfs = client_contrail_vrouter_agent.get_itfs()['ItfResp'][
|
compute_host = getattr(resources[0].server,
|
||||||
|
stepler_config.SERVER_ATTR_HOST)
|
||||||
|
compute_fqdn = os_faults_steps.get_fqdn_by_host_name(compute_host)
|
||||||
|
|
||||||
|
vrouter_agent_client = client_contrail_vrouter_agents[compute_fqdn]
|
||||||
|
|
||||||
|
itfs = vrouter_agent_client.get_itfs()['ItfResp'][
|
||||||
'itf_list']
|
'itf_list']
|
||||||
|
|
||||||
s1_net_label = next(vrif['label'] for vrif in itfs
|
s1_net_label = next(vrif['label'] for vrif in itfs
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import attrdict
|
import attrdict
|
||||||
from hamcrest import assert_that, equal_to # noqa: H301
|
from hamcrest import (assert_that, equal_to, only_contains,
|
||||||
|
has_entries) # noqa: H301
|
||||||
from pycontrail import types
|
from pycontrail import types
|
||||||
import pytest
|
import pytest
|
||||||
from stepler import config as stepler_config
|
from stepler import config as stepler_config
|
||||||
|
@ -448,3 +449,36 @@ def test_add_remove_security_group_with_active_flow(
|
||||||
ifaces[0], tcp_filter)
|
ifaces[0], tcp_filter)
|
||||||
connectivity.check_packets_on_iface(os_faults_steps, computes[1],
|
connectivity.check_packets_on_iface(os_faults_steps, computes[1],
|
||||||
ifaces[1], udp_filter)
|
ifaces[1], udp_filter)
|
||||||
|
|
||||||
|
|
||||||
|
def test_security_group_on_vrouter(
|
||||||
|
server, security_group, client_contrail_vrouter_agents,
|
||||||
|
os_faults_steps, neutron_create_security_group):
|
||||||
|
"""Check that server's compute vRouter "know" about security groups.
|
||||||
|
|
||||||
|
Steps:
|
||||||
|
#. Create server with security group
|
||||||
|
#. Check that security group uuid is present on server's vRouter agent
|
||||||
|
/Snh_SgListReq reply
|
||||||
|
#. Create new security group
|
||||||
|
#. Add created security group to server
|
||||||
|
#. Check that new security group uuid is present on server's vRouter
|
||||||
|
agent /Snh_SgListReq reply
|
||||||
|
"""
|
||||||
|
compute_host = getattr(server, stepler_config.SERVER_ATTR_HOST)
|
||||||
|
compute_fqdn = os_faults_steps.get_fqdn_by_host_name(compute_host)
|
||||||
|
vrouter_agent = client_contrail_vrouter_agents[compute_fqdn]
|
||||||
|
|
||||||
|
sg_list = vrouter_agent.get_sg_list()['SgListResp']['sg_list']
|
||||||
|
assert_that(
|
||||||
|
sg_list, only_contains(has_entries(sg_uuid=security_group['id'])))
|
||||||
|
|
||||||
|
new_security_group = neutron_create_security_group(
|
||||||
|
next(utils.generate_ids()))
|
||||||
|
server.add_security_group(new_security_group['id'])
|
||||||
|
|
||||||
|
sg_list = vrouter_agent.get_sg_list()['SgListResp']['sg_list']
|
||||||
|
assert_that(sg_list,
|
||||||
|
only_contains(
|
||||||
|
has_entries(sg_uuid=security_group['id']),
|
||||||
|
has_entries(sg_uuid=new_security_group['id'])))
|
||||||
|
|
Loading…
Reference in New Issue