Implement NeutronV2 Driver
This patch adds a neutronv2 driver. This driver allows one to write policy against neutron and exposes an improved schema from the first version of the driver (i.e no more subtables). This patch also exposes security-group-rules from neutron which were not exposed in the previous driver. Note: This patch does not remove the original datasource driver. I plan to remove this in a follow up patchset. The reason why I didn't remove it in this one is that test_congress uses the neutron datasource driver for several of its tests. Implements blueprint: neutron-datasource-driver-refactor Change-Id: I2124e449d524eea3ab293e0a592b9850f0896bd1
This commit is contained in:
parent
0f55d6dc48
commit
d6f4105f01
|
@ -0,0 +1,300 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright (c) 2014 VMware, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
import neutronclient.v2_0.client
|
||||
|
||||
from congress.datasources.datasource_driver import DataSourceDriver
|
||||
from congress.datasources import datasource_utils
|
||||
from congress.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def d6service(name, keys, inbox, datapath, args):
|
||||
"""This method is called by d6cage to create a dataservice instance."""
|
||||
return NeutronV2Driver(name, keys, inbox, datapath, args)
|
||||
|
||||
|
||||
class NeutronV2Driver(DataSourceDriver):
|
||||
|
||||
# This is the most common per-value translator, so define it once here.
|
||||
value_trans = {'translation-type': 'VALUE'}
|
||||
|
||||
networks_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'networks',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'field-translators':
|
||||
({'fieldname': 'id', 'translator': value_trans},
|
||||
{'fieldname': 'tenant_id', 'translator': value_trans},
|
||||
{'fieldname': 'name', 'translator': value_trans},
|
||||
{'fieldname': 'status', 'translator': value_trans},
|
||||
{'fieldname': 'admin_state_up', 'translator': value_trans},
|
||||
{'fieldname': 'shared', 'translator': value_trans})}
|
||||
|
||||
ports_fixed_ips_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'fixed_ips',
|
||||
'parent-key': 'id',
|
||||
'parent-col-name': 'port_id',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'in-list': True,
|
||||
'field-translators':
|
||||
({'fieldname': 'ip_address', 'translator': value_trans},
|
||||
{'fieldname': 'subnet_id', 'translator': value_trans})}
|
||||
|
||||
ports_security_groups_translator = {
|
||||
'translation-type': 'LIST',
|
||||
'table-name': 'security_group_port_bindings',
|
||||
'parent-key': 'id',
|
||||
'parent-col-name': 'port_id',
|
||||
'val-col': 'security_group_id',
|
||||
'translator': value_trans}
|
||||
|
||||
ports_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'ports',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'field-translators':
|
||||
({'fieldname': 'id', 'translator': value_trans},
|
||||
{'fieldname': 'tenant_id', 'translator': value_trans},
|
||||
{'fieldname': 'name', 'translator': value_trans},
|
||||
{'fieldname': 'network_id', 'translator': value_trans},
|
||||
{'fieldname': 'mac_address', 'translator': value_trans},
|
||||
{'fieldname': 'admin_state_up', 'translator': value_trans},
|
||||
{'fieldname': 'status', 'translator': value_trans},
|
||||
{'fieldname': 'device_id', 'translator': value_trans},
|
||||
{'fieldname': 'device_owner', 'translator': value_trans},
|
||||
{'fieldname': 'fixed_ips',
|
||||
'translator': ports_fixed_ips_translator},
|
||||
{'fieldname': 'security_groups',
|
||||
'translator': ports_security_groups_translator})}
|
||||
|
||||
subnets_allocation_pools_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'allocation_pools',
|
||||
'parent-key': 'id',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'in-list': True,
|
||||
'field-translators':
|
||||
({'fieldname': 'start', 'translator': value_trans},
|
||||
{'fieldname': 'end', 'translator': value_trans})}
|
||||
|
||||
subnets_dns_nameservers_translator = {
|
||||
'translation-type': 'LIST',
|
||||
'table-name': 'dns_nameservers',
|
||||
'parent-key': 'id',
|
||||
'parent-col-name': 'subnet_id',
|
||||
'val-col': 'dns_nameserver',
|
||||
'translator': value_trans}
|
||||
|
||||
subnets_routes_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'host_routes',
|
||||
'parent-key': 'id',
|
||||
'parent-col-name': 'subnet_id',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'in-list': True,
|
||||
'field-translators':
|
||||
({'fieldname': 'destination', 'translator': value_trans},
|
||||
{'fieldname': 'nexthop', 'translator': value_trans})}
|
||||
|
||||
subnets_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'subnets',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'field-translators':
|
||||
({'fieldname': 'id', 'translator': value_trans},
|
||||
{'fieldname': 'tenant_id', 'translator': value_trans},
|
||||
{'fieldname': 'name', 'translator': value_trans},
|
||||
{'fieldname': 'network_id', 'translator': value_trans},
|
||||
{'fieldname': 'ip_version', 'translator': value_trans},
|
||||
{'fieldname': 'cidr', 'translator': value_trans},
|
||||
{'fieldname': 'gateway_ip', 'translator': value_trans},
|
||||
{'fieldname': 'enable_dhcp', 'translator': value_trans},
|
||||
{'fieldname': 'ipv6_ra_mode', 'translator': value_trans},
|
||||
{'fieldname': 'ipv6_address_mode', 'translator': value_trans},
|
||||
{'fieldname': 'allocation_pools',
|
||||
'translator': subnets_allocation_pools_translator},
|
||||
{'fieldname': 'dns_nameservers',
|
||||
'translator': subnets_dns_nameservers_translator},
|
||||
{'fieldname': 'host_routes',
|
||||
'translator': subnets_routes_translator})}
|
||||
|
||||
external_fixed_ips_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'external_fixed_ips',
|
||||
'parent-key': 'router_id',
|
||||
'parent-col-name': 'router_id',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'in-list': True,
|
||||
'field-translators':
|
||||
({'fieldname': 'subnet_id', 'translator': value_trans},
|
||||
{'fieldname': 'ip_address', 'translator': value_trans})}
|
||||
|
||||
routers_external_gateway_infos_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'external_gateway_infos',
|
||||
'parent-key': 'id',
|
||||
'parent-col-name': 'router_id',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'field-translators':
|
||||
({'fieldname': 'network_id', 'translator': value_trans},
|
||||
{'fieldname': 'enable_snat', 'translator': value_trans},
|
||||
{'fieldname': 'external_fixed_ips',
|
||||
'translator': external_fixed_ips_translator})}
|
||||
|
||||
routers_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'routers',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'field-translators':
|
||||
({'fieldname': 'id', 'translator': value_trans},
|
||||
{'fieldname': 'tenant_id', 'translator': value_trans},
|
||||
{'fieldname': 'status', 'translator': value_trans},
|
||||
{'fieldname': 'admin_state_up', 'translator': value_trans},
|
||||
{'fieldname': 'name', 'translator': value_trans},
|
||||
{'fieldname': 'distributed', 'translator': value_trans},
|
||||
{'fieldname': 'external_gateway_info',
|
||||
'translator': routers_external_gateway_infos_translator})}
|
||||
|
||||
security_group_rules_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'security_group_rules',
|
||||
'parent-key': 'id',
|
||||
'parent-col-name': 'security_group_id',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'in-list': True,
|
||||
'field-translators':
|
||||
({'fieldname': 'id', 'translator': value_trans},
|
||||
{'fieldname': 'tenant_id', 'translator': value_trans},
|
||||
{'fieldname': 'remote_group_id', 'translator': value_trans},
|
||||
{'fieldname': 'direction', 'translator': value_trans},
|
||||
{'fieldname': 'ethertype', 'translator': value_trans},
|
||||
{'fieldname': 'protocol', 'translator': value_trans},
|
||||
{'fieldname': 'port_range_min', 'translator': value_trans},
|
||||
{'fieldname': 'port_range_max', 'translator': value_trans},
|
||||
{'fieldname': 'remote_ip_prefix', 'translator': value_trans})}
|
||||
|
||||
security_group_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': 'security_groups',
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'field-translators':
|
||||
({'fieldname': 'id', 'translator': value_trans},
|
||||
{'fieldname': 'tenant_id', 'translator': value_trans},
|
||||
{'fieldname': 'name', 'translator': value_trans},
|
||||
{'fieldname': 'description', 'translator': value_trans},
|
||||
{'fieldname': 'security_group_rules',
|
||||
'translator': security_group_rules_translator})}
|
||||
|
||||
def __init__(self, name='', keys='', inbox=None,
|
||||
datapath=None, args=None):
|
||||
super(NeutronV2Driver, self).__init__(name, keys, inbox,
|
||||
datapath, args)
|
||||
self.creds = datasource_utils.get_credentials(name, args)
|
||||
self.register_translator(NeutronV2Driver.networks_translator)
|
||||
self.register_translator(NeutronV2Driver.ports_translator)
|
||||
self.register_translator(NeutronV2Driver.subnets_translator)
|
||||
self.register_translator(NeutronV2Driver.routers_translator)
|
||||
self.register_translator(NeutronV2Driver.security_group_translator)
|
||||
self.neutron = neutronclient.v2_0.client.Client(**self.creds)
|
||||
|
||||
# Store raw state (result of API calls) so that we can
|
||||
# avoid re-translating and re-sending if no changes occurred.
|
||||
# Because translation is not deterministic (we're generating
|
||||
# UUIDs), it's hard to tell if no changes occurred
|
||||
# after performing the translation.
|
||||
self.raw_state = {}
|
||||
self.initialized = True
|
||||
|
||||
def update_from_datasource(self):
|
||||
LOG.debug("Neutron grabbing networks")
|
||||
networks = self.neutron.list_networks()
|
||||
if ('networks' not in self.raw_state or
|
||||
networks != self.raw_state['networks']):
|
||||
self.raw_state['networks'] = networks
|
||||
self._translate_networks(networks)
|
||||
|
||||
LOG.debug("Neutron grabbing ports")
|
||||
ports = self.neutron.list_ports()
|
||||
if 'ports' not in self.raw_state or ports != self.raw_state['ports']:
|
||||
self.raw_state['ports'] = ports
|
||||
self._translate_ports(ports)
|
||||
|
||||
subnets = self.neutron.list_subnets()
|
||||
if ('subnets' not in self.raw_state
|
||||
or subnets != self.raw_state['subnets']):
|
||||
self.raw_state['subnets'] = subnets
|
||||
self._translate_subnets(subnets)
|
||||
routers = self.neutron.list_routers()
|
||||
if ('routers' not in self.raw_state
|
||||
or routers != self.raw_state['routers']):
|
||||
self.raw_state['routers'] = routers
|
||||
self._translate_routers(routers)
|
||||
|
||||
security_groups = self.neutron.list_security_groups()
|
||||
if ('security_groups' not in self.raw_state
|
||||
or security_groups != self.raw_state['security_groups']):
|
||||
self.raw_state['security_groups'] = security_groups
|
||||
self._translate_security_groups(security_groups)
|
||||
|
||||
def _translate_networks(self, obj):
|
||||
LOG.debug("networks: %s", dict(obj))
|
||||
|
||||
row_data = NeutronV2Driver.convert_objs(obj['networks'],
|
||||
self.networks_translator)
|
||||
self.state['networks'] = set()
|
||||
for table, row in row_data:
|
||||
self.state[table].add(row)
|
||||
|
||||
def _translate_ports(self, obj):
|
||||
LOG.debug("ports: %s", obj)
|
||||
row_data = NeutronV2Driver.convert_objs(obj['ports'],
|
||||
self.ports_translator)
|
||||
self.state['ports'] = set()
|
||||
self.state['fixed_ips'] = set()
|
||||
self.state['security_group_port_bindings'] = set()
|
||||
for table, row in row_data:
|
||||
self.state[table].add(row)
|
||||
|
||||
def _translate_subnets(self, obj):
|
||||
LOG.debug("subnets: %s", obj)
|
||||
row_data = NeutronV2Driver.convert_objs(obj['subnets'],
|
||||
self.subnets_translator)
|
||||
self.state['subnets'] = set()
|
||||
self.state['host_routes'] = set()
|
||||
self.state['dns_nameservers'] = set()
|
||||
self.state['allocation_pools'] = set()
|
||||
for table, row in row_data:
|
||||
self.state[table].add(row)
|
||||
|
||||
def _translate_routers(self, obj):
|
||||
LOG.debug("routers: %s", obj)
|
||||
row_data = NeutronV2Driver.convert_objs(obj['routers'],
|
||||
self.routers_translator)
|
||||
self.state['routers'] = set()
|
||||
self.state['external_gateway_infos'] = set()
|
||||
for table, row in row_data:
|
||||
self.state[table].add(row)
|
||||
|
||||
def _translate_security_groups(self, obj):
|
||||
LOG.debug("security_groups: %s", obj)
|
||||
row_data = NeutronV2Driver.convert_objs(obj['security_groups'],
|
||||
self.security_group_translator)
|
||||
self.state['security_groups'] = set()
|
||||
self.state['security_group_rules'] = set()
|
||||
for table, row in row_data:
|
||||
self.state[table].add(row)
|
|
@ -0,0 +1,431 @@
|
|||
# Copyright (c) 2013 VMware, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
import contextlib
|
||||
|
||||
import mock
|
||||
|
||||
from congress.datasources import neutronv2_driver
|
||||
from congress.tests import base
|
||||
from congress.tests import helper
|
||||
|
||||
|
||||
class TestNeutronV2Driver(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNeutronV2Driver, self).setUp()
|
||||
self.neutron_client_p = mock.patch(
|
||||
"neutronclient.v2_0.client.Client")
|
||||
self.neutron_client_p.start()
|
||||
|
||||
args = helper.datasource_openstack_args()
|
||||
args['poll_time'] = 0
|
||||
args['client'] = mock.MagicMock()
|
||||
self.driver = neutronv2_driver.NeutronV2Driver(args=args)
|
||||
|
||||
self.mock_networks = {'networks': [
|
||||
{u'admin_state_up': True,
|
||||
u'id': u'63ce8fbb-12e9-4ecd-9b56-1bbf8b51217d',
|
||||
u'name': u'private',
|
||||
u'router:external': False,
|
||||
u'shared': False,
|
||||
u'status': u'ACTIVE',
|
||||
u'subnets': [u'3c0eb3a3-4d16-4b1b-b327-44417182d0bb'],
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'},
|
||||
{u'admin_state_up': True,
|
||||
u'id': u'ecdea1af-7197-43c8-b3b0-34d90f72a2a8',
|
||||
u'name': u'public',
|
||||
u'router:external': True,
|
||||
u'shared': False,
|
||||
u'status': u'ACTIVE',
|
||||
u'subnets': [u'10d20df9-e8ba-4756-ba30-d573ceb2e99a'],
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'}]}
|
||||
|
||||
self.mock_ports = {'ports': [
|
||||
{u'admin_state_up': True,
|
||||
u'allowed_address_pairs': [],
|
||||
u'binding:host_id': None,
|
||||
u'binding:vif_details': {u'port_filter': True},
|
||||
u'binding:vif_type': u'ovs',
|
||||
u'binding:vnic_type': u'normal',
|
||||
u'device_id': u'f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
u'device_owner': u'network:router_gateway',
|
||||
u'fixed_ips': [
|
||||
{u'ip_address': u'1.1.1.2',
|
||||
u'subnet_id': u'10d20df9-e8ba-4756-ba30-d573ceb2e99a'}],
|
||||
u'id': u'04627c85-3553-436c-a7c5-0a64f5b87bb9',
|
||||
u'mac_address': u'fa:16:3e:f3:19:e5',
|
||||
u'name': u'',
|
||||
u'network_id': u'ecdea1af-7197-43c8-b3b0-34d90f72a2a8',
|
||||
u'port_security_enabled': False,
|
||||
u'security_groups': [],
|
||||
u'status': u'DOWN',
|
||||
u'tenant_id': u''},
|
||||
{u'admin_state_up': True,
|
||||
u'allowed_address_pairs': [],
|
||||
u'binding:host_id': None,
|
||||
u'binding:vif_details': {u'port_filter': True},
|
||||
u'binding:vif_type': u'ovs',
|
||||
u'binding:vnic_type': u'normal',
|
||||
u'device_id': u'f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
u'device_owner': u'network:router_interface',
|
||||
u'fixed_ips': [
|
||||
{u'ip_address': u'169.254.169.253',
|
||||
u'subnet_id': u'aa9ad4f7-baf0-4a41-85c3-1cc8a3066db6'}],
|
||||
u'id': u'87f8933a-9582-48d8-ad16-9abf6e545002',
|
||||
u'mac_address': u'fa:16:3e:b7:78:e8',
|
||||
u'name': u'',
|
||||
u'network_id': u'6743ff85-2cfd-48a7-9d3f-472cd418783e',
|
||||
u'port_security_enabled': False,
|
||||
u'security_groups': [],
|
||||
u'status': u'DOWN',
|
||||
u'tenant_id': u''},
|
||||
{u'admin_state_up': True,
|
||||
u'allowed_address_pairs': [],
|
||||
u'binding:host_id': None,
|
||||
u'binding:vif_details': {u'port_filter': True},
|
||||
u'binding:vif_type': u'ovs',
|
||||
u'binding:vnic_type': u'normal',
|
||||
u'device_id': u'f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
u'device_owner': u'network:router_interface',
|
||||
u'fixed_ips': [
|
||||
{u'ip_address': u'10.0.0.1',
|
||||
u'subnet_id': u'3c0eb3a3-4d16-4b1b-b327-44417182d0bb'}],
|
||||
u'id': u'c58c3246-6c2e-490a-b4d9-3b8d5191b465',
|
||||
u'mac_address': u'fa:16:3e:08:31:6e',
|
||||
u'name': u'',
|
||||
u'network_id': u'63ce8fbb-12e9-4ecd-9b56-1bbf8b51217d',
|
||||
u'port_security_enabled': False,
|
||||
u'security_groups': [],
|
||||
u'status': u'DOWN',
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'},
|
||||
{u'admin_state_up': True,
|
||||
u'allowed_address_pairs': [],
|
||||
u'binding:host_id': None,
|
||||
u'binding:vif_details': {u'port_filter': True},
|
||||
u'binding:vif_type': u'ovs',
|
||||
u'binding:vnic_type': u'normal',
|
||||
u'device_id': u'',
|
||||
u'device_owner': u'',
|
||||
u'fixed_ips': [
|
||||
{u'ip_address': u'10.0.0.2',
|
||||
u'subnet_id': u'3c0eb3a3-4d16-4b1b-b327-44417182d0bb'}],
|
||||
u'id': u'eb50003b-a081-4533-92aa-1cbd97f526a8',
|
||||
u'mac_address': u'fa:16:3e:af:56:fa',
|
||||
u'name': u'',
|
||||
u'network_id': u'63ce8fbb-12e9-4ecd-9b56-1bbf8b51217d',
|
||||
u'port_security_enabled': True,
|
||||
u'security_groups': [u'e0239062-4243-4798-865f-7055f03786d6'],
|
||||
u'status': u'DOWN',
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'}]}
|
||||
|
||||
self.mock_subnets = {'subnets': [
|
||||
{u'allocation_pools': [{u'end': u'1.1.1.254',
|
||||
u'start': u'1.1.1.2'}],
|
||||
u'cidr': u'1.1.1.0/24',
|
||||
u'dns_nameservers': [],
|
||||
u'enable_dhcp': True,
|
||||
u'gateway_ip': u'1.1.1.1',
|
||||
u'host_routes': [],
|
||||
u'id': u'10d20df9-e8ba-4756-ba30-d573ceb2e99a',
|
||||
u'ip_version': 4,
|
||||
u'ipv6_address_mode': None,
|
||||
u'ipv6_ra_mode': None,
|
||||
u'name': u'',
|
||||
u'network_id': u'ecdea1af-7197-43c8-b3b0-34d90f72a2a8',
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'},
|
||||
{u'allocation_pools': [{u'end': u'10.0.0.254',
|
||||
u'start': u'10.0.0.2'}],
|
||||
u'cidr': u'10.0.0.0/24',
|
||||
u'dns_nameservers': [u'8.8.8.8'],
|
||||
u'enable_dhcp': True,
|
||||
u'gateway_ip': u'10.0.0.1',
|
||||
u'host_routes': [{u'destination': u'10.10.0.2/32',
|
||||
u'nexthop': u'10.0.0.1'}],
|
||||
u'id': u'3c0eb3a3-4d16-4b1b-b327-44417182d0bb',
|
||||
u'ip_version': 4,
|
||||
u'ipv6_address_mode': None,
|
||||
u'ipv6_ra_mode': None,
|
||||
u'name': u'private-subnet',
|
||||
u'network_id': u'63ce8fbb-12e9-4ecd-9b56-1bbf8b51217d',
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'},
|
||||
{u'allocation_pools': [{u'end': u'169.254.169.254',
|
||||
u'start': u'169.254.169.254'}],
|
||||
u'cidr': u'169.254.169.252/30',
|
||||
u'dns_nameservers': [],
|
||||
u'enable_dhcp': True,
|
||||
u'gateway_ip': u'169.254.169.253',
|
||||
u'host_routes': [],
|
||||
u'id': u'aa9ad4f7-baf0-4a41-85c3-1cc8a3066db6',
|
||||
u'ip_version': 4,
|
||||
u'ipv6_address_mode': None,
|
||||
u'ipv6_ra_mode': None,
|
||||
u'name': u'meta-f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
u'network_id': u'6743ff85-2cfd-48a7-9d3f-472cd418783e',
|
||||
u'tenant_id': u''}]}
|
||||
|
||||
self.mock_routers = {'routers': [
|
||||
{u'admin_state_up': True,
|
||||
u'distributed': False,
|
||||
u'external_gateway_info': {
|
||||
u'enable_snat': True,
|
||||
u'external_fixed_ips': [
|
||||
{u'ip_address': u'1.1.1.2',
|
||||
u'subnet_id': u'10d20df9-e8ba-4756-ba30-d573ceb2e99a'}],
|
||||
u'network_id': u'ecdea1af-7197-43c8-b3b0-34d90f72a2a8'},
|
||||
u'id': u'f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
u'name': u'myrouter',
|
||||
u'routes': [],
|
||||
u'status': u'DOWN',
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'}]}
|
||||
|
||||
self.mock_security_groups = {'security_groups': [
|
||||
{u'description': u'Default security group',
|
||||
u'id': u'a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
u'name': u'default',
|
||||
u'security_group_rules': [
|
||||
{u'direction': u'egress',
|
||||
u'ethertype': u'IPv4',
|
||||
u'id': u'1d943e83-e4e6-472a-9655-f74eb22f3668',
|
||||
u'port_range_max': None,
|
||||
u'port_range_min': None,
|
||||
u'protocol': None,
|
||||
u'remote_group_id': None,
|
||||
u'remote_ip_prefix': None,
|
||||
u'security_group_id':
|
||||
u'a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
u'tenant_id': u''},
|
||||
{u'direction': u'ingress',
|
||||
u'ethertype': u'IPv4',
|
||||
u'id': u'30be5ee1-5b0a-4929-aca5-0c25f1c6b733',
|
||||
u'port_range_max': None,
|
||||
u'port_range_min': None,
|
||||
u'protocol': None,
|
||||
u'remote_group_id': u'a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
u'remote_ip_prefix': None,
|
||||
u'security_group_id':
|
||||
u'a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
u'tenant_id': u''},
|
||||
{u'direction': u'ingress',
|
||||
u'ethertype': u'IPv6',
|
||||
u'id': u'639995b8-c3ac-44a3-a4f3-c74f9172ad54',
|
||||
u'port_range_max': None,
|
||||
u'port_range_min': None,
|
||||
u'protocol': None,
|
||||
u'remote_group_id': u'a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
u'remote_ip_prefix': None,
|
||||
u'security_group_id':
|
||||
u'a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
u'tenant_id': u''},
|
||||
{u'direction': u'egress',
|
||||
u'ethertype': u'IPv6',
|
||||
u'id': u'ed7fd9f6-e390-448a-9f5f-8dd4659282f7',
|
||||
u'port_range_max': None,
|
||||
u'port_range_min': None,
|
||||
u'protocol': None,
|
||||
u'remote_group_id': None,
|
||||
u'remote_ip_prefix': None,
|
||||
u'security_group_id':
|
||||
u'a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
u'tenant_id': u''}],
|
||||
u'tenant_id': u''},
|
||||
{u'description': u'Default security group',
|
||||
u'id': u'e0239062-4243-4798-865f-7055f03786d6',
|
||||
u'name': u'default',
|
||||
u'security_group_rules': [
|
||||
{u'direction': u'ingress',
|
||||
u'ethertype': u'IPv6',
|
||||
u'id': u'8a81fecc-ecc7-48ca-bccc-195799667e23',
|
||||
u'port_range_max': None,
|
||||
u'port_range_min': None,
|
||||
u'protocol': None,
|
||||
u'remote_group_id': u'e0239062-4243-4798-865f-7055f03786d6',
|
||||
u'remote_ip_prefix': None,
|
||||
u'security_group_id':
|
||||
u'e0239062-4243-4798-865f-7055f03786d6',
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'},
|
||||
{u'direction': u'ingress',
|
||||
u'ethertype': u'IPv4',
|
||||
u'id': u'8f4d9e99-1fe8-4816-9f07-c4ecddea9427',
|
||||
u'port_range_max': None,
|
||||
u'port_range_min': None,
|
||||
u'protocol': None,
|
||||
u'remote_group_id': u'e0239062-4243-4798-865f-7055f03786d6',
|
||||
u'remote_ip_prefix': None,
|
||||
u'security_group_id':
|
||||
u'e0239062-4243-4798-865f-7055f03786d6',
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'},
|
||||
{u'direction': u'egress',
|
||||
u'ethertype': u'IPv4',
|
||||
u'id': u'e70cf243-3389-4f80-82dc-92a3ec1f2d2a',
|
||||
u'port_range_max': None,
|
||||
u'port_range_min': None,
|
||||
u'protocol': None,
|
||||
u'remote_group_id': None,
|
||||
u'remote_ip_prefix': None,
|
||||
u'security_group_id':
|
||||
u'e0239062-4243-4798-865f-7055f03786d6',
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'},
|
||||
{u'direction': u'egress',
|
||||
u'ethertype': u'IPv6',
|
||||
u'id': u'eca1df0f-b222-4208-8f96-8a8024fd6834',
|
||||
u'port_range_max': None,
|
||||
u'port_range_min': None,
|
||||
u'protocol': None,
|
||||
u'remote_group_id': None,
|
||||
u'remote_ip_prefix': None,
|
||||
u'security_group_id':
|
||||
u'e0239062-4243-4798-865f-7055f03786d6',
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'}],
|
||||
u'tenant_id': u'feee0a965cc34274917fb753623dd57d'}]}
|
||||
|
||||
self.expected_state = {
|
||||
'subnets': set([
|
||||
('3c0eb3a3-4d16-4b1b-b327-44417182d0bb',
|
||||
'feee0a965cc34274917fb753623dd57d', 'private-subnet',
|
||||
'63ce8fbb-12e9-4ecd-9b56-1bbf8b51217d', 4, '10.0.0.0/24',
|
||||
'10.0.0.1', 'True', 'None', 'None'),
|
||||
('aa9ad4f7-baf0-4a41-85c3-1cc8a3066db6', '',
|
||||
'meta-f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
'6743ff85-2cfd-48a7-9d3f-472cd418783e', 4,
|
||||
'169.254.169.252/30',
|
||||
'169.254.169.253', 'True', 'None', 'None'),
|
||||
('10d20df9-e8ba-4756-ba30-d573ceb2e99a',
|
||||
'feee0a965cc34274917fb753623dd57d', '',
|
||||
'ecdea1af-7197-43c8-b3b0-34d90f72a2a8', 4, '1.1.1.0/24',
|
||||
'1.1.1.1', 'True', 'None', 'None')]),
|
||||
'routers':
|
||||
set([('f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
'feee0a965cc34274917fb753623dd57d', 'DOWN', 'True',
|
||||
'myrouter', 'False')]),
|
||||
'dns_nameservers':
|
||||
set([('3c0eb3a3-4d16-4b1b-b327-44417182d0bb', '8.8.8.8')]),
|
||||
'security_group_rules':
|
||||
set([('e0239062-4243-4798-865f-7055f03786d6',
|
||||
'e70cf243-3389-4f80-82dc-92a3ec1f2d2a',
|
||||
'feee0a965cc34274917fb753623dd57d', 'None', 'egress',
|
||||
'IPv4', 'None', 'None', 'None', 'None'),
|
||||
('a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
'ed7fd9f6-e390-448a-9f5f-8dd4659282f7', '', 'None',
|
||||
'egress', 'IPv6', 'None', 'None', 'None', 'None'),
|
||||
('a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
'1d943e83-e4e6-472a-9655-f74eb22f3668', '', 'None',
|
||||
'egress', 'IPv4', 'None', 'None', 'None', 'None'),
|
||||
('a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
'30be5ee1-5b0a-4929-aca5-0c25f1c6b733', '',
|
||||
'a268fc32-1a59-4154-9a7c-f453ef92560c', 'ingress',
|
||||
'IPv4', 'None', 'None', 'None', 'None'),
|
||||
('e0239062-4243-4798-865f-7055f03786d6',
|
||||
'8a81fecc-ecc7-48ca-bccc-195799667e23',
|
||||
'feee0a965cc34274917fb753623dd57d',
|
||||
'e0239062-4243-4798-865f-7055f03786d6', 'ingress',
|
||||
'IPv6', 'None', 'None', 'None', 'None'),
|
||||
('a268fc32-1a59-4154-9a7c-f453ef92560c',
|
||||
'639995b8-c3ac-44a3-a4f3-c74f9172ad54', '',
|
||||
'a268fc32-1a59-4154-9a7c-f453ef92560c', 'ingress',
|
||||
'IPv6', 'None', 'None', 'None', 'None'),
|
||||
('e0239062-4243-4798-865f-7055f03786d6',
|
||||
'8f4d9e99-1fe8-4816-9f07-c4ecddea9427',
|
||||
'feee0a965cc34274917fb753623dd57d',
|
||||
'e0239062-4243-4798-865f-7055f03786d6',
|
||||
'ingress', 'IPv4', 'None', 'None', 'None', 'None'),
|
||||
('e0239062-4243-4798-865f-7055f03786d6',
|
||||
'eca1df0f-b222-4208-8f96-8a8024fd6834',
|
||||
'feee0a965cc34274917fb753623dd57d', 'None', 'egress',
|
||||
'IPv6', 'None', 'None', 'None', 'None')]),
|
||||
'ports':
|
||||
set([('c58c3246-6c2e-490a-b4d9-3b8d5191b465',
|
||||
'feee0a965cc34274917fb753623dd57d', '',
|
||||
'63ce8fbb-12e9-4ecd-9b56-1bbf8b51217d',
|
||||
'fa:16:3e:08:31:6e', 'True', 'DOWN',
|
||||
'f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
'network:router_interface'),
|
||||
('87f8933a-9582-48d8-ad16-9abf6e545002', '', '',
|
||||
'6743ff85-2cfd-48a7-9d3f-472cd418783e',
|
||||
'fa:16:3e:b7:78:e8', 'True', 'DOWN',
|
||||
'f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
'network:router_interface'),
|
||||
('eb50003b-a081-4533-92aa-1cbd97f526a8',
|
||||
'feee0a965cc34274917fb753623dd57d', '',
|
||||
'63ce8fbb-12e9-4ecd-9b56-1bbf8b51217d',
|
||||
'fa:16:3e:af:56:fa', 'True', 'DOWN', '', ''),
|
||||
('04627c85-3553-436c-a7c5-0a64f5b87bb9', '', '',
|
||||
'ecdea1af-7197-43c8-b3b0-34d90f72a2a8',
|
||||
'fa:16:3e:f3:19:e5', 'True', 'DOWN',
|
||||
'f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
'network:router_gateway')]),
|
||||
'allocation_pools':
|
||||
set([('10d20df9-e8ba-4756-ba30-d573ceb2e99a', '1.1.1.2',
|
||||
'1.1.1.254'),
|
||||
('3c0eb3a3-4d16-4b1b-b327-44417182d0bb', '10.0.0.2',
|
||||
'10.0.0.254'),
|
||||
('aa9ad4f7-baf0-4a41-85c3-1cc8a3066db6',
|
||||
'169.254.169.254', '169.254.169.254')]),
|
||||
'host_routes':
|
||||
set([('3c0eb3a3-4d16-4b1b-b327-44417182d0bb',
|
||||
'10.10.0.2/32', '10.0.0.1')]),
|
||||
'security_group_port_bindings':
|
||||
set([('eb50003b-a081-4533-92aa-1cbd97f526a8',
|
||||
'e0239062-4243-4798-865f-7055f03786d6')]),
|
||||
'external_gateway_infos':
|
||||
set([('f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
'ecdea1af-7197-43c8-b3b0-34d90f72a2a8', 'True')]),
|
||||
'fixed_ips':
|
||||
set([('c58c3246-6c2e-490a-b4d9-3b8d5191b465', '10.0.0.1',
|
||||
'3c0eb3a3-4d16-4b1b-b327-44417182d0bb'),
|
||||
('eb50003b-a081-4533-92aa-1cbd97f526a8', '10.0.0.2',
|
||||
'3c0eb3a3-4d16-4b1b-b327-44417182d0bb'),
|
||||
('87f8933a-9582-48d8-ad16-9abf6e545002',
|
||||
'169.254.169.253',
|
||||
'aa9ad4f7-baf0-4a41-85c3-1cc8a3066db6'),
|
||||
('04627c85-3553-436c-a7c5-0a64f5b87bb9', '1.1.1.2',
|
||||
'10d20df9-e8ba-4756-ba30-d573ceb2e99a')]),
|
||||
'networks':
|
||||
set([('ecdea1af-7197-43c8-b3b0-34d90f72a2a8',
|
||||
'feee0a965cc34274917fb753623dd57d', 'public',
|
||||
'ACTIVE', 'True', 'False'),
|
||||
('63ce8fbb-12e9-4ecd-9b56-1bbf8b51217d',
|
||||
'feee0a965cc34274917fb753623dd57d', 'private',
|
||||
'ACTIVE', 'True', 'False')]),
|
||||
'security_groups':
|
||||
set([('e0239062-4243-4798-865f-7055f03786d6',
|
||||
'feee0a965cc34274917fb753623dd57d', 'default',
|
||||
'Default security group'),
|
||||
('a268fc32-1a59-4154-9a7c-f453ef92560c', '',
|
||||
'default', 'Default security group')]),
|
||||
'external_fixed_ips':
|
||||
set([('f42dc4f1-f371-48cc-95be-cf1b97112ab8',
|
||||
'10d20df9-e8ba-4756-ba30-d573ceb2e99a', '1.1.1.2')])}
|
||||
|
||||
def test_update_from_datasource(self):
|
||||
with contextlib.nested(
|
||||
mock.patch.object(self.driver.neutron,
|
||||
"list_networks",
|
||||
return_value=self.mock_networks),
|
||||
mock.patch.object(self.driver.neutron,
|
||||
"list_ports",
|
||||
return_value=self.mock_ports),
|
||||
mock.patch.object(self.driver.neutron,
|
||||
"list_subnets",
|
||||
return_value=self.mock_subnets),
|
||||
mock.patch.object(self.driver.neutron,
|
||||
"list_routers",
|
||||
return_value=self.mock_routers),
|
||||
mock.patch.object(self.driver.neutron,
|
||||
"list_security_groups",
|
||||
return_value=self.mock_security_groups),
|
||||
) as (list_networks, list_ports, list_subnets, list_routers,
|
||||
list_security_groups):
|
||||
self.driver.update_from_datasource()
|
||||
self.assertEqual(self.driver.state, self.expected_state)
|
|
@ -109,7 +109,7 @@ function configure_congress {
|
|||
fi
|
||||
|
||||
rm -rf $CONGRESS_DATASOURCE_FILE
|
||||
_configure_service neutron neutron
|
||||
_configure_service neutron neutronv2
|
||||
_configure_service nova nova
|
||||
_configure_service key keystone
|
||||
_configure_service ceilometer ceilometer
|
||||
|
|
|
@ -0,0 +1,359 @@
|
|||
# Copyright 2014 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from tempest import clients
|
||||
from tempest import config
|
||||
from tempest import exceptions
|
||||
from tempest.openstack.common import log as logging
|
||||
from tempest.scenario import manager_congress
|
||||
from tempest import test
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestNeutronV2Driver(manager_congress.ScenarioPolicyBase):
|
||||
|
||||
@classmethod
|
||||
def check_preconditions(cls):
|
||||
super(TestNeutronV2Driver, cls).check_preconditions()
|
||||
if not (CONF.network.tenant_networks_reachable
|
||||
or CONF.network.public_network_id):
|
||||
msg = ('Either tenant_networks_reachable must be "true", or '
|
||||
'public_network_id must be defined.')
|
||||
cls.enabled = False
|
||||
raise cls.skipException(msg)
|
||||
|
||||
def setUp(cls):
|
||||
super(TestNeutronV2Driver, cls).setUp()
|
||||
if not CONF.service_available.neutron:
|
||||
skip_msg = ("%s skipped as neutron is not available"
|
||||
% cls.__name__)
|
||||
raise cls.skipException(skip_msg)
|
||||
cls.os = clients.Manager(cls.admin_credentials())
|
||||
cls.neutron_client = cls.os.network_client
|
||||
|
||||
@test.attr(type='smoke')
|
||||
@test.services('network')
|
||||
def test_neutronv2_networks_table(self):
|
||||
networks = self.neutron_client.list_networks()
|
||||
network_map = {}
|
||||
for network in networks['networks']:
|
||||
network_map[network['id']] = network
|
||||
|
||||
network_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'networks')['columns'])
|
||||
|
||||
def _check_data():
|
||||
results = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'networks'))
|
||||
for row in results['results']:
|
||||
network_row = network_map[row['data'][0]]
|
||||
for index in range(len(network_schema)):
|
||||
if (str(row['data'][index]) !=
|
||||
str(network_row[network_schema[index]['name']])):
|
||||
return False
|
||||
return True
|
||||
|
||||
if not test.call_until_true(func=_check_data,
|
||||
duration=200, sleep_for=10):
|
||||
raise exceptions.TimeoutException("Data did not converge in time "
|
||||
"or failure in server")
|
||||
|
||||
@test.attr(type='smoke')
|
||||
@test.services('network')
|
||||
def test_neutronv2_ports_tables(self):
|
||||
ports = self.neutron_client.list_ports()
|
||||
port_map = {}
|
||||
for port in ports['ports']:
|
||||
port_map[port['id']] = port
|
||||
|
||||
port_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'ports')['columns'])
|
||||
|
||||
port_sec_binding_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'security_group_port_bindings')['columns'])
|
||||
|
||||
fixed_ips_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'fixed_ips')['columns'])
|
||||
|
||||
def _check_data():
|
||||
ports = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'ports'))
|
||||
security_group_port_bindings = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'security_group_port_bindings'))
|
||||
fixed_ips = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'fixed_ips'))
|
||||
|
||||
# Validate ports table
|
||||
for row in ports['results']:
|
||||
port_row = port_map[row['data'][0]]
|
||||
for index in range(len(port_schema)):
|
||||
if (str(row['data'][index]) !=
|
||||
str(port_row[port_schema[index]['name']])):
|
||||
return False
|
||||
|
||||
# validate security_group_port_bindings table
|
||||
for row in security_group_port_bindings['results']:
|
||||
port_row = port_map[row['data'][0]]
|
||||
for index in range(len(port_sec_binding_schema)):
|
||||
row_index = port_sec_binding_schema[index]['name']
|
||||
# Translate port_id -> id
|
||||
if row_index == 'port_id':
|
||||
if (str(row['data'][index]) !=
|
||||
str(port_row['id'])):
|
||||
return False
|
||||
elif row_index == 'security_group_id':
|
||||
if (str(row['data'][index]) not in
|
||||
port_row['security_groups']):
|
||||
return False
|
||||
|
||||
# validate fixed_ips
|
||||
for row in fixed_ips['results']:
|
||||
port_row = port_map[row['data'][0]]
|
||||
for index in range(len(fixed_ips_schema)):
|
||||
row_index = fixed_ips_schema[index]['name']
|
||||
if row_index in ['subnet_id', 'ip_address']:
|
||||
if not port_row['fixed_ips']:
|
||||
continue
|
||||
for fixed_ip in port_row['fixed_ips']:
|
||||
if row['data'][index] == fixed_ip[row_index]:
|
||||
break
|
||||
else:
|
||||
# no subnet_id/ip_address match found
|
||||
return False
|
||||
return True
|
||||
|
||||
if not test.call_until_true(func=_check_data,
|
||||
duration=200, sleep_for=10):
|
||||
raise exceptions.TimeoutException("Data did not converge in time "
|
||||
"or failure in server")
|
||||
|
||||
@test.attr(type='smoke')
|
||||
@test.services('network')
|
||||
def test_neutronv2_subnets_tables(self):
|
||||
subnets = self.neutron_client.list_subnets()
|
||||
subnet_map = {}
|
||||
for subnet in subnets['subnets']:
|
||||
subnet_map[subnet['id']] = subnet
|
||||
|
||||
subnet_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'subnets')['columns'])
|
||||
|
||||
host_routes_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'host_routes')['columns'])
|
||||
|
||||
dns_nameservers_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'dns_nameservers')['columns'])
|
||||
|
||||
allocation_pools_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'allocation_pools')['columns'])
|
||||
|
||||
def _check_data():
|
||||
subnets = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'subnets'))
|
||||
host_routes = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'host_routes'))
|
||||
dns_nameservers = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'dns_nameservers'))
|
||||
allocation_pools = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'allocation_pools'))
|
||||
|
||||
# Validate subnets table
|
||||
for row in subnets['results']:
|
||||
subnet_row = subnet_map[row['data'][0]]
|
||||
for index in range(len(subnet_schema)):
|
||||
if (str(row['data'][index]) !=
|
||||
str(subnet_row[subnet_schema[index]['name']])):
|
||||
return False
|
||||
|
||||
# validate dns_nameservers
|
||||
for row in dns_nameservers['results']:
|
||||
subnet_row = subnet_map[row['data'][0]]
|
||||
for index in range(len(dns_nameservers_schema)):
|
||||
row_index = dns_nameservers_schema[index]['name']
|
||||
if row_index in ['dns_nameserver']:
|
||||
if (row['data'][index]
|
||||
not in subnet_row['dns_nameservers']):
|
||||
return False
|
||||
|
||||
# validate host_routes
|
||||
for row in host_routes['results']:
|
||||
subnet_row = subnet_map[row['data'][0]]
|
||||
for index in range(len(host_routes_schema)):
|
||||
row_index = host_routes_schema[index]['name']
|
||||
if row_index in ['destination', 'nexthop']:
|
||||
if not subnet_row['host_routes']:
|
||||
continue
|
||||
for host_route in subnet_row['host_routes']:
|
||||
if row['data'][index] == host_route[row_index]:
|
||||
break
|
||||
else:
|
||||
# no destination/nexthop match found
|
||||
return False
|
||||
|
||||
# validate allocation_pools
|
||||
for row in allocation_pools['results']:
|
||||
subnet_row = subnet_map[row['data'][0]]
|
||||
for index in range(len(allocation_pools_schema)):
|
||||
row_index = allocation_pools_schema[index]['name']
|
||||
if row_index in ['start', 'end']:
|
||||
if not subnet_row['allocation_pools']:
|
||||
continue
|
||||
for allocation_pool in subnet_row['allocation_pools']:
|
||||
if (row['data'][index] ==
|
||||
allocation_pool[row_index]):
|
||||
break
|
||||
else:
|
||||
# no destination/nexthop match found
|
||||
return False
|
||||
return True
|
||||
|
||||
if not test.call_until_true(func=_check_data,
|
||||
duration=200, sleep_for=10):
|
||||
raise exceptions.TimeoutException("Data did not converge in time "
|
||||
"or failure in server")
|
||||
|
||||
@test.attr(type='smoke')
|
||||
@test.services('network')
|
||||
def test_neutronv2_routers_tables(self):
|
||||
routers = self.neutron_client.list_routers()
|
||||
router_map = {}
|
||||
for router in routers['routers']:
|
||||
router_map[router['id']] = router
|
||||
|
||||
router_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'routers')['columns'])
|
||||
|
||||
ext_gw_info_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'external_gateway_infos')['columns'])
|
||||
|
||||
def _check_data():
|
||||
routers = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'routers'))
|
||||
|
||||
ext_gw_info = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'external_gateway_infos'))
|
||||
|
||||
# Validate routers table
|
||||
for row in routers['results']:
|
||||
router_row = router_map[row['data'][0]]
|
||||
for index in range(len(router_schema)):
|
||||
if (str(row['data'][index]) !=
|
||||
str(router_row[router_schema[index]['name']])):
|
||||
return False
|
||||
|
||||
# validate external_gateway_infos
|
||||
for row in ext_gw_info['results']:
|
||||
router_ext_gw_info = (
|
||||
router_map[row['data'][0]]['external_gateway_info'])
|
||||
# populate router_id
|
||||
router_ext_gw_info['router_id'] = row['data'][0]
|
||||
for index in range(len(ext_gw_info_schema)):
|
||||
val = router_ext_gw_info[ext_gw_info_schema[index]['name']]
|
||||
if (str(row['data'][index]) != str(val)):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
if not test.call_until_true(func=_check_data,
|
||||
duration=200, sleep_for=10):
|
||||
raise exceptions.TimeoutException("Data did not converge in time "
|
||||
"or failure in server")
|
||||
|
||||
@test.attr(type='smoke')
|
||||
@test.services('network')
|
||||
def test_neutronv2_security_groups_table(self):
|
||||
security_groups = self.neutron_client.list_security_groups()
|
||||
security_groups_map = {}
|
||||
for security_group in security_groups['security_groups']:
|
||||
security_groups_map[security_group['id']] = security_group
|
||||
|
||||
sg_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'security_groups')['columns'])
|
||||
|
||||
def _check_data():
|
||||
security_groups = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'security_groups'))
|
||||
|
||||
# Validate security_group table
|
||||
for row in security_groups['results']:
|
||||
sg_row = security_groups_map[row['data'][0]]
|
||||
for index in range(len(sg_schema)):
|
||||
if (str(row['data'][index]) !=
|
||||
str(sg_row[sg_schema[index]['name']])):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
if not test.call_until_true(func=_check_data,
|
||||
duration=200, sleep_for=10):
|
||||
raise exceptions.TimeoutException("Data did not converge in time "
|
||||
"or failure in server")
|
||||
|
||||
@test.attr(type='smoke')
|
||||
@test.services('network')
|
||||
def test_neutronv2_security_group_rules_table(self):
|
||||
security_groups = self.neutron_client.list_security_groups()
|
||||
sgrs_map = {} # security_group_rules
|
||||
for sg in security_groups['security_groups']:
|
||||
for sgr in sg['security_group_rules']:
|
||||
sgrs_map[sgr['id']] = sgr
|
||||
|
||||
sgrs_schema = (
|
||||
self.admin_manager.congress_client.show_datasource_table_schema(
|
||||
'neutronv2', 'security_group_rules')['columns'])
|
||||
|
||||
def _check_data():
|
||||
security_group_rules = (
|
||||
self.admin_manager.congress_client.list_datasource_rows(
|
||||
'neutronv2', 'security_group_rules'))
|
||||
|
||||
# Validate security_group_rules table
|
||||
for row in security_group_rules['results']:
|
||||
sg_rule_row = sgrs_map[row['data'][1]]
|
||||
for index in range(len(sgrs_schema)):
|
||||
if (str(row['data'][index]) !=
|
||||
str(sg_rule_row[sgrs_schema[index]['name']])):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
if not test.call_until_true(func=_check_data,
|
||||
duration=200, sleep_for=10):
|
||||
raise exceptions.TimeoutException("Data did not converge in time "
|
||||
"or failure in server")
|
|
@ -45,16 +45,14 @@ class TestPolicyBasicOps(manager_congress.ScenarioPolicyBase):
|
|||
@test.services('compute', 'network')
|
||||
def test_policy_basic_op(self):
|
||||
self._setup_network_and_servers()
|
||||
body = {"rule": "port_security_group(port, security_group_name) :-"
|
||||
"neutron:ports(addr_pairs, security_groups, "
|
||||
"extra_dhcp_opts, binding_cap, status, name, "
|
||||
"admin_state_up, network_id, tenant_id, binding_vif, "
|
||||
"device_owner, mac_address, fixed_ips, port, "
|
||||
"device_id, binding_host_id1), "
|
||||
"neutron:ports.security_groups(security_groups, "
|
||||
"security_group_id), neutron:security_groups("
|
||||
"tenant_id2, security_group_name, desc2, "
|
||||
"security_group_id)"}
|
||||
body = {"rule": "port_security_group(id, security_group_name) "
|
||||
":-neutronv2:ports(id, tenant_id, name, network_id,"
|
||||
"mac_address, admin_state_up, status, device_id, "
|
||||
"device_owner),"
|
||||
"neutronv2:security_group_port_bindings(id, "
|
||||
"security_group_id), neutronv2:security_groups("
|
||||
"security_group_id, tenant_id1, security_group_name,"
|
||||
"description)"}
|
||||
results = self.admin_manager.congress_client.create_policy_rule(
|
||||
'classification', body)
|
||||
rule_id = results['id']
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[neutron]
|
||||
module: datasources/neutron_driver.py
|
||||
[neutronv2]
|
||||
module: datasources/neutronv2_driver.py
|
||||
username: admin
|
||||
password: password
|
||||
auth_url: http://127.0.0.1:5000/v2.0
|
||||
|
|
Loading…
Reference in New Issue