[wrappers] Move wrappers under plugins.openstack
Change-Id: I23cb04aea14e59d388ca8b34811f260ede79e116 Implements: blueprint split-plugins
This commit is contained in:
parent
c4666d5eef
commit
1e160f3fa1
@ -16,8 +16,8 @@
|
|||||||
from oslo_utils import uuidutils as uid
|
from oslo_utils import uuidutils as uid
|
||||||
|
|
||||||
from rally.benchmark.scenarios import base
|
from rally.benchmark.scenarios import base
|
||||||
from rally.benchmark.wrappers import network as network_wrapper
|
|
||||||
from rally.common import log as logging
|
from rally.common import log as logging
|
||||||
|
from rally.plugins.openstack.wrappers import network as network_wrapper
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -19,12 +19,12 @@ from rally.benchmark.scenarios import base
|
|||||||
from rally.benchmark.scenarios import utils as scenario_utils
|
from rally.benchmark.scenarios import utils as scenario_utils
|
||||||
from rally.benchmark import types as types
|
from rally.benchmark import types as types
|
||||||
from rally.benchmark import validation
|
from rally.benchmark import validation
|
||||||
from rally.benchmark.wrappers import network as network_wrapper
|
|
||||||
from rally.common import log as logging
|
from rally.common import log as logging
|
||||||
from rally import consts
|
from rally import consts
|
||||||
from rally import exceptions as rally_exceptions
|
from rally import exceptions as rally_exceptions
|
||||||
from rally.plugins.openstack.scenarios.cinder import utils as cinder_utils
|
from rally.plugins.openstack.scenarios.cinder import utils as cinder_utils
|
||||||
from rally.plugins.openstack.scenarios.nova import utils
|
from rally.plugins.openstack.scenarios.nova import utils
|
||||||
|
from rally.plugins.openstack.wrappers import network as network_wrapper
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -21,9 +21,8 @@ import six
|
|||||||
|
|
||||||
from rally.benchmark.scenarios import base
|
from rally.benchmark.scenarios import base
|
||||||
from rally.benchmark import utils as bench_utils
|
from rally.benchmark import utils as bench_utils
|
||||||
from rally.benchmark.wrappers import network as network_wrapper
|
|
||||||
from rally import exceptions
|
from rally import exceptions
|
||||||
|
from rally.plugins.openstack.wrappers import network as network_wrapper
|
||||||
|
|
||||||
NOVA_BENCHMARK_OPTS = []
|
NOVA_BENCHMARK_OPTS = []
|
||||||
option_names_and_defaults = [
|
option_names_and_defaults = [
|
||||||
|
@ -21,11 +21,11 @@ import six
|
|||||||
|
|
||||||
from rally.benchmark.scenarios import base
|
from rally.benchmark.scenarios import base
|
||||||
from rally.benchmark import utils as bench_utils
|
from rally.benchmark import utils as bench_utils
|
||||||
from rally.benchmark.wrappers import network as network_wrapper
|
|
||||||
from rally.common.i18n import _
|
from rally.common.i18n import _
|
||||||
from rally.common import log as logging
|
from rally.common import log as logging
|
||||||
from rally.common import sshutils
|
from rally.common import sshutils
|
||||||
from rally import exceptions
|
from rally import exceptions
|
||||||
|
from rally.plugins.openstack.wrappers import network as network_wrapper
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
0
rally/plugins/openstack/wrappers/__init__.py
Normal file
0
rally/plugins/openstack/wrappers/__init__.py
Normal file
217
rally/plugins/openstack/wrappers/keystone.py
Normal file
217
rally/plugins/openstack/wrappers/keystone.py
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
# Copyright 2014: Mirantis 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 abc
|
||||||
|
import collections
|
||||||
|
|
||||||
|
from keystoneclient import exceptions
|
||||||
|
import six
|
||||||
|
|
||||||
|
from rally.common import log as logging
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
Project = collections.namedtuple("Project", ["id", "name", "domain_id"])
|
||||||
|
User = collections.namedtuple("User",
|
||||||
|
["id", "name", "project_id", "domain_id"])
|
||||||
|
Service = collections.namedtuple("Service", ["id", "name"])
|
||||||
|
Role = collections.namedtuple("Role", ["id", "name"])
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class KeystoneWrapper(object):
|
||||||
|
def __init__(self, client):
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
def __getattr__(self, attr_name):
|
||||||
|
return getattr(self.client, attr_name)
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def create_project(self, project_name, domain_name="Default"):
|
||||||
|
"""Creates new project/tenant and return project object.
|
||||||
|
|
||||||
|
:param project_name: Name of project to be created.
|
||||||
|
:param domain_name: Name or id of domain where to create project, for
|
||||||
|
implementations that don't support domains this
|
||||||
|
argument must be None or 'Default'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def delete_project(self, project_id):
|
||||||
|
"""Deletes project."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def create_user(self, username, password, email=None, project_id=None,
|
||||||
|
domain_name="Default"):
|
||||||
|
"""Create user.
|
||||||
|
|
||||||
|
:param username: name of user
|
||||||
|
:param password: user password
|
||||||
|
:param project: user's default project
|
||||||
|
:param domain_name: Name or id of domain where to create project, for
|
||||||
|
implementations that don't support domains this
|
||||||
|
argument must be None or 'Default'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def delete_user(self, user_id):
|
||||||
|
"""Deletes user."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def list_users(self):
|
||||||
|
"""List all users."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def list_projects(self):
|
||||||
|
"""List all projects/tenants."""
|
||||||
|
|
||||||
|
def delete_service(self, service_id):
|
||||||
|
"""Deletes service."""
|
||||||
|
self.client.services.delete(service_id)
|
||||||
|
|
||||||
|
def list_services(self):
|
||||||
|
"""List all services."""
|
||||||
|
return map(KeystoneWrapper._wrap_service, self.client.services.list())
|
||||||
|
|
||||||
|
def delete_role(self, role_id):
|
||||||
|
"""Deletes role."""
|
||||||
|
self.client.roles.delete(role_id)
|
||||||
|
|
||||||
|
def list_roles(self):
|
||||||
|
"""List all roles."""
|
||||||
|
return map(KeystoneWrapper._wrap_role, self.client.roles.list())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _wrap_service(service):
|
||||||
|
return Service(id=service.id, name=service.name)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _wrap_role(role):
|
||||||
|
return Role(id=role.id, name=role.name)
|
||||||
|
|
||||||
|
|
||||||
|
class KeystoneV2Wrapper(KeystoneWrapper):
|
||||||
|
def _check_domain(self, domain_name):
|
||||||
|
if domain_name.lower() != "default":
|
||||||
|
raise NotImplementedError("Domain functionality not implemented "
|
||||||
|
"in Keystone v2")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _wrap_v2_tenant(tenant):
|
||||||
|
return Project(id=tenant.id, name=tenant.name, domain_id="default")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _wrap_v2_user(user):
|
||||||
|
return User(id=user.id, name=user.name,
|
||||||
|
project_id=getattr(user, "tenantId", None),
|
||||||
|
domain_id="default")
|
||||||
|
|
||||||
|
def create_project(self, project_name, domain_name="Default"):
|
||||||
|
self._check_domain(domain_name)
|
||||||
|
tenant = self.client.tenants.create(project_name)
|
||||||
|
return KeystoneV2Wrapper._wrap_v2_tenant(tenant)
|
||||||
|
|
||||||
|
def delete_project(self, project_id):
|
||||||
|
self.client.tenants.delete(project_id)
|
||||||
|
|
||||||
|
def create_user(self, username, password, email=None, project_id=None,
|
||||||
|
domain_name="Default"):
|
||||||
|
self._check_domain(domain_name)
|
||||||
|
user = self.client.users.create(username, password, email, project_id)
|
||||||
|
return KeystoneV2Wrapper._wrap_v2_user(user)
|
||||||
|
|
||||||
|
def delete_user(self, user_id):
|
||||||
|
self.client.users.delete(user_id)
|
||||||
|
|
||||||
|
def list_users(self):
|
||||||
|
return map(KeystoneV2Wrapper._wrap_v2_user, self.client.users.list())
|
||||||
|
|
||||||
|
def list_projects(self):
|
||||||
|
return map(KeystoneV2Wrapper._wrap_v2_tenant,
|
||||||
|
self.client.tenants.list())
|
||||||
|
|
||||||
|
|
||||||
|
class KeystoneV3Wrapper(KeystoneWrapper):
|
||||||
|
def _get_domain_id(self, domain_name_or_id):
|
||||||
|
try:
|
||||||
|
# First try to find domain by ID
|
||||||
|
return self.client.domains.get(domain_name_or_id).id
|
||||||
|
except exceptions.NotFound:
|
||||||
|
# Domain not found by ID, try to find it by name
|
||||||
|
domains = self.client.domains.list(name=domain_name_or_id)
|
||||||
|
if domains:
|
||||||
|
return domains[0].id
|
||||||
|
# Domain not found by name, raise original NotFound exception
|
||||||
|
raise
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _wrap_v3_project(project):
|
||||||
|
return Project(id=project.id, name=project.name,
|
||||||
|
domain_id=project.domain_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _wrap_v3_user(user):
|
||||||
|
# When user has default_project_id that is None user.default_project_id
|
||||||
|
# will raise AttributeError
|
||||||
|
project_id = getattr(user, "default_project_id", None)
|
||||||
|
return User(id=user.id, name=user.name, project_id=project_id,
|
||||||
|
domain_id=user.domain_id)
|
||||||
|
|
||||||
|
def create_project(self, project_name, domain_name="Default"):
|
||||||
|
domain_id = self._get_domain_id(domain_name)
|
||||||
|
project = self.client.projects.create(
|
||||||
|
name=project_name, domain=domain_id)
|
||||||
|
return KeystoneV3Wrapper._wrap_v3_project(project)
|
||||||
|
|
||||||
|
def delete_project(self, project_id):
|
||||||
|
self.client.projects.delete(project_id)
|
||||||
|
|
||||||
|
def create_user(self, username, password, email=None, project_id=None,
|
||||||
|
domain_name="Default"):
|
||||||
|
domain_id = self._get_domain_id(domain_name)
|
||||||
|
user = self.client.users.create(name=username, password=password,
|
||||||
|
default_project=project_id,
|
||||||
|
email=email, domain=domain_id)
|
||||||
|
for role in self.client.roles.list():
|
||||||
|
if "member" in role.name.lower():
|
||||||
|
self.client.roles.grant(role.id, user=user.id,
|
||||||
|
project=project_id)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
LOG.warning("Unable to set member role to created user.")
|
||||||
|
return KeystoneV3Wrapper._wrap_v3_user(user)
|
||||||
|
|
||||||
|
def delete_user(self, user_id):
|
||||||
|
self.client.users.delete(user_id)
|
||||||
|
|
||||||
|
def list_users(self):
|
||||||
|
return map(KeystoneV3Wrapper._wrap_v3_user, self.client.users.list())
|
||||||
|
|
||||||
|
def list_projects(self):
|
||||||
|
return map(KeystoneV3Wrapper._wrap_v3_project,
|
||||||
|
self.client.projects.list())
|
||||||
|
|
||||||
|
|
||||||
|
def wrap(client):
|
||||||
|
"""Returns keystone wrapper based on keystone client version."""
|
||||||
|
|
||||||
|
if client.version == "v2.0":
|
||||||
|
return KeystoneV2Wrapper(client)
|
||||||
|
elif client.version == "v3":
|
||||||
|
return KeystoneV3Wrapper(client)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError(
|
||||||
|
"Wrapper for version %s is not implemented." % client.version)
|
407
rally/plugins/openstack/wrappers/network.py
Normal file
407
rally/plugins/openstack/wrappers/network.py
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
# Copyright 2014: Mirantis 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 abc
|
||||||
|
|
||||||
|
import netaddr
|
||||||
|
import six
|
||||||
|
|
||||||
|
from rally.benchmark import utils as bench_utils
|
||||||
|
from rally.common.i18n import _
|
||||||
|
from rally.common import log as logging
|
||||||
|
from rally.common import utils
|
||||||
|
from rally import consts
|
||||||
|
from rally import exceptions
|
||||||
|
|
||||||
|
from neutronclient.common import exceptions as neutron_exceptions
|
||||||
|
from novaclient import exceptions as nova_exceptions
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
cidr_incr = utils.RAMInt()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_cidr(start_cidr="10.2.0.0/24"):
|
||||||
|
"""Generate next CIDR for network or subnet, without IP overlapping.
|
||||||
|
|
||||||
|
This is process and thread safe, because `cidr_incr' points to
|
||||||
|
value stored directly in RAM. This guarantees that CIDRs will be
|
||||||
|
serial and unique even under hard multiprocessing/threading load.
|
||||||
|
|
||||||
|
:param start_cidr: start CIDR str
|
||||||
|
:returns: next available CIDR str
|
||||||
|
"""
|
||||||
|
cidr = str(netaddr.IPNetwork(start_cidr).next(next(cidr_incr)))
|
||||||
|
LOG.debug("CIDR generated: %s" % cidr)
|
||||||
|
return cidr
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkWrapperException(exceptions.RallyException):
|
||||||
|
msg_fmt = _("%(message)s")
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class NetworkWrapper(object):
|
||||||
|
"""Base class for network service implementations.
|
||||||
|
|
||||||
|
We actually have two network services implementations, with different API:
|
||||||
|
NovaNetwork and Neutron. The idea is (at least to try) to use unified
|
||||||
|
service, which hides most differences and routines behind the scenes.
|
||||||
|
This allows to significantly re-use and simplify code.
|
||||||
|
"""
|
||||||
|
START_CIDR = "10.2.0.0/24"
|
||||||
|
SERVICE_IMPL = None
|
||||||
|
|
||||||
|
def __init__(self, clients, config=None):
|
||||||
|
if hasattr(clients, self.SERVICE_IMPL):
|
||||||
|
self.client = getattr(clients, self.SERVICE_IMPL)()
|
||||||
|
else:
|
||||||
|
self.client = clients(self.SERVICE_IMPL)
|
||||||
|
self.config = config or {}
|
||||||
|
self.start_cidr = self.config.get("start_cidr", self.START_CIDR)
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def create_network(self):
|
||||||
|
"""Create network."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def delete_network(self):
|
||||||
|
"""Delete network."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def list_networks(self):
|
||||||
|
"""List networks."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def create_floating_ip(self):
|
||||||
|
"""Create floating IP."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def delete_floating_ip(self):
|
||||||
|
"""Delete floating IP."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def supports_security_group(self):
|
||||||
|
"""Checks whether security group is supported."""
|
||||||
|
|
||||||
|
|
||||||
|
class NovaNetworkWrapper(NetworkWrapper):
|
||||||
|
SERVICE_IMPL = consts.Service.NOVA
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
super(NovaNetworkWrapper, self).__init__(*args)
|
||||||
|
self.skip_cidrs = [n.cidr for n in self.client.networks.list()]
|
||||||
|
|
||||||
|
def _generate_cidr(self):
|
||||||
|
cidr = generate_cidr(start_cidr=self.start_cidr)
|
||||||
|
while cidr in self.skip_cidrs:
|
||||||
|
cidr = generate_cidr(start_cidr=self.start_cidr)
|
||||||
|
return cidr
|
||||||
|
|
||||||
|
def create_network(self, tenant_id, **kwargs):
|
||||||
|
"""Create network.
|
||||||
|
|
||||||
|
:param tenant_id: str, tenant ID
|
||||||
|
:param **kwargs: for compatibility, not used here
|
||||||
|
:returns: dict, network data
|
||||||
|
"""
|
||||||
|
cidr = self._generate_cidr()
|
||||||
|
label = utils.generate_random_name("rally_net_")
|
||||||
|
network = self.client.networks.create(
|
||||||
|
tenant_id=tenant_id, cidr=cidr, label=label)
|
||||||
|
return {"id": network.id,
|
||||||
|
"cidr": network.cidr,
|
||||||
|
"name": network.label,
|
||||||
|
"status": "ACTIVE",
|
||||||
|
"external": False,
|
||||||
|
"tenant_id": tenant_id}
|
||||||
|
|
||||||
|
def delete_network(self, network):
|
||||||
|
return self.client.networks.delete(network["id"])
|
||||||
|
|
||||||
|
def list_networks(self):
|
||||||
|
return self.client.networks.list()
|
||||||
|
|
||||||
|
def create_floating_ip(self, ext_network=None, **kwargs):
|
||||||
|
"""Allocate a floating ip from the given nova-network pool
|
||||||
|
|
||||||
|
:param ext_network: name or external network, str
|
||||||
|
:param **kwargs: for compatibility, not used here
|
||||||
|
:returns: floating IP dict
|
||||||
|
"""
|
||||||
|
if not ext_network:
|
||||||
|
try:
|
||||||
|
ext_network = self.client.floating_ip_pools.list()[0].name
|
||||||
|
except IndexError:
|
||||||
|
raise NetworkWrapperException("No floating IP pools found")
|
||||||
|
fip = self.client.floating_ips.create(ext_network)
|
||||||
|
return {"id": fip.id, "ip": fip.ip}
|
||||||
|
|
||||||
|
def _get_floating_ip(self, fip_id, do_raise=False):
|
||||||
|
try:
|
||||||
|
fip = self.client.floating_ips.get(fip_id)
|
||||||
|
except nova_exceptions.NotFound:
|
||||||
|
if not do_raise:
|
||||||
|
return None
|
||||||
|
raise exceptions.GetResourceNotFound(
|
||||||
|
resource="Floating IP %s" % fip_id)
|
||||||
|
return fip.id
|
||||||
|
|
||||||
|
def delete_floating_ip(self, fip_id, wait=False):
|
||||||
|
"""Delete floating IP.
|
||||||
|
|
||||||
|
:param fip_id: int floating IP id
|
||||||
|
:param wait: if True then wait to return until floating ip is deleted
|
||||||
|
"""
|
||||||
|
self.client.floating_ips.delete(fip_id)
|
||||||
|
if not wait:
|
||||||
|
return
|
||||||
|
bench_utils.wait_for_delete(
|
||||||
|
fip_id,
|
||||||
|
update_resource=lambda i: self._get_floating_ip(i, do_raise=True))
|
||||||
|
|
||||||
|
def supports_security_group(self):
|
||||||
|
"""Check whether security group is supported
|
||||||
|
|
||||||
|
:return: result tuple. Always (True, "") for nova-network.
|
||||||
|
:rtype: (bool, string)
|
||||||
|
"""
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
|
||||||
|
class NeutronWrapper(NetworkWrapper):
|
||||||
|
SERVICE_IMPL = consts.Service.NEUTRON
|
||||||
|
SUBNET_IP_VERSION = 4
|
||||||
|
|
||||||
|
@property
|
||||||
|
def external_networks(self):
|
||||||
|
return self.client.list_networks(**{
|
||||||
|
"router:external": True})["networks"]
|
||||||
|
|
||||||
|
def get_network(self, net_id=None, name=None):
|
||||||
|
net = None
|
||||||
|
try:
|
||||||
|
if net_id:
|
||||||
|
net = self.client.show_network(net_id)["network"]
|
||||||
|
else:
|
||||||
|
for net in self.client.list_networks(name=name)["networks"]:
|
||||||
|
break
|
||||||
|
return {"id": net["id"],
|
||||||
|
"name": net["name"],
|
||||||
|
"tenant_id": net["tenant_id"],
|
||||||
|
"status": net["status"],
|
||||||
|
"external": net["router:external"],
|
||||||
|
"subnets": net["subnets"],
|
||||||
|
"router_id": None}
|
||||||
|
except (TypeError, neutron_exceptions.NeutronClientException):
|
||||||
|
raise NetworkWrapperException(
|
||||||
|
"Network not found: %s" % (name or net_id))
|
||||||
|
|
||||||
|
def create_router(self, external=False, **kwargs):
|
||||||
|
"""Create neutron router.
|
||||||
|
|
||||||
|
:param external: bool, whether to set setup external_gateway_info
|
||||||
|
:param **kwargs: POST /v2.0/routers request options
|
||||||
|
:returns: neutron router dict
|
||||||
|
"""
|
||||||
|
if "name" not in kwargs:
|
||||||
|
kwargs["name"] = utils.generate_random_name("rally_router_")
|
||||||
|
|
||||||
|
if external and "external_gateway_info" not in kwargs:
|
||||||
|
for net in self.external_networks:
|
||||||
|
kwargs["external_gateway_info"] = {
|
||||||
|
"network_id": net["id"], "enable_snat": True}
|
||||||
|
return self.client.create_router({"router": kwargs})["router"]
|
||||||
|
|
||||||
|
def _generate_cidr(self):
|
||||||
|
# TODO(amaretskiy): Generate CIDRs unique for network, not cluster
|
||||||
|
return generate_cidr(start_cidr=self.start_cidr)
|
||||||
|
|
||||||
|
def create_network(self, tenant_id, **kwargs):
|
||||||
|
"""Create network.
|
||||||
|
|
||||||
|
:param tenant_id: str, tenant ID
|
||||||
|
:param **kwargs: extra options
|
||||||
|
:returns: dict, network data
|
||||||
|
"""
|
||||||
|
network_args = {
|
||||||
|
"network": {
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
"name": utils.generate_random_name("rally_net_")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
network = self.client.create_network(network_args)["network"]
|
||||||
|
|
||||||
|
router = None
|
||||||
|
if kwargs.get("add_router", False):
|
||||||
|
router = self.create_router(external=True, tenant_id=tenant_id)
|
||||||
|
|
||||||
|
subnets = []
|
||||||
|
subnets_num = kwargs.get("subnets_num", 0)
|
||||||
|
for i in range(subnets_num):
|
||||||
|
subnet_args = {
|
||||||
|
"subnet": {
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
"network_id": network["id"],
|
||||||
|
"name": utils.generate_random_name("rally_subnet_"),
|
||||||
|
"ip_version": self.SUBNET_IP_VERSION,
|
||||||
|
"cidr": self._generate_cidr(),
|
||||||
|
"enable_dhcp": True,
|
||||||
|
"dns_nameservers": kwargs.get("dns_nameservers",
|
||||||
|
["8.8.8.8", "8.8.4.4"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subnet = self.client.create_subnet(subnet_args)["subnet"]
|
||||||
|
subnets.append(subnet["id"])
|
||||||
|
|
||||||
|
if router:
|
||||||
|
self.client.add_interface_router(router["id"],
|
||||||
|
{"subnet_id": subnet["id"]})
|
||||||
|
|
||||||
|
return {"id": network["id"],
|
||||||
|
"name": network["name"],
|
||||||
|
"status": network["status"],
|
||||||
|
"subnets": subnets,
|
||||||
|
"external": network.get("router:external", False),
|
||||||
|
"router_id": router and router["id"] or None,
|
||||||
|
"tenant_id": tenant_id}
|
||||||
|
|
||||||
|
def delete_network(self, network):
|
||||||
|
net_dhcps = self.client.list_dhcp_agent_hosting_networks(
|
||||||
|
network["id"])["agents"]
|
||||||
|
for net_dhcp in net_dhcps:
|
||||||
|
self.client.remove_network_from_dhcp_agent(net_dhcp["id"],
|
||||||
|
network["id"])
|
||||||
|
router_id = network["router_id"]
|
||||||
|
if router_id:
|
||||||
|
self.client.remove_gateway_router(router_id)
|
||||||
|
for subnet_id in network["subnets"]:
|
||||||
|
self.client.remove_interface_router(router_id,
|
||||||
|
{"subnet_id": subnet_id})
|
||||||
|
self.client.delete_router(router_id)
|
||||||
|
|
||||||
|
for port in self.client.list_ports(network_id=network["id"])["ports"]:
|
||||||
|
self.client.delete_port(port["id"])
|
||||||
|
|
||||||
|
for subnet_id in network["subnets"]:
|
||||||
|
self._delete_subnet(subnet_id)
|
||||||
|
|
||||||
|
return self.client.delete_network(network["id"])
|
||||||
|
|
||||||
|
def _delete_subnet(self, subnet_id):
|
||||||
|
self.client.delete_subnet(subnet_id)
|
||||||
|
|
||||||
|
def list_networks(self):
|
||||||
|
return self.client.list_networks()["networks"]
|
||||||
|
|
||||||
|
def create_port(self, network_id, **kwargs):
|
||||||
|
"""Create neutron port.
|
||||||
|
|
||||||
|
:param network_id: neutron network id
|
||||||
|
:param **kwargs: POST /v2.0/ports request options
|
||||||
|
:returns: neutron port dict
|
||||||
|
"""
|
||||||
|
kwargs["network_id"] = network_id
|
||||||
|
if "name" not in kwargs:
|
||||||
|
kwargs["name"] = utils.generate_random_name("rally_port_")
|
||||||
|
return self.client.create_port({"port": kwargs})["port"]
|
||||||
|
|
||||||
|
def create_floating_ip(self, ext_network=None, int_network=None,
|
||||||
|
tenant_id=None, port_id=None, **kwargs):
|
||||||
|
"""Create Neutron floating IP.
|
||||||
|
|
||||||
|
:param ext_network: floating network name or dict
|
||||||
|
:param int_network: fixed network name or dict
|
||||||
|
:param tenant_id str tenant id
|
||||||
|
:param port_id: str port id
|
||||||
|
:param **kwargs: for compatibility, not used here
|
||||||
|
:returns: floating IP dict
|
||||||
|
"""
|
||||||
|
if not tenant_id:
|
||||||
|
raise ValueError("Missed tenant_id")
|
||||||
|
|
||||||
|
net_id = None
|
||||||
|
if type(ext_network) is dict:
|
||||||
|
net_id = ext_network["id"]
|
||||||
|
elif ext_network:
|
||||||
|
ext_net = self.get_network(name=ext_network)
|
||||||
|
if not ext_net["external"]:
|
||||||
|
raise NetworkWrapperException("Network is not external: %s"
|
||||||
|
% ext_network)
|
||||||
|
net_id = ext_net["id"]
|
||||||
|
else:
|
||||||
|
ext_networks = self.external_networks
|
||||||
|
if not ext_networks:
|
||||||
|
raise NetworkWrapperException(
|
||||||
|
"Failed to allocate floating IP: "
|
||||||
|
"no external networks found")
|
||||||
|
net_id = ext_networks[0]["id"]
|
||||||
|
|
||||||
|
if not port_id:
|
||||||
|
if type(int_network) is dict:
|
||||||
|
port_id = self.create_port(int_network["id"])["id"]
|
||||||
|
elif int_network:
|
||||||
|
int_net = self.get_network(name=int_network)
|
||||||
|
if int_net["external"]:
|
||||||
|
raise NetworkWrapperException("Network is external: %s"
|
||||||
|
% int_network)
|
||||||
|
port_id = self.create_port(int_net["id"])["id"]
|
||||||
|
kwargs = {"floatingip": {"floating_network_id": net_id},
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
"port_id": port_id}
|
||||||
|
|
||||||
|
fip = self.client.create_floatingip(kwargs)["floatingip"]
|
||||||
|
return {"id": fip["id"], "ip": fip["floating_ip_address"]}
|
||||||
|
|
||||||
|
def delete_floating_ip(self, fip_id, **kwargs):
|
||||||
|
"""Delete floating IP.
|
||||||
|
|
||||||
|
:param fip_id: int floating IP id
|
||||||
|
:param **kwargs: for compatibility, not used here
|
||||||
|
"""
|
||||||
|
self.client.delete_floatingip(fip_id)
|
||||||
|
|
||||||
|
def supports_security_group(self):
|
||||||
|
"""Check whether security group is supported
|
||||||
|
|
||||||
|
:return: result tuple
|
||||||
|
:rtype: (bool, string)
|
||||||
|
"""
|
||||||
|
extensions = self.client.list_extensions().get("extensions", [])
|
||||||
|
use_sg = any(ext.get("alias") == "security-group"
|
||||||
|
for ext in extensions)
|
||||||
|
if use_sg:
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
return False, _("neutron driver does not support security groups")
|
||||||
|
|
||||||
|
|
||||||
|
def wrap(clients, config=None):
|
||||||
|
"""Returns available network wrapper instance.
|
||||||
|
|
||||||
|
:param clients: rally.osclients.Clients instance
|
||||||
|
:param config: task config dict
|
||||||
|
:returns: NetworkWrapper subclass instance
|
||||||
|
"""
|
||||||
|
if hasattr(clients, "services"):
|
||||||
|
services = clients.services()
|
||||||
|
else:
|
||||||
|
services = clients("services")
|
||||||
|
|
||||||
|
if consts.Service.NEUTRON in services.values():
|
||||||
|
return NeutronWrapper(clients, config)
|
||||||
|
return NovaNetworkWrapper(clients, config)
|
0
tests/unit/plugins/openstack/wrappers/__init__.py
Normal file
0
tests/unit/plugins/openstack/wrappers/__init__.py
Normal file
208
tests/unit/plugins/openstack/wrappers/test_keystone.py
Normal file
208
tests/unit/plugins/openstack/wrappers/test_keystone.py
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
# Copyright 2014: Mirantis 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.
|
||||||
|
|
||||||
|
from keystoneclient import exceptions
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from rally.plugins.openstack.wrappers import keystone
|
||||||
|
from tests.unit import test
|
||||||
|
|
||||||
|
|
||||||
|
class KeystoneWrapperTestBase(object):
|
||||||
|
def test_list_services(self):
|
||||||
|
service = mock.MagicMock()
|
||||||
|
service.id = "fake_id"
|
||||||
|
service.name = "Foobar"
|
||||||
|
service.extra_field = "extra_field"
|
||||||
|
self.client.services.list.return_value = [service]
|
||||||
|
result = list(self.wrapped_client.list_services())
|
||||||
|
self.assertEqual([("fake_id", "Foobar")], result)
|
||||||
|
self.assertEqual("fake_id", result[0].id)
|
||||||
|
self.assertEqual("Foobar", result[0].name)
|
||||||
|
self.assertFalse(hasattr(result[0], "extra_field"))
|
||||||
|
|
||||||
|
def test_wrap(self):
|
||||||
|
client = mock.MagicMock()
|
||||||
|
client.version = "dummy"
|
||||||
|
self.assertRaises(NotImplementedError, keystone.wrap, client)
|
||||||
|
|
||||||
|
def test_delete_service(self):
|
||||||
|
self.wrapped_client.delete_service("fake_id")
|
||||||
|
self.client.services.delete.assert_called_once_with("fake_id")
|
||||||
|
|
||||||
|
def test_list_roles(self):
|
||||||
|
role = mock.MagicMock()
|
||||||
|
role.id = "fake_id"
|
||||||
|
role.name = "Foobar"
|
||||||
|
role.extra_field = "extra_field"
|
||||||
|
self.client.roles.list.return_value = [role]
|
||||||
|
result = list(self.wrapped_client.list_roles())
|
||||||
|
self.assertEqual([("fake_id", "Foobar")], result)
|
||||||
|
self.assertEqual("fake_id", result[0].id)
|
||||||
|
self.assertEqual("Foobar", result[0].name)
|
||||||
|
self.assertFalse(hasattr(result[0], "extra_field"))
|
||||||
|
|
||||||
|
def test_delete_role(self):
|
||||||
|
self.wrapped_client.delete_role("fake_id")
|
||||||
|
self.client.roles.delete.assert_called_once_with("fake_id")
|
||||||
|
|
||||||
|
|
||||||
|
class KeystoneV2WrapperTestCase(test.TestCase, KeystoneWrapperTestBase):
|
||||||
|
def setUp(self):
|
||||||
|
super(KeystoneV2WrapperTestCase, self).setUp()
|
||||||
|
self.client = mock.MagicMock()
|
||||||
|
self.client.version = "v2.0"
|
||||||
|
self.wrapped_client = keystone.wrap(self.client)
|
||||||
|
|
||||||
|
def test_create_project(self):
|
||||||
|
self.wrapped_client.create_project("Foobar")
|
||||||
|
self.client.tenants.create.assert_called_once_with("Foobar")
|
||||||
|
|
||||||
|
def test_create_project_in_non_default_domain_fail(self):
|
||||||
|
self.assertRaises(
|
||||||
|
NotImplementedError, self.wrapped_client.create_project,
|
||||||
|
"Foobar", "non-default-domain")
|
||||||
|
|
||||||
|
def test_delete_project(self):
|
||||||
|
self.wrapped_client.delete_project("fake_id")
|
||||||
|
self.client.tenants.delete.assert_called_once_with("fake_id")
|
||||||
|
|
||||||
|
def test_list_projects(self):
|
||||||
|
tenant = mock.MagicMock()
|
||||||
|
tenant.id = "fake_id"
|
||||||
|
tenant.name = "Foobar"
|
||||||
|
tenant.extra_field = "extra_field"
|
||||||
|
self.client.tenants.list.return_value = [tenant]
|
||||||
|
result = list(self.wrapped_client.list_projects())
|
||||||
|
self.assertEqual([("fake_id", "Foobar", "default")], result)
|
||||||
|
self.assertEqual("fake_id", result[0].id)
|
||||||
|
self.assertEqual("Foobar", result[0].name)
|
||||||
|
self.assertEqual("default", result[0].domain_id)
|
||||||
|
self.assertFalse(hasattr(result[0], "extra_field"))
|
||||||
|
|
||||||
|
def test_create_user(self):
|
||||||
|
self.wrapped_client.create_user("foo", "bar", email="foo@bar.com",
|
||||||
|
project_id="tenant_id",
|
||||||
|
domain_name="default")
|
||||||
|
self.client.users.create.assert_called_once_with(
|
||||||
|
"foo", "bar", "foo@bar.com", "tenant_id")
|
||||||
|
|
||||||
|
def test_create_user_in_non_default_domain_fail(self):
|
||||||
|
self.assertRaises(
|
||||||
|
NotImplementedError, self.wrapped_client.create_user,
|
||||||
|
"foo", "bar", email="foo@bar.com", project_id="tenant_id",
|
||||||
|
domain_name="non-default-domain")
|
||||||
|
|
||||||
|
def test_delete_user(self):
|
||||||
|
self.wrapped_client.delete_user("fake_id")
|
||||||
|
self.client.users.delete.assert_called_once_with("fake_id")
|
||||||
|
|
||||||
|
def test_list_users(self):
|
||||||
|
user = mock.MagicMock()
|
||||||
|
user.id = "fake_id"
|
||||||
|
user.name = "foo"
|
||||||
|
user.tenantId = "tenant_id"
|
||||||
|
user.extra_field = "extra_field"
|
||||||
|
self.client.users.list.return_value = [user]
|
||||||
|
result = list(self.wrapped_client.list_users())
|
||||||
|
self.assertEqual([("fake_id", "foo", "tenant_id", "default")], result)
|
||||||
|
self.assertEqual("fake_id", result[0].id)
|
||||||
|
self.assertEqual("foo", result[0].name)
|
||||||
|
self.assertEqual("tenant_id", result[0].project_id)
|
||||||
|
self.assertEqual("default", result[0].domain_id)
|
||||||
|
self.assertFalse(hasattr(result[0], "extra_field"))
|
||||||
|
|
||||||
|
|
||||||
|
class KeystoneV3WrapperTestCase(test.TestCase, KeystoneWrapperTestBase):
|
||||||
|
def setUp(self):
|
||||||
|
super(KeystoneV3WrapperTestCase, self).setUp()
|
||||||
|
self.client = mock.MagicMock()
|
||||||
|
self.client.version = "v3"
|
||||||
|
self.wrapped_client = keystone.wrap(self.client)
|
||||||
|
self.client.domains.get.side_effect = exceptions.NotFound
|
||||||
|
self.client.domains.list.return_value = [
|
||||||
|
mock.MagicMock(id="domain_id")]
|
||||||
|
|
||||||
|
def test_create_project(self):
|
||||||
|
self.wrapped_client.create_project("Foobar", "domain")
|
||||||
|
self.client.projects.create.assert_called_once_with(
|
||||||
|
name="Foobar", domain="domain_id")
|
||||||
|
|
||||||
|
def test_create_project_with_non_existing_domain_fail(self):
|
||||||
|
self.client.domains.list.return_value = []
|
||||||
|
self.assertRaises(exceptions.NotFound,
|
||||||
|
self.wrapped_client.create_project,
|
||||||
|
"Foobar", "non-existing-domain")
|
||||||
|
|
||||||
|
def test_delete_project(self):
|
||||||
|
self.wrapped_client.delete_project("fake_id")
|
||||||
|
self.client.projects.delete.assert_called_once_with("fake_id")
|
||||||
|
|
||||||
|
def test_list_projects(self):
|
||||||
|
project = mock.MagicMock()
|
||||||
|
project.id = "fake_id"
|
||||||
|
project.name = "Foobar"
|
||||||
|
project.domain_id = "domain_id"
|
||||||
|
project.extra_field = "extra_field"
|
||||||
|
self.client.projects.list.return_value = [project]
|
||||||
|
result = list(self.wrapped_client.list_projects())
|
||||||
|
self.assertEqual([("fake_id", "Foobar", "domain_id")], result)
|
||||||
|
self.assertEqual("fake_id", result[0].id)
|
||||||
|
self.assertEqual("Foobar", result[0].name)
|
||||||
|
self.assertEqual("domain_id", result[0].domain_id)
|
||||||
|
self.assertFalse(hasattr(result[0], "extra_field"))
|
||||||
|
|
||||||
|
def test_create_user(self):
|
||||||
|
fake_role = mock.MagicMock(id="fake_role_id")
|
||||||
|
fake_role.name = "__member__"
|
||||||
|
self.client.roles.list.return_value = [fake_role]
|
||||||
|
self.client.users.create.return_value = mock.MagicMock(
|
||||||
|
id="fake_user_id")
|
||||||
|
|
||||||
|
self.wrapped_client.create_user(
|
||||||
|
"foo", "bar", email="foo@bar.com",
|
||||||
|
project_id="project_id", domain_name="domain")
|
||||||
|
self.client.users.create.assert_called_once_with(
|
||||||
|
name="foo", password="bar",
|
||||||
|
email="foo@bar.com", default_project="project_id",
|
||||||
|
domain="domain_id")
|
||||||
|
|
||||||
|
def test_create_user_with_non_existing_domain_fail(self):
|
||||||
|
self.client.domains.list.return_value = []
|
||||||
|
self.assertRaises(exceptions.NotFound,
|
||||||
|
self.wrapped_client.create_user, "foo", "bar",
|
||||||
|
email="foo@bar.com", project_id="project_id",
|
||||||
|
domain_name="non-existing-domain")
|
||||||
|
|
||||||
|
def test_delete_user(self):
|
||||||
|
self.wrapped_client.delete_user("fake_id")
|
||||||
|
self.client.users.delete.assert_called_once_with("fake_id")
|
||||||
|
|
||||||
|
def test_list_users(self):
|
||||||
|
user = mock.MagicMock()
|
||||||
|
user.id = "fake_id"
|
||||||
|
user.name = "foo"
|
||||||
|
user.default_project_id = "project_id"
|
||||||
|
user.domain_id = "domain_id"
|
||||||
|
user.extra_field = "extra_field"
|
||||||
|
self.client.users.list.return_value = [user]
|
||||||
|
result = list(self.wrapped_client.list_users())
|
||||||
|
self.assertEqual([("fake_id", "foo", "project_id", "domain_id")],
|
||||||
|
result)
|
||||||
|
self.assertEqual("fake_id", result[0].id)
|
||||||
|
self.assertEqual("foo", result[0].name)
|
||||||
|
self.assertEqual("project_id", result[0].project_id)
|
||||||
|
self.assertEqual("domain_id", result[0].domain_id)
|
||||||
|
self.assertFalse(hasattr(result[0], "extra_field"))
|
494
tests/unit/plugins/openstack/wrappers/test_network.py
Normal file
494
tests/unit/plugins/openstack/wrappers/test_network.py
Normal file
@ -0,0 +1,494 @@
|
|||||||
|
# Copyright 2014: Mirantis 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 mock
|
||||||
|
|
||||||
|
from rally import consts
|
||||||
|
from rally import exceptions
|
||||||
|
from rally.plugins.openstack.wrappers import network
|
||||||
|
from tests.unit import test
|
||||||
|
|
||||||
|
from neutronclient.common import exceptions as neutron_exceptions
|
||||||
|
from novaclient import exceptions as nova_exceptions
|
||||||
|
|
||||||
|
SVC = "rally.plugins.openstack.wrappers.network."
|
||||||
|
|
||||||
|
|
||||||
|
class NovaNetworkWrapperTestCase(test.TestCase):
|
||||||
|
|
||||||
|
class Net(object):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.__dict__.update(kwargs)
|
||||||
|
|
||||||
|
def get_wrapper(self, *skip_cidrs, **kwargs):
|
||||||
|
mock_clients = mock.Mock()
|
||||||
|
mock_clients.nova.return_value.networks.list.return_value = [
|
||||||
|
self.Net(cidr=cidr) for cidr in skip_cidrs]
|
||||||
|
return network.NovaNetworkWrapper(mock_clients, kwargs)
|
||||||
|
|
||||||
|
def test__init__(self):
|
||||||
|
skip_cidrs = ["foo_cidr", "bar_cidr"]
|
||||||
|
service = self.get_wrapper(*skip_cidrs)
|
||||||
|
self.assertEqual(service.skip_cidrs, skip_cidrs)
|
||||||
|
service.client.networks.list.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch("rally.plugins.openstack.wrappers.network.generate_cidr")
|
||||||
|
def test__generate_cidr(self, mock_cidr):
|
||||||
|
skip_cidrs = [5, 7]
|
||||||
|
cidrs = iter(range(7))
|
||||||
|
mock_cidr.side_effect = lambda start_cidr: start_cidr + next(cidrs)
|
||||||
|
service = self.get_wrapper(*skip_cidrs, start_cidr=3)
|
||||||
|
self.assertEqual(service._generate_cidr(), 3)
|
||||||
|
self.assertEqual(service._generate_cidr(), 4)
|
||||||
|
self.assertEqual(service._generate_cidr(), 6) # 5 is skipped
|
||||||
|
self.assertEqual(service._generate_cidr(), 8) # 7 is skipped
|
||||||
|
self.assertEqual(service._generate_cidr(), 9)
|
||||||
|
self.assertEqual(mock_cidr.mock_calls, [mock.call(start_cidr=3)] * 7)
|
||||||
|
|
||||||
|
@mock.patch("rally.common.utils.generate_random_name",
|
||||||
|
return_value="foo_name")
|
||||||
|
def test_create_network(self, mock_name):
|
||||||
|
service = self.get_wrapper()
|
||||||
|
service.client.networks.create.side_effect = (
|
||||||
|
lambda **kwargs: self.Net(id="foo_id", **kwargs))
|
||||||
|
service._generate_cidr = mock.Mock(return_value="foo_cidr")
|
||||||
|
net = service.create_network("foo_tenant", bar="spam")
|
||||||
|
self.assertEqual(net, {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"cidr": "foo_cidr",
|
||||||
|
"status": "ACTIVE",
|
||||||
|
"external": False,
|
||||||
|
"tenant_id": "foo_tenant"})
|
||||||
|
mock_name.assert_called_once_with("rally_net_")
|
||||||
|
service._generate_cidr.assert_called_once_with()
|
||||||
|
service.client.networks.create.assert_called_once_with(
|
||||||
|
tenant_id="foo_tenant", cidr="foo_cidr", label="foo_name")
|
||||||
|
|
||||||
|
def test_delete_network(self):
|
||||||
|
service = self.get_wrapper()
|
||||||
|
service.client.networks.delete.return_value = "foo_deleted"
|
||||||
|
self.assertEqual(service.delete_network({"id": "foo_id"}),
|
||||||
|
"foo_deleted")
|
||||||
|
service.client.networks.delete.assert_called_once_with("foo_id")
|
||||||
|
|
||||||
|
def test_list_networks(self):
|
||||||
|
service = self.get_wrapper()
|
||||||
|
service.client.networks.list.return_value = "foo_list"
|
||||||
|
service.client.networks.list.reset_mock()
|
||||||
|
self.assertEqual(service.list_networks(), "foo_list")
|
||||||
|
service.client.networks.list.assert_called_once_with()
|
||||||
|
|
||||||
|
def test__get_floating_ip(self):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
wrap.client.floating_ips.get.return_value = mock.Mock(id="foo_id",
|
||||||
|
ip="foo_ip")
|
||||||
|
fip = wrap._get_floating_ip("fip_id")
|
||||||
|
wrap.client.floating_ips.get.assert_called_once_with("fip_id")
|
||||||
|
self.assertEqual(fip, "foo_id")
|
||||||
|
|
||||||
|
wrap.client.floating_ips.get.side_effect = (
|
||||||
|
nova_exceptions.NotFound(""))
|
||||||
|
self.assertIsNone(wrap._get_floating_ip("fip_id"))
|
||||||
|
|
||||||
|
self.assertRaises(exceptions.GetResourceNotFound,
|
||||||
|
wrap._get_floating_ip, "fip_id", do_raise=True)
|
||||||
|
|
||||||
|
def test_create_floating_ip(self):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
wrap.client.floating_ips.create.return_value = mock.Mock(id="foo_id",
|
||||||
|
ip="foo_ip")
|
||||||
|
fip = wrap.create_floating_ip(ext_network="bar_net", bar="spam")
|
||||||
|
self.assertEqual(fip, {"ip": "foo_ip", "id": "foo_id"})
|
||||||
|
wrap.client.floating_ips.create.assert_called_once_with("bar_net")
|
||||||
|
|
||||||
|
net = mock.Mock()
|
||||||
|
net.name = "foo_net"
|
||||||
|
wrap.client.floating_ip_pools.list.return_value = [net]
|
||||||
|
fip = wrap.create_floating_ip()
|
||||||
|
self.assertEqual(fip, {"ip": "foo_ip", "id": "foo_id"})
|
||||||
|
wrap.client.floating_ips.create.assert_called_with("foo_net")
|
||||||
|
|
||||||
|
def test_delete_floating_ip(self):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
fip_found = iter(range(3))
|
||||||
|
|
||||||
|
def get_fip(*args, **kwargs):
|
||||||
|
for i in fip_found:
|
||||||
|
return "fip_id"
|
||||||
|
raise exceptions.GetResourceNotFound
|
||||||
|
wrap._get_floating_ip = mock.Mock(side_effect=get_fip)
|
||||||
|
|
||||||
|
wrap.delete_floating_ip("fip_id")
|
||||||
|
wrap.client.floating_ips.delete.assert_called_once_with("fip_id")
|
||||||
|
self.assertFalse(wrap._get_floating_ip.called)
|
||||||
|
|
||||||
|
wrap.delete_floating_ip("fip_id", wait=True)
|
||||||
|
self.assertEqual(
|
||||||
|
[mock.call("fip_id", do_raise=True)] * 4,
|
||||||
|
wrap._get_floating_ip.mock_calls)
|
||||||
|
|
||||||
|
def test_supports_secgroup(self):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
self.assertTrue(wrap.supports_security_group()[0])
|
||||||
|
|
||||||
|
|
||||||
|
class NeutronWrapperTestCase(test.TestCase):
|
||||||
|
def get_wrapper(self, *skip_cidrs, **kwargs):
|
||||||
|
return network.NeutronWrapper(mock.Mock(), kwargs)
|
||||||
|
|
||||||
|
def test_SUBNET_IP_VERSION(self):
|
||||||
|
self.assertEqual(network.NeutronWrapper.SUBNET_IP_VERSION, 4)
|
||||||
|
|
||||||
|
@mock.patch("rally.plugins.openstack.wrappers.network.generate_cidr")
|
||||||
|
def test__generate_cidr(self, mock_cidr):
|
||||||
|
cidrs = iter(range(5))
|
||||||
|
mock_cidr.side_effect = lambda start_cidr: start_cidr + next(cidrs)
|
||||||
|
service = self.get_wrapper(start_cidr=3)
|
||||||
|
self.assertEqual(service._generate_cidr(), 3)
|
||||||
|
self.assertEqual(service._generate_cidr(), 4)
|
||||||
|
self.assertEqual(service._generate_cidr(), 5)
|
||||||
|
self.assertEqual(service._generate_cidr(), 6)
|
||||||
|
self.assertEqual(service._generate_cidr(), 7)
|
||||||
|
self.assertEqual(mock_cidr.mock_calls, [mock.call(start_cidr=3)] * 5)
|
||||||
|
|
||||||
|
def test_external_networks(self):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
wrap.client.list_networks.return_value = {"networks": "foo_networks"}
|
||||||
|
self.assertEqual(wrap.external_networks, "foo_networks")
|
||||||
|
wrap.client.list_networks.assert_called_once_with(
|
||||||
|
**{"router:external": True})
|
||||||
|
|
||||||
|
def test_get_network(self):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
neutron_net = {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"tenant_id": "foo_tenant",
|
||||||
|
"status": "foo_status",
|
||||||
|
"router:external": "foo_external",
|
||||||
|
"subnets": "foo_subnets"}
|
||||||
|
expected_net = {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"tenant_id": "foo_tenant",
|
||||||
|
"status": "foo_status",
|
||||||
|
"external": "foo_external",
|
||||||
|
"router_id": None,
|
||||||
|
"subnets": "foo_subnets"}
|
||||||
|
wrap.client.show_network.return_value = {"network": neutron_net}
|
||||||
|
net = wrap.get_network(net_id="foo_id")
|
||||||
|
self.assertEqual(net, expected_net)
|
||||||
|
wrap.client.show_network.assert_called_once_with("foo_id")
|
||||||
|
|
||||||
|
wrap.client.show_network.side_effect = (
|
||||||
|
neutron_exceptions.NeutronClientException)
|
||||||
|
self.assertRaises(network.NetworkWrapperException, wrap.get_network,
|
||||||
|
net_id="foo_id")
|
||||||
|
|
||||||
|
wrap.client.list_networks.return_value = {"networks": [neutron_net]}
|
||||||
|
net = wrap.get_network(name="foo_name")
|
||||||
|
self.assertEqual(net, expected_net)
|
||||||
|
wrap.client.list_networks.assert_called_once_with(name="foo_name")
|
||||||
|
|
||||||
|
wrap.client.list_networks.return_value = {"networks": []}
|
||||||
|
self.assertRaises(network.NetworkWrapperException, wrap.get_network,
|
||||||
|
name="foo_name")
|
||||||
|
|
||||||
|
@mock.patch("rally.common.utils.generate_random_name")
|
||||||
|
def test_create_network(self, mock_name):
|
||||||
|
mock_name.return_value = "foo_name"
|
||||||
|
service = self.get_wrapper()
|
||||||
|
service.client.create_network.return_value = {
|
||||||
|
"network": {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"status": "foo_status"}}
|
||||||
|
net = service.create_network("foo_tenant")
|
||||||
|
mock_name.assert_called_once_with("rally_net_")
|
||||||
|
service.client.create_network.assert_called_once_with({
|
||||||
|
"network": {"tenant_id": "foo_tenant", "name": "foo_name"}})
|
||||||
|
self.assertEqual(net, {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"status": "foo_status",
|
||||||
|
"external": False,
|
||||||
|
"tenant_id": "foo_tenant",
|
||||||
|
"router_id": None,
|
||||||
|
"subnets": []})
|
||||||
|
|
||||||
|
@mock.patch("rally.common.utils.generate_random_name")
|
||||||
|
def test_create_network_with_subnets(self, mock_name):
|
||||||
|
subnets_num = 4
|
||||||
|
mock_name.return_value = "foo_name"
|
||||||
|
service = self.get_wrapper()
|
||||||
|
subnets_cidrs = iter(range(subnets_num))
|
||||||
|
subnets_ids = iter(range(subnets_num))
|
||||||
|
service._generate_cidr = mock.Mock(
|
||||||
|
side_effect=lambda: "cidr-%d" % next(subnets_cidrs))
|
||||||
|
service.client.create_subnet = mock.Mock(
|
||||||
|
side_effect=lambda i: {
|
||||||
|
"subnet": {"id": "subnet-%d" % next(subnets_ids)}})
|
||||||
|
service.client.create_network.return_value = {
|
||||||
|
"network": {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"status": "foo_status"}}
|
||||||
|
net = service.create_network("foo_tenant", subnets_num=subnets_num)
|
||||||
|
service.client.create_network.assert_called_once_with({
|
||||||
|
"network": {"tenant_id": "foo_tenant", "name": "foo_name"}})
|
||||||
|
self.assertEqual(net, {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"status": "foo_status",
|
||||||
|
"external": False,
|
||||||
|
"router_id": None,
|
||||||
|
"tenant_id": "foo_tenant",
|
||||||
|
"subnets": ["subnet-%d" % i
|
||||||
|
for i in range(subnets_num)]})
|
||||||
|
self.assertEqual(
|
||||||
|
service.client.create_subnet.mock_calls,
|
||||||
|
[mock.call({"subnet": {"name": "foo_name",
|
||||||
|
"enable_dhcp": True,
|
||||||
|
"network_id": "foo_id",
|
||||||
|
"tenant_id": "foo_tenant",
|
||||||
|
"ip_version": service.SUBNET_IP_VERSION,
|
||||||
|
"dns_nameservers": ["8.8.8.8", "8.8.4.4"],
|
||||||
|
"cidr": "cidr-%d" % i}})
|
||||||
|
for i in range(subnets_num)])
|
||||||
|
|
||||||
|
@mock.patch("rally.common.utils.generate_random_name")
|
||||||
|
def test_create_network_with_router(self, mock_name):
|
||||||
|
mock_name.return_value = "foo_name"
|
||||||
|
service = self.get_wrapper()
|
||||||
|
service.create_router = mock.Mock(return_value={"id": "foo_router"})
|
||||||
|
service.client.create_network.return_value = {
|
||||||
|
"network": {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"status": "foo_status"}}
|
||||||
|
net = service.create_network("foo_tenant", add_router=True)
|
||||||
|
self.assertEqual(net, {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"status": "foo_status",
|
||||||
|
"external": False,
|
||||||
|
"tenant_id": "foo_tenant",
|
||||||
|
"router_id": "foo_router",
|
||||||
|
"subnets": []})
|
||||||
|
service.create_router.assert_called_once_with(external=True,
|
||||||
|
tenant_id="foo_tenant")
|
||||||
|
|
||||||
|
@mock.patch("rally.common.utils.generate_random_name")
|
||||||
|
def test_create_network_with_router_and_subnets(self, mock_name):
|
||||||
|
subnets_num = 4
|
||||||
|
mock_name.return_value = "foo_name"
|
||||||
|
service = self.get_wrapper()
|
||||||
|
service._generate_cidr = mock.Mock(return_value="foo_cidr")
|
||||||
|
service.create_router = mock.Mock(return_value={"id": "foo_router"})
|
||||||
|
service.client.create_subnet = mock.Mock(
|
||||||
|
return_value={"subnet": {"id": "foo_subnet"}})
|
||||||
|
service.client.create_network.return_value = {
|
||||||
|
"network": {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"status": "foo_status"}}
|
||||||
|
net = service.create_network("foo_tenant", add_router=True,
|
||||||
|
subnets_num=subnets_num,
|
||||||
|
dns_nameservers=["foo_nameservers"])
|
||||||
|
self.assertEqual(net, {"id": "foo_id",
|
||||||
|
"name": "foo_name",
|
||||||
|
"status": "foo_status",
|
||||||
|
"external": False,
|
||||||
|
"tenant_id": "foo_tenant",
|
||||||
|
"router_id": "foo_router",
|
||||||
|
"subnets": ["foo_subnet"] * subnets_num})
|
||||||
|
service.create_router.assert_called_once_with(external=True,
|
||||||
|
tenant_id="foo_tenant")
|
||||||
|
self.assertEqual(
|
||||||
|
service.client.create_subnet.mock_calls,
|
||||||
|
[mock.call({"subnet": {"name": "foo_name",
|
||||||
|
"enable_dhcp": True,
|
||||||
|
"network_id": "foo_id",
|
||||||
|
"tenant_id": "foo_tenant",
|
||||||
|
"ip_version": service.SUBNET_IP_VERSION,
|
||||||
|
"dns_nameservers": ["foo_nameservers"],
|
||||||
|
"cidr": "foo_cidr"}})] * subnets_num)
|
||||||
|
self.assertEqual(service.client.add_interface_router.mock_calls,
|
||||||
|
[mock.call("foo_router", {"subnet_id": "foo_subnet"})
|
||||||
|
for i in range(subnets_num)])
|
||||||
|
|
||||||
|
def test_delete_network(self):
|
||||||
|
service = self.get_wrapper()
|
||||||
|
service.client.list_dhcp_agent_hosting_networks.return_value = (
|
||||||
|
{"agents": []})
|
||||||
|
service.client.list_ports.return_value = {"ports": []}
|
||||||
|
service.client.delete_network.return_value = "foo_deleted"
|
||||||
|
result = service.delete_network({"id": "foo_id", "router_id": None,
|
||||||
|
"subnets": []})
|
||||||
|
self.assertEqual(result, "foo_deleted")
|
||||||
|
self.assertEqual(
|
||||||
|
service.client.remove_network_from_dhcp_agent.mock_calls, [])
|
||||||
|
self.assertEqual(service.client.remove_gateway_router.mock_calls, [])
|
||||||
|
self.assertEqual(
|
||||||
|
service.client.remove_interface_router.mock_calls, [])
|
||||||
|
self.assertEqual(service.client.delete_router.mock_calls, [])
|
||||||
|
self.assertEqual(service.client.delete_subnet.mock_calls, [])
|
||||||
|
service.client.delete_network.assert_called_once_with("foo_id")
|
||||||
|
|
||||||
|
def test_delete_network_with_dhcp_and_router_and_ports_and_subnets(self):
|
||||||
|
service = self.get_wrapper()
|
||||||
|
agents = ["foo_agent", "bar_agent"]
|
||||||
|
subnets = ["foo_subnet", "bar_subnet"]
|
||||||
|
ports = ["foo_port", "bar_port"]
|
||||||
|
service.client.list_dhcp_agent_hosting_networks.return_value = (
|
||||||
|
{"agents": [{"id": agent_id} for agent_id in agents]})
|
||||||
|
service.client.list_ports.return_value = (
|
||||||
|
{"ports": [{"id": port_id} for port_id in ports]})
|
||||||
|
service.client.delete_network.return_value = "foo_deleted"
|
||||||
|
result = service.delete_network(
|
||||||
|
{"id": "foo_id", "router_id": "foo_router", "subnets": subnets})
|
||||||
|
self.assertEqual(result, "foo_deleted")
|
||||||
|
self.assertEqual(
|
||||||
|
service.client.remove_network_from_dhcp_agent.mock_calls,
|
||||||
|
[mock.call(agent_id, "foo_id") for agent_id in agents])
|
||||||
|
self.assertEqual(service.client.remove_gateway_router.mock_calls,
|
||||||
|
[mock.call("foo_router")])
|
||||||
|
self.assertEqual(
|
||||||
|
service.client.remove_interface_router.mock_calls,
|
||||||
|
[mock.call("foo_router", {"subnet_id": subnet_id})
|
||||||
|
for subnet_id in subnets])
|
||||||
|
self.assertEqual(service.client.delete_router.mock_calls,
|
||||||
|
[mock.call("foo_router")])
|
||||||
|
self.assertEqual(service.client.delete_port.mock_calls,
|
||||||
|
[mock.call(port_id) for port_id in ports])
|
||||||
|
self.assertEqual(service.client.delete_subnet.mock_calls,
|
||||||
|
[mock.call(subnet_id) for subnet_id in subnets])
|
||||||
|
service.client.delete_network.assert_called_once_with("foo_id")
|
||||||
|
|
||||||
|
def test_list_networks(self):
|
||||||
|
service = self.get_wrapper()
|
||||||
|
service.client.list_networks.return_value = {"networks": "foo_nets"}
|
||||||
|
self.assertEqual(service.list_networks(), "foo_nets")
|
||||||
|
service.client.list_networks.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch(SVC + "NeutronWrapper.external_networks")
|
||||||
|
def test_create_floating_ip(self, mock_ext_networks):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
wrap.create_port = mock.Mock(return_value={"id": "port_id"})
|
||||||
|
wrap.client.create_floatingip = mock.Mock(
|
||||||
|
return_value={"floatingip": {"id": "fip_id",
|
||||||
|
"floating_ip_address": "fip_ip"}})
|
||||||
|
|
||||||
|
self.assertRaises(ValueError, wrap.create_floating_ip)
|
||||||
|
|
||||||
|
mock_ext_networks.__get__ = lambda *args: []
|
||||||
|
self.assertRaises(network.NetworkWrapperException,
|
||||||
|
wrap.create_floating_ip, tenant_id="foo_tenant")
|
||||||
|
|
||||||
|
mock_ext_networks.__get__ = lambda *args: [{"id": "ext_id"}]
|
||||||
|
fip = wrap.create_floating_ip(tenant_id="foo_tenant")
|
||||||
|
self.assertEqual(fip, {"id": "fip_id", "ip": "fip_ip"})
|
||||||
|
|
||||||
|
wrap.get_network = mock.Mock(
|
||||||
|
return_value={"id": "foo_net", "external": True})
|
||||||
|
self.assertRaises(network.NetworkWrapperException,
|
||||||
|
wrap.create_floating_ip, tenant_id="foo_tenant",
|
||||||
|
int_network="int_net")
|
||||||
|
wrap.create_floating_ip(tenant_id="foo_tenant", ext_network="ext_net")
|
||||||
|
|
||||||
|
wrap.get_network = mock.Mock(
|
||||||
|
return_value={"id": "foo_net", "external": False})
|
||||||
|
wrap.create_floating_ip(tenant_id="foo_tenant", int_network="int_net")
|
||||||
|
|
||||||
|
self.assertRaises(network.NetworkWrapperException,
|
||||||
|
wrap.create_floating_ip, tenant_id="foo_tenant",
|
||||||
|
ext_network="ext_net")
|
||||||
|
|
||||||
|
def test_delete_floating_ip(self):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
wrap.delete_floating_ip("fip_id")
|
||||||
|
wrap.delete_floating_ip("fip_id", ignored_kwarg="bar")
|
||||||
|
self.assertEqual(wrap.client.delete_floatingip.mock_calls,
|
||||||
|
[mock.call("fip_id")] * 2)
|
||||||
|
|
||||||
|
@mock.patch(SVC + "NeutronWrapper.external_networks")
|
||||||
|
@mock.patch("rally.common.utils.generate_random_name")
|
||||||
|
def test_create_router(self, mock_random, mock_ext_networks):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
mock_random.return_value = "random_name"
|
||||||
|
wrap.client.create_router.return_value = {"router": "foo_router"}
|
||||||
|
mock_ext_networks.__get__ = lambda *args: [{"id": "ext_id"}]
|
||||||
|
|
||||||
|
router = wrap.create_router(name="foo_name")
|
||||||
|
wrap.client.create_router.assert_called_once_with(
|
||||||
|
{"router": {"name": "foo_name"}})
|
||||||
|
self.assertEqual(router, "foo_router")
|
||||||
|
|
||||||
|
router = wrap.create_router(external=True, foo="bar")
|
||||||
|
wrap.client.create_router.assert_called_with(
|
||||||
|
{"router": {"name": "random_name",
|
||||||
|
"external_gateway_info": {
|
||||||
|
"network_id": "ext_id",
|
||||||
|
"enable_snat": True},
|
||||||
|
"foo": "bar"}})
|
||||||
|
|
||||||
|
@mock.patch("rally.common.utils.generate_random_name")
|
||||||
|
def test_create_port(self, mock_random):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
mock_random.return_value = "random_name"
|
||||||
|
wrap.client.create_port.return_value = {"port": "foo_port"}
|
||||||
|
|
||||||
|
port = wrap.create_port("foo_net", name="foo_name")
|
||||||
|
wrap.client.create_port.assert_called_once_with(
|
||||||
|
{"port": {"network_id": "foo_net", "name": "foo_name"}})
|
||||||
|
self.assertEqual(port, "foo_port")
|
||||||
|
|
||||||
|
port = wrap.create_port("foo_net", foo="bar")
|
||||||
|
wrap.client.create_port.assert_called_with(
|
||||||
|
{"port": {"network_id": "foo_net",
|
||||||
|
"name": "random_name", "foo": "bar"}})
|
||||||
|
|
||||||
|
def test_supports_security_group(self):
|
||||||
|
wrap = self.get_wrapper()
|
||||||
|
wrap.client.list_extensions.return_value = (
|
||||||
|
{"extensions": [{"alias": "security-group"}]})
|
||||||
|
self.assertTrue(wrap.supports_security_group()[0])
|
||||||
|
|
||||||
|
wrap.client.list_extensions.return_value = (
|
||||||
|
{"extensions": [{"alias": "dummy-group"}]})
|
||||||
|
self.assertFalse(wrap.supports_security_group()[0])
|
||||||
|
|
||||||
|
wrap.client.list_extensions.return_value = {}
|
||||||
|
self.assertFalse(wrap.supports_security_group()[0])
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionsTestCase(test.TestCase):
|
||||||
|
|
||||||
|
def test_generate_cidr(self):
|
||||||
|
with mock.patch("rally.plugins.openstack.wrappers.network.cidr_incr",
|
||||||
|
iter(range(1, 4))):
|
||||||
|
self.assertEqual(network.generate_cidr(), "10.2.1.0/24")
|
||||||
|
self.assertEqual(network.generate_cidr(), "10.2.2.0/24")
|
||||||
|
self.assertEqual(network.generate_cidr(), "10.2.3.0/24")
|
||||||
|
|
||||||
|
with mock.patch("rally.plugins.openstack.wrappers.network.cidr_incr",
|
||||||
|
iter(range(1, 4))):
|
||||||
|
start_cidr = "1.1.0.0/26"
|
||||||
|
self.assertEqual(network.generate_cidr(start_cidr), "1.1.0.64/26")
|
||||||
|
self.assertEqual(network.generate_cidr(start_cidr), "1.1.0.128/26")
|
||||||
|
self.assertEqual(network.generate_cidr(start_cidr), "1.1.0.192/26")
|
||||||
|
|
||||||
|
def test_wrap(self):
|
||||||
|
mock_clients = mock.Mock()
|
||||||
|
mock_clients.nova().networks.list.return_value = []
|
||||||
|
|
||||||
|
mock_clients.services.return_value = {"foo": consts.Service.NEUTRON}
|
||||||
|
self.assertIsInstance(network.wrap(mock_clients, {}),
|
||||||
|
network.NeutronWrapper)
|
||||||
|
|
||||||
|
mock_clients.services.return_value = {"foo": "bar"}
|
||||||
|
self.assertIsInstance(network.wrap(mock_clients, {}),
|
||||||
|
network.NovaNetworkWrapper)
|
Loading…
Reference in New Issue
Block a user