Remove NovaNetworkPlugin

Nova network was deprecated in Newton and is no longer supported for
regular deployments in Ocata [1].

Complete the removal of nova network support from manila begun in [2]
by removing support for ''nova_net_id`` in the share networks API,
by removing the corresponding column from the share networks DB model,
and by removing the nova network plugins themselves.  Unit tests for
share network api views were refactored to remove redundancy while
extending coverage to the new microversion introduced with this patch
and maintaining full coverage of earlier microversions.

APIImpact
DocImpact
UpgradeImpact

Partially-implements: bp remove-nova-net-plugin

[1] http://docs.openstack.org/releasenotes/nova/unreleased.html
[2] I846b760fa7c01f7f86768399a2bfad9ced7e57cd

Change-Id: I8b9a559fbea61979f01737ed1dc272276c4f1269
This commit is contained in:
Tom Barron 2017-01-04 09:35:19 -05:00
parent 2455c2ef60
commit b213a25c44
32 changed files with 223 additions and 848 deletions

View File

@ -1951,9 +1951,9 @@ neutron_net_id:
type: string
neutron_net_id_1:
description: |
The UUID of the neutron network to set up for
share servers. You can set up either a neutron network and subnet
or a nova network.
The UUID of a neutron network when setting up a share network
with neutron. Specify both a neutron network and a neutron
subnet that belongs to that neutron network.
in: body
required: false
type: string
@ -1965,10 +1965,9 @@ neutron_subnet_id:
type: string
neutron_subnet_id_1:
description: |
The UUID of the neutron subnet to set up for
share servers. This subnet must be part of the neutron network.
You can set up either a neutron network and subnet or a nova
network.
The UUID of the neutron subnet when setting up a share network
with neutron. Specify both a neutron network and a neutron
subnet that belongs to that neutron network.
in: body
required: false
type: string
@ -1996,20 +1995,6 @@ notify:
in: body
required: true
type: string
nova_net_id:
description: |
The nova network ID.
in: body
required: true
type: string
nova_net_id_1:
description: |
The UUID of the nova network to set up for share
servers. You can set up either a neutron network and subnet or a
nova network.
in: body
required: false
type: string
os-force_delete:
description: |
The ``force_delete`` object.

View File

@ -8,7 +8,6 @@
"id": "d8ae6799-2567-4a89-aafb-fa4424350d2b",
"neutron_net_id": null,
"ip_version": null,
"nova_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
"cidr": null,
"project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
"network_type": null,

View File

@ -8,7 +8,6 @@
"id": "77eb3421-4549-4789-ac39-0d5185d68c29",
"neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
"ip_version": null,
"nova_net_id": null,
"cidr": null,
"project_id": "e10a683c20da41248cfd5e1ab3d88c62",
"network_type": null,

View File

@ -8,7 +8,6 @@
"id": "d8ae6799-2567-4a89-aafb-fa4424350d2b",
"neutron_net_id": null,
"ip_version": null,
"nova_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
"cidr": null,
"project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
"network_type": null,

View File

@ -8,7 +8,6 @@
"id": "7f950b52-6141-4a08-bbb5-bb7ffa3ea5fd",
"neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
"ip_version": null,
"nova_net_id": null,
"cidr": null,
"project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
"network_type": null,

View File

@ -8,7 +8,6 @@
"id": "713df749-aac0-4a54-af52-10f6c991e80c",
"neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
"ip_version": "4",
"nova_net_id": null,
"cidr": null,
"project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
"network_type": null,

View File

@ -9,7 +9,6 @@
"id": "32763294-e3d4-456a-998d-60047677c2fb",
"neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
"ip_version": null,
"nova_net_id": null,
"cidr": null,
"project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
"network_type": null,
@ -24,7 +23,6 @@
"id": "713df749-aac0-4a54-af52-10f6c991e80c",
"neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
"ip_version": null,
"nova_net_id": null,
"cidr": null,
"project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
"network_type": null,
@ -39,7 +37,6 @@
"id": "fa158a3d-6d9f-4187-9ca5-abbb82646eb2",
"neutron_net_id": null,
"ip_version": null,
"nova_net_id": null,
"cidr": null,
"project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
"network_type": null,

View File

@ -12,12 +12,11 @@ access the share.
You can create, update, view, and delete a share network.
When you create a share network, you can specify only one type of
network:
When you create a share network, you may optionally specify an associated
neutron network and subnetwork:
- Neutron network. Specify a network ID and subnet ID.
- Nova network. Specify a network ID.
For more information about supported plug-ins for share networks,
see `Manila Network Plugins <http://docs.openstack.org/developer/ma
@ -97,7 +96,6 @@ Response parameters
- project_id: project_id
- neutron_net_id: neutron_net_id
- neutron_subnet_id: neutron_subnet_id
- nova_net_id: nova_net_id
- network_type: network_type
- segmentation_id: segmentation_id
- cidr: cidr
@ -142,7 +140,6 @@ Response parameters
- project_id: project_id
- neutron_net_id: neutron_net_id
- neutron_subnet_id: neutron_subnet_id
- nova_net_id: nova_net_id
- network_type: network_type
- segmentation_id: segmentation_id
- cidr: cidr
@ -179,7 +176,6 @@ Request
- tenant_id: tenant_id_1
- neutron_net_id: neutron_net_id_1
- neutron_subnet_id: neutron_subnet_id_1
- nova_net_id: nova_net_id_1
- name: name
- description: description
@ -198,7 +194,6 @@ Response parameters
- project_id: project_id
- neutron_net_id: neutron_net_id
- neutron_subnet_id: neutron_subnet_id
- nova_net_id: nova_net_id
- network_type: network_type_1
- segmentation_id: segmentation_id_1
- cidr: cidr_1
@ -251,7 +246,6 @@ Response parameters
- project_id: project_id
- neutron_net_id: neutron_net_id
- neutron_subnet_id: neutron_subnet_id
- nova_net_id: nova_net_id
- network_type: network_type
- segmentation_id: segmentation_id
- cidr: cidr
@ -305,7 +299,6 @@ Response parameters
- project_id: project_id
- neutron_net_id: neutron_net_id
- neutron_subnet_id: neutron_subnet_id
- nova_net_id: nova_net_id
- network_type: network_type
- segmentation_id: segmentation_id
- cidr: cidr
@ -361,7 +354,6 @@ Response parameters
- project_id: project_id
- neutron_net_id: neutron_net_id
- neutron_subnet_id: neutron_subnet_id
- nova_net_id: nova_net_id
- network_type: network_type
- segmentation_id: segmentation_id
- cidr: cidr

View File

@ -83,14 +83,14 @@ REST_API_VERSION_HISTORY = """
which was previously inferred from the 'snapshot_support' extra
spec. Also made the 'snapshot_support' extra spec optional.
* 2.25 - Added quota-show detail API.
* 2.26 - Removed 'nova_net_id' parameter from share_network API.
"""
# The minimum and maximum versions of the API supported
# The default api version request is defined to be the
# minimum version of the API supported.
_MIN_API_VERSION = "2.0"
_MAX_API_VERSION = "2.25"
_MAX_API_VERSION = "2.26"
DEFAULT_API_VERSION = _MIN_API_VERSION

View File

@ -151,3 +151,8 @@ user documentation.
2.25
----
Added quota-show detail API.
2.26
----
Removed nova-net plugin support and removed 'nova_net_id' parameter from
share_network API.

View File

@ -26,7 +26,6 @@ from manila.api.v1 import scheduler_stats
from manila.api.v1 import security_service
from manila.api.v1 import share_manage
from manila.api.v1 import share_metadata
from manila.api.v1 import share_networks
from manila.api.v1 import share_servers
from manila.api.v1 import share_snapshots
from manila.api.v1 import share_types_extra_specs
@ -36,6 +35,7 @@ from manila.api.v2 import availability_zones
from manila.api.v2 import quota_class_sets
from manila.api.v2 import quota_sets
from manila.api.v2 import services
from manila.api.v2 import share_networks
from manila.api.v2 import share_types
from manila.api import versions

View File

@ -27,7 +27,6 @@ from manila.api.v1 import scheduler_stats
from manila.api.v1 import security_service
from manila.api.v1 import share_manage
from manila.api.v1 import share_metadata
from manila.api.v1 import share_networks
from manila.api.v1 import share_servers
from manila.api.v1 import share_types_extra_specs
from manila.api.v1 import share_unmanage
@ -40,6 +39,7 @@ from manila.api.v2 import services
from manila.api.v2 import share_export_locations
from manila.api.v2 import share_instance_export_locations
from manila.api.v2 import share_instances
from manila.api.v2 import share_networks
from manila.api.v2 import share_replicas
from manila.api.v2 import share_snapshot_instances
from manila.api.v2 import share_snapshots

View File

@ -185,23 +185,6 @@ class ShareNetworkController(wsgi.Controller):
'detail')
return self._get_share_networks(req)
@staticmethod
def _verify_no_mutually_exclusive_data(share_network, update_data=None):
update_data = update_data or dict()
neutron_net_id = (
share_network.get('neutron_net_id') or
update_data.get('neutron_net_id'))
neutron_subnet_id = (
share_network.get('neutron_subnet_id') or
update_data.get('neutron_subnet_id'))
nova_net_id = (
share_network.get('nova_net_id') or
update_data.get('nova_net_id'))
if nova_net_id and (neutron_net_id or neutron_subnet_id):
msg = _("Neutron net data and Nova net data are mutually "
"exclusive. Only one of these are allowed at a time.")
raise exc.HTTPBadRequest(explanation=msg)
def update(self, req, id, body):
"""Update specified share network."""
context = req.environ['manila.context']
@ -217,7 +200,10 @@ class ShareNetworkController(wsgi.Controller):
update_values = body[RESOURCE_NAME]
self._verify_no_mutually_exclusive_data(share_network, update_values)
if 'nova_net_id' in update_values:
raise exc.HTTPBadRequest("``nova`` networking is not supported "
"starting in ocata.")
if share_network['share_servers']:
for value in update_values:
if value not in ['name', 'description']:
@ -248,7 +234,10 @@ class ShareNetworkController(wsgi.Controller):
values = body[RESOURCE_NAME]
values['project_id'] = context.project_id
values['user_id'] = context.user_id
self._verify_no_mutually_exclusive_data(values)
if 'nova_net_id' in values:
raise exc.HTTPBadRequest("``nova`` networking is not supported "
"starting in ocata.")
try:
reservations = QUOTAS.reserve(context, share_networks=1)

View File

@ -20,7 +20,7 @@ class ViewBuilder(common.ViewBuilder):
"""Model a server API response as a python dictionary."""
_collection_name = 'share_networks'
_detail_version_modifiers = ["add_gateway", "add_mtu"]
_detail_version_modifiers = ["add_gateway", "add_mtu", "add_nova_net_id"]
def build_share_network(self, request, share_network):
"""View of a share network."""
@ -47,7 +47,6 @@ class ViewBuilder(common.ViewBuilder):
'updated_at': share_network.get('updated_at'),
'neutron_net_id': share_network.get('neutron_net_id'),
'neutron_subnet_id': share_network.get('neutron_subnet_id'),
'nova_net_id': share_network.get('nova_net_id'),
'network_type': share_network.get('network_type'),
'segmentation_id': share_network.get('segmentation_id'),
'cidr': share_network.get('cidr'),
@ -65,3 +64,7 @@ class ViewBuilder(common.ViewBuilder):
@common.ViewBuilder.versioned_method("2.20")
def add_mtu(self, context, network_dict, network):
network_dict['mtu'] = network.get('mtu')
@common.ViewBuilder.versioned_method("1.0", "2.25")
def add_nova_net_id(self, context, network_dict, network):
network_dict['nova_net_id'] = None

View File

@ -0,0 +1,36 @@
# 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.
"""remove_nova_net_id_column_from_share_networks
Revision ID: 95e3cf760840
Revises: 3e7d62517afa
Create Date: 2016-12-13 16:11:05.191717
"""
# revision identifiers, used by Alembic.
revision = '95e3cf760840'
down_revision = '3e7d62517afa'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.drop_column('share_networks', 'nova_net_id')
def downgrade():
op.add_column(
'share_networks',
sa.Column('nova_net_id', sa.String(36), nullable=True))

View File

@ -750,7 +750,6 @@ class ShareNetwork(BASE, ManilaBase):
deleted = Column(String(36), default='False')
project_id = Column(String(255), nullable=False)
user_id = Column(String(255), nullable=False)
nova_net_id = Column(String(36), nullable=True)
neutron_net_id = Column(String(36), nullable=True)
neutron_subnet_id = Column(String(36), nullable=True)
network_type = Column(String(32), nullable=True)

View File

@ -320,10 +320,6 @@ class NeutronSingleNetworkPlugin(NeutronNetworkPlugin):
def _update_share_network_net_data(self, context, share_network):
upd = dict()
if share_network.get('nova_net_id') is not None:
raise exception.NetworkBadConfigurationException(
"Share network has nova_net_id set.")
if not share_network.get('neutron_net_id') == self.net:
if share_network.get('neutron_net_id') is not None:
raise exception.NetworkBadConfigurationException(

View File

@ -1,228 +0,0 @@
# Copyright 2015 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 netaddr
from oslo_config import cfg
from oslo_log import log
import six
from manila.common import constants
from manila.compute import nova
import manila.context
from manila import exception
from manila.i18n import _
from manila import network
from manila import utils
nova_single_network_plugin_opts = [
cfg.StrOpt(
'nova_single_network_plugin_net_id',
help="Default Nova network that will be used for share servers. "
"This opt is used only with class 'NovaSingleNetworkPlugin'.",
deprecated_group='DEFAULT'),
]
CONF = cfg.CONF
LOG = log.getLogger(__name__)
class NovaNetworkPlugin(network.NetworkBaseAPI):
"""Nova network plugin for share drivers.
This plugin uses Nova networks provided within 'share-network' entities.
"""
def __init__(self, config_group_name=None, db_driver=None, label=None):
super(NovaNetworkPlugin, self).__init__(db_driver=db_driver)
self.config_group_name = config_group_name or 'DEFAULT'
self._label = label or 'user'
self.admin_context = manila.context.get_admin_context()
self.nova_api = nova.API()
@property
def label(self):
return self._label
@utils.synchronized(
"allocate_network_for_nova_network_plugin", external=True)
def allocate_network(self, context, share_server, share_network, **kwargs):
# NOTE(vponomaryov): This one is made as wrapper for inheritance
# purposes to avoid deadlock.
return self._allocate_network(
context, share_server, share_network, **kwargs)
def _allocate_network(
self, context, share_server, share_network, **kwargs):
"""Allocate network resources using one Nova network."""
allocations = []
allocation_count = kwargs.get('count', 1)
if allocation_count < 1:
return allocations
nova_net_id = share_network.get('nova_net_id')
if not nova_net_id:
raise exception.NetworkException(
_("'nova_net_id' is not provided with share network."))
# NOTE(vponomaryov): nova network should be taken using admin context
# because several required attrs of network are available
# only for admins.
nova_net = self.nova_api.network_get(self.admin_context, nova_net_id)
self._save_network_info(context, nova_net, share_network)
ip_addresses = self._get_available_ips(
context, nova_net, allocation_count)
for ip_address in ip_addresses:
data = {
'share_server_id': share_server['id'],
'ip_address': ip_address,
'status': constants.STATUS_ACTIVE,
'label': self.label,
'cidr': share_network['cidr'],
'gateway': share_network['gateway'],
'ip_version': share_network['ip_version'],
'segmentation_id': share_network['segmentation_id'],
'network_type': share_network['network_type'],
'mtu': share_network['mtu'],
}
self.nova_api.fixed_ip_reserve(self.admin_context, ip_address)
allocations.append(
self.db.network_allocation_create(context, data))
return allocations
def _get_available_ips(self, context, nova_net, amount):
"""Returns unused IP addresses from provided Nova network.
:param context: RequestContext instance
:param nova_net: dict -- dictionary with data of nova network
:param amount: int - amount of IP addresses to return
:returns: IP addresses as list of text types
:raises: exception.NetworkBadConfigurationException
"""
cidr = nova_net['cidr'] or nova_net['cidr_v6']
reserved = (
six.text_type(netaddr.IPNetwork(cidr).network),
nova_net['gateway'],
nova_net['gateway_v6'],
nova_net['dhcp_server'],
nova_net['broadcast'],
nova_net['vpn_private_address'],
nova_net['vpn_public_address'],
nova_net['dns1'],
nova_net['dns2'])
ips = []
iterator = netaddr.iter_unique_ips(cidr)
for ip in iterator:
ip = six.text_type(ip)
if ip in reserved:
# This IP address is reserved for service needs
continue
elif self.db.network_allocations_get_by_ip_address(context, ip):
# Some existing share server already uses this IP address
continue
fixed_ip = self.nova_api.fixed_ip_get(self.admin_context, ip)
if fixed_ip.get('host') or fixed_ip.get('hostname'):
# Some Nova VM already uses this IP address
continue
ips.append(ip)
if len(ips) == amount:
return ips
msg = _("No available IP addresses left in network '%(net_id)s' with "
"CIDR %(cidr)s. Requested amount of IPs to be provided "
"'%(amount)s', available only '%(available)s'") % dict(
net_id=nova_net['id'], cidr=cidr, amount=amount,
available=len(ips))
LOG.error(msg)
raise exception.NetworkBadConfigurationException(reason=msg)
def _save_network_info(self, context, nova_net, share_network):
"""Update 'share-network' with plugin specific data."""
data = {
'cidr': (nova_net['cidr'] or nova_net['cidr_v6']),
'gateway': (nova_net['gateway'] or nova_net['gateway_v6']),
'ip_version': (4 if nova_net['cidr'] else 6),
'segmentation_id': nova_net['vlan'],
'network_type': ('vlan' if nova_net['vlan'] else 'flat'),
'mtu': nova_net['mtu'],
}
share_network.update(data)
if self.label != 'admin':
self.db.share_network_update(context, share_network['id'], data)
def deallocate_network(self, context, share_server_id):
"""Deallocate network resources for share server."""
allocations = self.db.network_allocations_get_for_share_server(
context, share_server_id)
for allocation in allocations:
self.db.network_allocation_delete(context, allocation['id'])
self.nova_api.fixed_ip_unreserve(
self.admin_context, allocation['ip_address'])
class NovaSingleNetworkPlugin(NovaNetworkPlugin):
"""Nova network plugin for share drivers.
This plugin uses only one network that is predefined within config
option 'nova_single_network_plugin_net_id' and stores all required info
in provided 'share-network' that, further, can be used by share drivers.
"""
def __init__(self, *args, **kwargs):
super(NovaSingleNetworkPlugin, self).__init__(*args, **kwargs)
CONF.register_opts(
nova_single_network_plugin_opts,
group=self.config_group_name)
self.net_id = getattr(CONF, self.config_group_name,
CONF).nova_single_network_plugin_net_id
if not self.net_id:
msg = _("Nova network is not set")
LOG.error(msg)
raise exception.NetworkBadConfigurationException(reason=msg)
@utils.synchronized(
"allocate_network_for_nova_network_plugin", external=True)
def allocate_network(self, context, share_server, share_network, **kwargs):
if self.label != 'admin':
share_network = self._update_share_network_net_data(
context, share_network)
else:
share_network = {'nova_net_id': self.net_id}
return self._allocate_network(
context, share_server, share_network, **kwargs)
def _update_share_network_net_data(self, context, share_network):
neutron_data = share_network.get(
'neutron_net_id', share_network.get('neutron_subnet_id'))
if neutron_data:
msg = _("'share-network' with id '%s' should not contain Neutron "
"data. Either remove it or use another "
"'share-network'") % share_network['id']
LOG.error(msg)
raise exception.NetworkBadConfigurationException(reason=msg)
nova_net_id = share_network.get('nova_net_id')
if nova_net_id and nova_net_id != self.net_id:
msg = _("'share-network' with id '%(sn_id)s' already contains "
"Nova network id '%(provided)s' that is different from "
"what is defined in config '%(allowed)s'. Either remove "
"incorrect network id or set it the same") % dict(
sn_id=share_network['id'], provided=nova_net_id,
allowed=self.net_id)
LOG.error(msg)
raise exception.NetworkBadConfigurationException(reason=msg)
elif not nova_net_id:
share_network = self.db.share_network_update(
context, share_network['id'], dict(nova_net_id=self.net_id))
return share_network

View File

@ -83,7 +83,7 @@ class StandaloneNetworkPlugin(network.NetworkBaseAPI):
This network plugin can be used with any network platform.
It can serve flat networks as well as segmented.
It does not require some specific network services in OpenStack like
Neutron or Nova.
the Neutron plugin.
The only thing that plugin does is reservation and release of IP addresses
from some network.
"""

View File

@ -36,7 +36,6 @@ import manila.network
import manila.network.linux.interface
import manila.network.neutron.api
import manila.network.neutron.neutron_network_plugin
import manila.network.nova_network_plugin
import manila.network.standalone_network_plugin
import manila.quota
import manila.scheduler.drivers.base
@ -104,7 +103,6 @@ _global_opt_lists = [
neutron_bind_network_plugin_opts,
manila.network.neutron.neutron_network_plugin.
neutron_single_network_plugin_opts,
manila.network.nova_network_plugin.nova_single_network_plugin_opts,
manila.network.standalone_network_plugin.standalone_network_plugin_opts,
manila.quota.quota_opts,
manila.scheduler.drivers.base.scheduler_driver_opts,

View File

@ -2655,7 +2655,6 @@ class ShareManager(manager.SchedulerDependentManager):
'cidr': share_network['cidr'],
'neutron_net_id': share_network['neutron_net_id'],
'neutron_subnet_id': share_network['neutron_subnet_id'],
'nova_net_id': share_network['nova_net_id'],
'security_services': share_network['security_services'],
'network_allocations': network_allocations,
'admin_network_allocations': admin_network_allocations,

View File

@ -20,7 +20,8 @@ from oslo_utils import timeutils
from six.moves.urllib import parse
from webob import exc as webob_exc
from manila.api.v1 import share_networks
from manila.api.openstack import api_version_request as api_version
from manila.api.v2 import share_networks
from manila.db import api as db_api
from manila import exception
from manila import quota
@ -113,7 +114,6 @@ class ShareNetworkAPITest(test.TestCase):
self.assertNotIn('security_services', view)
@ddt.data(
{'nova_net_id': 'fake_nova_net_id'},
{'neutron_net_id': 'fake_neutron_net_id'},
{'neutron_subnet_id': 'fake_neutron_subnet_id'},
{'neutron_net_id': 'fake', 'neutron_subnet_id': 'fake'})
@ -129,7 +129,8 @@ class ShareNetworkAPITest(test.TestCase):
{'nova_net_id': 'foo', 'neutron_net_id': 'bar'},
{'nova_net_id': 'foo', 'neutron_subnet_id': 'quuz'},
{'nova_net_id': 'foo', 'neutron_net_id': 'bar',
'neutron_subnet_id': 'quuz'})
'neutron_subnet_id': 'quuz'},
{'nova_net_id': 'fake_nova_net_id'})
def test_create_invalid_cases(self, data):
data.update({'user_id': 'fake_user_id'})
body = {share_networks.RESOURCE_NAME: data}
@ -137,7 +138,6 @@ class ShareNetworkAPITest(test.TestCase):
webob_exc.HTTPBadRequest, self.controller.create, self.req, body)
@ddt.data(
{'nova_net_id': 'fake_nova_net_id'},
{'neutron_net_id': 'fake_neutron_net_id'},
{'neutron_subnet_id': 'fake_neutron_subnet_id'},
{'neutron_net_id': 'fake', 'neutron_subnet_id': 'fake'})
@ -160,7 +160,9 @@ class ShareNetworkAPITest(test.TestCase):
{'nova_net_id': 'foo', 'neutron_net_id': 'bar'},
{'nova_net_id': 'foo', 'neutron_subnet_id': 'quuz'},
{'nova_net_id': 'foo', 'neutron_net_id': 'bar',
'neutron_subnet_id': 'quuz'})
'neutron_subnet_id': 'quuz'},
{'nova_net_id': 'fake_nova_net_id'},
)
def test_update_invalid_cases(self, data):
body = {share_networks.RESOURCE_NAME: {'user_id': 'fake_user'}}
created = self.controller.create(self.req, body)
@ -570,17 +572,19 @@ class ShareNetworkAPITest(test.TestCase):
share_nw,
body)
def test_action_add_security_service(self):
@ddt.data(*set(("1.0", "2.25", "2.26", api_version._MAX_API_VERSION)))
def test_action_add_security_service(self, microversion):
share_network_id = 'fake network id'
security_service_id = 'fake ss id'
body = {'add_security_service': {'security_service_id':
security_service_id}}
req = fakes.HTTPRequest.blank('/share-networks', version=microversion)
with mock.patch.object(self.controller, '_add_security_service',
mock.Mock()):
self.controller.action(self.req, share_network_id, body)
self.controller.action(req, share_network_id, body)
self.controller._add_security_service.assert_called_once_with(
self.req, share_network_id, body['add_security_service'])
req, share_network_id, body['add_security_service'])
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
@mock.patch.object(db_api, 'security_service_get', mock.Mock())
@ -612,17 +616,19 @@ class ShareNetworkAPITest(test.TestCase):
'add_security_service',
)
def test_action_remove_security_service(self):
@ddt.data(*set(("1.0", "2.25", "2.26", api_version._MAX_API_VERSION)))
def test_action_remove_security_service(self, microversion):
share_network_id = 'fake network id'
security_service_id = 'fake ss id'
body = {'remove_security_service': {'security_service_id':
security_service_id}}
req = fakes.HTTPRequest.blank('/share-networks', version=microversion)
with mock.patch.object(self.controller, '_remove_security_service',
mock.Mock()):
self.controller.action(self.req, share_network_id, body)
self.controller.action(req, share_network_id, body)
self.controller._remove_security_service.assert_called_once_with(
self.req, share_network_id, body['remove_security_service'])
req, share_network_id, body['remove_security_service'])
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
@mock.patch.object(share_networks.policy, 'check_policy', mock.Mock())

View File

@ -14,7 +14,9 @@
# under the License.
import ddt
import itertools
from manila.api.openstack import api_version_request as api_version
from manila.api.views import share_networks
from manila import test
from manila.tests.api import fakes
@ -30,145 +32,83 @@ class ViewBuilderTestCase(test.TestCase):
def test__collection_name(self):
self.assertEqual('share_networks', self.builder._collection_name)
@ddt.data(
{'id': 'fake_sn_id', 'name': 'fake_sn_name'},
{'id': 'fake_sn_id', 'name': 'fake_sn_name', 'fake_extra_key': 'foo'},
@ddt.data(*itertools.product(
[
{'id': 'fake_sn_id', 'name': 'fake_sn_name'},
{'id': 'fake_sn_id', 'name': 'fake_sn_name',
'fake_extra_key': 'foo'},
],
["1.0", "2.0", "2.18", "2.20", "2.25", "2.26",
api_version._MAX_API_VERSION])
)
def test_build_share_network_v_2_18(self, sn):
req = fakes.HTTPRequest.blank('/share-networks', version="2.18")
expected_keys = (
@ddt.unpack
def test_build_share_network(self, share_network_data, microversion):
gateway_support = (api_version.APIVersionRequest(microversion) >=
api_version.APIVersionRequest('2.18'))
mtu_support = (api_version.APIVersionRequest(microversion) >=
api_version.APIVersionRequest('2.20'))
nova_net_support = (api_version.APIVersionRequest(microversion) <
api_version.APIVersionRequest('2.26'))
req = fakes.HTTPRequest.blank('/share-networks', version=microversion)
expected_keys = {
'id', 'name', 'project_id', 'created_at', 'updated_at',
'neutron_net_id', 'neutron_subnet_id', 'nova_net_id',
'network_type', 'segmentation_id', 'cidr', 'ip_version',
'gateway', 'description')
result = self.builder.build_share_network(req, sn)
'neutron_net_id', 'neutron_subnet_id', 'network_type',
'segmentation_id', 'cidr', 'ip_version', 'description'}
if gateway_support:
expected_keys.add('gateway')
if mtu_support:
expected_keys.add('mtu')
if nova_net_support:
expected_keys.add('nova_net_id')
result = self.builder.build_share_network(req, share_network_data)
self.assertEqual(1, len(result))
self.assertIn('share_network', result)
self.assertEqual(sn['id'], result['share_network']['id'])
self.assertEqual(sn['name'], result['share_network']['name'])
self.assertEqual(len(expected_keys), len(result['share_network']))
for key in expected_keys:
self.assertIn(key, result['share_network'])
@ddt.data(
[],
[dict(id='fake_id',
name='fake_name',
project_id='fake_project_id',
created_at='fake_created_at',
updated_at='fake_updated_at',
neutron_net_id='fake_neutron_net_id',
neutron_subnet_id='fake_neutron_subnet_id',
nova_net_id='fake_nova_net_id',
network_type='fake_network_type',
segmentation_id='fake_segmentation_id',
cidr='fake_cidr',
ip_version='fake_ip_version',
gateway='fake_gateway',
description='fake_description'),
dict(id='fake_id2', name='fake_name2')],
)
def test_build_share_networks_with_details_v_2_18(self, share_networks):
req = fakes.HTTPRequest.blank('/share-networks', version="2.18")
expected = []
for share_network in share_networks:
expected.append(dict(
id=share_network.get('id'),
name=share_network.get('name'),
project_id=share_network.get('project_id'),
created_at=share_network.get('created_at'),
updated_at=share_network.get('updated_at'),
neutron_net_id=share_network.get('neutron_net_id'),
neutron_subnet_id=share_network.get('neutron_subnet_id'),
nova_net_id=share_network.get('nova_net_id'),
network_type=share_network.get('network_type'),
segmentation_id=share_network.get('segmentation_id'),
cidr=share_network.get('cidr'),
ip_version=share_network.get('ip_version'),
gateway=share_network.get('gateway'),
description=share_network.get('description')))
expected = {'share_networks': expected}
result = self.builder.build_share_networks(
req, share_networks, True)
self.assertEqual(expected, result)
@ddt.data(
[],
[{'id': 'foo', 'name': 'bar'}],
[{'id': 'id1', 'name': 'name1'}, {'id': 'id2', 'name': 'name2'}],
[{'id': 'id1', 'name': 'name1'},
{'id': 'id2', 'name': 'name2', 'fake': 'I should not be returned'}],
)
def test_build_share_networks_without_details_v_2_18(self,
share_networks):
req = fakes.HTTPRequest.blank('/share-networks', version="2.18")
expected = []
for share_network in share_networks:
expected.append(dict(
id=share_network.get('id'), name=share_network.get('name')))
expected = {'share_networks': expected}
result = self.builder.build_share_networks(
req, share_networks, False)
self.assertEqual(expected, result)
@ddt.data(
{'id': 'fake_sn_id', 'name': 'fake_sn_name'},
{'id': 'fake_sn_id', 'name': 'fake_sn_name', 'fake_extra_key': 'foo'},
)
def test_build_share_network_v_2_20(self, sn):
req = fakes.HTTPRequest.blank('/share-networks', version="2.20")
expected_keys = (
'id', 'name', 'project_id', 'created_at', 'updated_at',
'neutron_net_id', 'neutron_subnet_id', 'nova_net_id',
'network_type', 'segmentation_id', 'cidr', 'ip_version',
'gateway', 'description', 'mtu')
result = self.builder.build_share_network(req, sn)
self.assertEqual(1, len(result))
self.assertIn('share_network', result)
self.assertEqual(sn['id'], result['share_network']['id'])
self.assertEqual(sn['name'], result['share_network']['name'])
self.assertEqual(len(expected_keys), len(result['share_network']))
self.assertEqual(share_network_data['id'],
result['share_network']['id'])
self.assertEqual(share_network_data['name'],
result['share_network']['name'])
self.assertEqual(len(expected_keys),
len(result['share_network']))
for key in expected_keys:
self.assertIn(key, result['share_network'])
for key in result['share_network']:
self.assertIn(key, expected_keys)
@ddt.data(
[], [{
'id': 'fake_id',
'name': 'fake_name',
'project_id': 'fake_project_id',
'created_at': 'fake_created_at',
'updated_at': 'fake_updated_at',
'neutron_net_id': 'fake_neutron_net_id',
'neutron_subnet_id': 'fake_neutron_subnet_id',
'nova_net_id': 'fake_nova_net_id',
'network_type': 'fake_network_type',
'segmentation_id': 'fake_segmentation_id',
'cidr': 'fake_cidr',
'ip_version': 'fake_ip_version',
'gateway': 'fake_gateway',
'description': 'fake_description',
'mtu': 1509
},
{
'id': 'fake_id2',
'name': 'fake_name2'
}],
@ddt.data(*itertools.product(
[
[],
[{'id': 'fake_id',
'name': 'fake_name',
'project_id': 'fake_project_id',
'created_at': 'fake_created_at',
'updated_at': 'fake_updated_at',
'neutron_net_id': 'fake_neutron_net_id',
'neutron_subnet_id': 'fake_neutron_subnet_id',
'network_type': 'fake_network_type',
'segmentation_id': 'fake_segmentation_id',
'cidr': 'fake_cidr',
'ip_version': 'fake_ip_version',
'description': 'fake_description'},
{'id': 'fake_id2',
'name': 'fake_name2'}],
],
set(["1.0", "2.0", "2.18", "2.20", "2.25", "2.26",
api_version._MAX_API_VERSION]))
)
def test_build_share_networks_with_details_v_2_20(self, share_networks):
req = fakes.HTTPRequest.blank('/share-networks', version="2.20")
expected = []
@ddt.unpack
def test_build_share_networks_with_details(self, share_networks,
microversion):
gateway_support = (api_version.APIVersionRequest(microversion) >=
api_version.APIVersionRequest('2.18'))
mtu_support = (api_version.APIVersionRequest(microversion) >=
api_version.APIVersionRequest('2.20'))
nova_net_support = (api_version.APIVersionRequest(microversion) <
api_version.APIVersionRequest('2.26'))
req = fakes.HTTPRequest.blank('/share-networks', version=microversion)
expected_networks_list = []
for share_network in share_networks:
expected.append({
expected_data = {
'id': share_network.get('id'),
'name': share_network.get('name'),
'project_id': share_network.get('project_id'),
@ -176,32 +116,45 @@ class ViewBuilderTestCase(test.TestCase):
'updated_at': share_network.get('updated_at'),
'neutron_net_id': share_network.get('neutron_net_id'),
'neutron_subnet_id': share_network.get('neutron_subnet_id'),
'nova_net_id': share_network.get('nova_net_id'),
'network_type': share_network.get('network_type'),
'segmentation_id': share_network.get('segmentation_id'),
'cidr': share_network.get('cidr'),
'ip_version': share_network.get('ip_version'),
'gateway': share_network.get('gateway'),
'description': share_network.get('description'),
'mtu': share_network.get('mtu'),
})
expected = {'share_networks': expected}
}
if gateway_support:
share_network.update({'gateway': 'fake_gateway'})
expected_data.update({'gateway': share_network.get('gateway')})
if mtu_support:
share_network.update({'mtu': 1509})
expected_data.update({'mtu': share_network.get('mtu')})
if nova_net_support:
share_network.update({'nova_net_id': 'fake_nova_net_id'})
expected_data.update({'nova_net_id': None})
expected_networks_list.append(expected_data)
expected = {'share_networks': expected_networks_list}
result = self.builder.build_share_networks(
req, share_networks, True)
result = self.builder.build_share_networks(req, share_networks,
is_detail=True)
self.assertEqual(expected, result)
@ddt.data(
[],
[{'id': 'foo', 'name': 'bar'}],
[{'id': 'id1', 'name': 'name1'}, {'id': 'id2', 'name': 'name2'}],
[{'id': 'id1', 'name': 'name1'},
{'id': 'id2', 'name': 'name2', 'fake': 'I should not be returned'}],
@ddt.data(*itertools.product(
[
[],
[{'id': 'foo', 'name': 'bar'}],
[{'id': 'id1', 'name': 'name1'}, {'id': 'id2', 'name': 'name2'}],
[{'id': 'id1', 'name': 'name1'},
{'id': 'id2', 'name': 'name2',
'fake': 'I should not be returned'}]
],
set(["1.0", "2.0", "2.18", "2.20", "2.25", "2.26",
api_version._MAX_API_VERSION]))
)
def test_build_share_networks_without_details_v_2_20(self,
share_networks):
req = fakes.HTTPRequest.blank('/share-networks', version="2.20")
@ddt.unpack
def test_build_share_networks_without_details(self, share_networks,
microversion):
req = fakes.HTTPRequest.blank('/share-networks', version=microversion)
expected = []
for share_network in share_networks:
expected.append({
@ -210,7 +163,7 @@ class ViewBuilderTestCase(test.TestCase):
})
expected = {'share_networks': expected}
result = self.builder.build_share_networks(
req, share_networks, False)
result = self.builder.build_share_networks(req, share_networks,
is_detail=False)
self.assertEqual(expected, result)

View File

@ -1331,3 +1331,38 @@ class CreateFromSnapshotExtraSpecAndShareColumn(BaseMigrationChecks):
if x['spec_key'] == self.expected_attr
and x['share_type_id'] == share_type_id]
self.test_case.assertEqual(0, len(new_extra_spec))
@map_to_migration('95e3cf760840')
class RemoveNovaNetIdColumnFromShareNetworks(BaseMigrationChecks):
table_name = 'share_networks'
nova_net_column_name = 'nova_net_id'
def setup_upgrade_data(self, engine):
user_id = 'user_id'
project_id = 'project_id'
nova_net_id = 'foo_nova_net_id'
share_network_data = {
'id': 'foo_share_network_id_3',
'user_id': user_id,
'project_id': project_id,
'nova_net_id': nova_net_id,
}
sn_table = utils.load_table(self.table_name, engine)
engine.execute(sn_table.insert(share_network_data))
def check_upgrade(self, engine, data):
sn_table = utils.load_table(self.table_name, engine)
rows = engine.execute(sn_table.select())
self.test_case.assertGreater(rows.rowcount, 0)
for row in rows:
self.test_case.assertFalse(hasattr(row, self.nova_net_column_name))
def check_downgrade(self, engine):
sn_table = utils.load_table(self.table_name, engine)
rows = engine.execute(sn_table.select())
self.test_case.assertGreater(rows.rowcount, 0)
for row in rows:
self.test_case.assertTrue(hasattr(row, self.nova_net_column_name))
self.test_case.assertIsNone(row[self.nova_net_column_name])

View File

@ -612,22 +612,6 @@ class NeutronSingleNetworkPluginTest(test.TestCase):
self.context, share_network)
self.assertFalse(instance.db.share_network_update.called)
def test___update_share_network_net_data_nova_net_id_present(self):
instance = self._get_neutron_network_plugin_instance()
share_network = {
'id': 'fake_share_network_id',
'nova_net_id': 'foo',
}
self.mock_object(
instance.db, 'share_network_update',
mock.Mock(return_value=share_network))
self.assertRaises(
exception.NetworkBadConfigurationException,
instance._update_share_network_net_data,
self.context, share_network)
self.assertFalse(instance.db.share_network_update.called)
def test_allocate_network(self):
self.mock_object(plugin.NeutronNetworkPlugin, 'allocate_network')
plugin.NeutronNetworkPlugin.allocate_network.return_value = [
@ -1196,22 +1180,6 @@ class NeutronBindSingleNetworkPluginTest(test.TestCase):
self.context, share_network)
self.assertFalse(instance.db.share_network_update.called)
def test___update_share_network_net_data_nova_net_id_present(self):
instance = self._get_neutron_single_network_plugin_instance()
share_network = {
'id': 'fake_share_network_id',
'nova_net_id': 'foo',
}
self.mock_object(
instance.db, 'share_network_update',
mock.Mock(return_value=share_network))
self.assertRaises(
exception.NetworkBadConfigurationException,
instance._update_share_network_net_data,
self.context, share_network)
self.assertFalse(instance.db.share_network_update.called)
def test_wait_for_bind(self):
self.mock_object(self.bind_plugin.neutron_api, 'show_port')
self.bind_plugin.neutron_api.show_port.return_value = fake_neutron_port

View File

@ -1,343 +0,0 @@
# Copyright 2015 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 ddt
import mock
from manila import context
from manila import exception
from manila.network import nova_network_plugin as plugin
from manila import test
from manila.tests import utils as test_utils
@ddt.ddt
class NovaNetworkPluginTest(test.TestCase):
def setUp(self):
super(NovaNetworkPluginTest, self).setUp()
self.fake_context = context.RequestContext(
user_id='fake user', project_id='fake project', is_admin=False)
self.instance = plugin.NovaNetworkPlugin()
self.share_server = dict(id='fake_share_server_id')
self.share_network = dict(
id='fake_sn_id', nova_net_id='fake_nova_net_id')
def test_allocate_network_get_zero(self):
share_network = 'fake_share_network'
allocations = self.instance.allocate_network(
self.fake_context, self.share_server, share_network, count=0)
self.assertEqual([], allocations)
self.assertTrue(hasattr(self.instance, 'label'))
self.assertEqual('user', self.instance.label)
@ddt.data('flat', 'vlan')
def test_allocate_network_get_one(self, net_type):
def fake_get_ip_from_db(context, ip_addr):
return [] if ip_addr != '20.0.0.7' else ['fake not empty list']
def fake_fixed_ip_get(context, ip_addr):
if ip_addr == '20.0.0.8':
return dict(host='foo', hostname='bar')
return dict(host=None, hostname=None)
share_network = dict(id='fake_sn_id', nova_net_id='fake_nova_net_id')
nova_net = dict(
cidr='20.0.0.0/24', cidr_v6=None,
gateway='20.0.0.1', gateway_v6=None,
dhcp_server='20.0.0.2', broadcast='20.0.0.255',
vpn_private_address='20.0.0.3', vpn_public_address='20.0.0.4',
dns1='20.0.0.5', dns2='20.0.0.6', vlan=None, mtu=1509)
if net_type == 'vlan':
nova_net['vlan'] = 100
self.mock_object(self.instance.nova_api, 'fixed_ip_reserve')
self.mock_object(
self.instance.nova_api, 'fixed_ip_get',
mock.Mock(side_effect=fake_fixed_ip_get))
self.mock_object(
self.instance.nova_api, 'network_get',
mock.Mock(return_value=nova_net))
self.mock_object(self.instance.db, 'share_network_update')
self.mock_object(
self.instance.db, 'network_allocations_get_by_ip_address',
mock.Mock(side_effect=fake_get_ip_from_db))
expected_ip_address = '20.0.0.9'
allocations = self.instance.allocate_network(
self.fake_context, self.share_server, share_network)
self.assertEqual(1, len(allocations))
self.assertEqual(
self.share_server['id'], allocations[0]['share_server_id'])
self.assertEqual(expected_ip_address, allocations[0]['ip_address'])
self.instance.nova_api.network_get.assert_called_once_with(
self.instance.admin_context, share_network['nova_net_id'])
self.instance.nova_api.fixed_ip_reserve.assert_called_once_with(
self.instance.admin_context, expected_ip_address)
self.instance.db.share_network_update.assert_called_once_with(
self.fake_context, share_network['id'],
dict(cidr=nova_net['cidr'], gateway=nova_net['gateway'],
ip_version=4, segmentation_id=nova_net['vlan'],
network_type=net_type, mtu=1509))
self.instance.db.network_allocations_get_by_ip_address.\
assert_has_calls([
mock.call(self.fake_context, '20.0.0.7'),
mock.call(self.fake_context, '20.0.0.8'),
mock.call(self.fake_context, '20.0.0.9')])
self.instance.nova_api.fixed_ip_get.assert_has_calls([
mock.call(self.instance.admin_context, '20.0.0.8'),
mock.call(self.instance.admin_context, '20.0.0.9')])
@ddt.data('flat', 'vlan')
def test_allocate_network_get_two(self, net_type):
def fake_get_ip_from_db(context, ip_addr):
return [] if ip_addr != '20.0.0.7' else ['fake not empty list']
def fake_fixed_ip_get(context, ip_addr):
if ip_addr == '20.0.0.8':
return dict(host='foo', hostname='bar')
return dict(host=None, hostname=None)
nova_net = dict(
cidr='20.0.0.0/24', cidr_v6=None,
gateway='20.0.0.1', gateway_v6=None,
dhcp_server='20.0.0.254', broadcast='20.0.0.255',
vpn_private_address='20.0.0.3', vpn_public_address='20.0.0.4',
dns1='20.0.0.5', dns2='20.0.0.6', vlan=None, mtu=1509)
if net_type == 'vlan':
nova_net['vlan'] = 100
self.mock_object(self.instance.nova_api, 'fixed_ip_reserve')
self.mock_object(
self.instance.nova_api, 'fixed_ip_get',
mock.Mock(side_effect=fake_fixed_ip_get))
self.mock_object(
self.instance.nova_api, 'network_get',
mock.Mock(return_value=nova_net))
self.mock_object(self.instance.db, 'share_network_update')
self.mock_object(
self.instance.db, 'network_allocations_get_by_ip_address',
mock.Mock(side_effect=fake_get_ip_from_db))
expected_ip_address1 = '20.0.0.2'
expected_ip_address2 = '20.0.0.9'
allocations = self.instance.allocate_network(
self.fake_context, self.share_server, self.share_network, count=2)
self.assertEqual(2, len(allocations))
for allocation in allocations:
self.assertEqual(
self.share_server['id'], allocation['share_server_id'])
self.assertEqual(expected_ip_address1, allocations[0]['ip_address'])
self.assertEqual(expected_ip_address2, allocations[1]['ip_address'])
self.instance.nova_api.network_get.assert_called_once_with(
self.instance.admin_context, self.share_network['nova_net_id'])
self.instance.nova_api.fixed_ip_reserve.assert_has_calls([
mock.call(self.instance.admin_context, expected_ip_address1),
mock.call(self.instance.admin_context, expected_ip_address2)])
self.instance.db.share_network_update.assert_called_once_with(
self.fake_context, self.share_network['id'],
dict(cidr=nova_net['cidr'], gateway=nova_net['gateway'],
ip_version=4, segmentation_id=nova_net['vlan'],
network_type=net_type, mtu=1509))
self.instance.db.network_allocations_get_by_ip_address.\
assert_has_calls([
mock.call(self.fake_context, '20.0.0.2'),
mock.call(self.fake_context, '20.0.0.7'),
mock.call(self.fake_context, '20.0.0.8'),
mock.call(self.fake_context, '20.0.0.9')])
self.instance.nova_api.fixed_ip_get.assert_has_calls([
mock.call(self.instance.admin_context, '20.0.0.2'),
mock.call(self.instance.admin_context, '20.0.0.8'),
mock.call(self.instance.admin_context, '20.0.0.9')])
def test_allocate_network_nova_net_id_no_available_ips_left(self):
nova_net = dict(
id='fake_net_id', cidr='20.0.0.0/24', cidr_v6=None,
gateway='20.0.0.1', gateway_v6=None,
dhcp_server='20.0.0.2', broadcast='20.0.0.255',
vpn_private_address='20.0.0.3', vpn_public_address='20.0.0.4',
dns1='20.0.0.5', dns2='20.0.0.6', vlan=100, mtu=1509)
self.mock_object(
self.instance.nova_api, 'network_get',
mock.Mock(return_value=nova_net))
self.mock_object(self.instance.db, 'share_network_update')
self.mock_object(
self.instance.db, 'network_allocations_get_by_ip_address',
mock.Mock(return_value=['fake not empty list']))
self.assertRaises(
exception.NetworkBadConfigurationException,
self.instance.allocate_network,
self.fake_context, self.share_server, self.share_network)
self.instance.nova_api.network_get.assert_called_once_with(
self.instance.admin_context, self.share_network['nova_net_id'])
self.instance.db.share_network_update.assert_called_once_with(
self.fake_context, self.share_network['id'],
dict(cidr=nova_net['cidr'], gateway=nova_net['gateway'],
ip_version=4, segmentation_id=nova_net['vlan'],
network_type='vlan', mtu=1509))
self.assertEqual(
248,
self.instance.db.network_allocations_get_by_ip_address.call_count)
@ddt.data(dict(), dict(nova_net_id=None))
def test_allocate_network_nova_net_id_is_not_provided(self, share_network):
self.assertRaises(
exception.NetworkException,
self.instance.allocate_network,
self.fake_context, self.share_server, share_network)
def test_deallocate_network(self):
fake_alloc = dict(id='fake_alloc_id', ip_address='fake_ip_address')
self.mock_object(self.instance.nova_api, 'fixed_ip_unreserve')
self.mock_object(self.instance.db, 'network_allocation_delete')
self.mock_object(
self.instance.db, 'network_allocations_get_for_share_server',
mock.Mock(return_value=[fake_alloc]))
self.instance.deallocate_network(
self.fake_context, self.share_server['id'])
self.instance.db.network_allocations_get_for_share_server.\
assert_called_once_with(
self.fake_context, self.share_server['id'])
self.instance.db.network_allocation_delete.assert_called_once_with(
self.fake_context, fake_alloc['id'])
self.instance.nova_api.fixed_ip_unreserve.assert_called_once_with(
self.instance.admin_context, fake_alloc['ip_address'])
@ddt.ddt
class NovaSingleNetworkPluginTest(test.TestCase):
def setUp(self):
super(NovaSingleNetworkPluginTest, self).setUp()
self.share_server = dict(id='fake_share_server_id')
self.context = context.RequestContext(
user_id='fake user', project_id='fake project', is_admin=False)
def _get_instance(self, label=None):
nova_net_id = 'fake_nova_net_id'
config_data = dict(
DEFAULT=dict(nova_single_network_plugin_net_id=nova_net_id))
with test_utils.create_temp_config_with_opts(config_data):
return plugin.NovaSingleNetworkPlugin(label=label)
def test_init_valid(self):
nova_net_id = 'fake_nova_net_id'
config_data = dict(
DEFAULT=dict(nova_single_network_plugin_net_id=nova_net_id))
with test_utils.create_temp_config_with_opts(config_data):
instance = plugin.NovaSingleNetworkPlugin()
self.assertEqual(nova_net_id, instance.net_id)
@ddt.data(dict(), dict(net=''))
def test_init_invalid(self, data):
config_data = dict(DEFAULT=data)
with test_utils.create_temp_config_with_opts(config_data):
self.assertRaises(
exception.NetworkBadConfigurationException,
plugin.NovaSingleNetworkPlugin)
def test_allocate_network_net_is_not_set_in_share_network(self):
instance = self._get_instance()
share_network = dict(id='fake_share_network')
updated_share_network = dict(id='fake_updated_share_network')
allocations = ['foo', 'bar']
self.mock_object(
instance.db, 'share_network_update',
mock.Mock(return_value=updated_share_network))
self.mock_object(
instance, '_allocate_network', mock.Mock(return_value=allocations))
result = instance.allocate_network(
self.context, self.share_server, share_network, count=2)
self.assertEqual(allocations, result)
instance.db.share_network_update.assert_called_once_with(
self.context, share_network['id'],
dict(nova_net_id='fake_nova_net_id'))
instance._allocate_network.assert_called_once_with(
self.context, self.share_server, updated_share_network, count=2)
def test_allocate_network_net_is_set_in_share_network(self):
instance = self._get_instance()
share_network = dict(
id='fake_share_network', nova_net_id='fake_nova_net_id')
allocations = ['foo', 'bar']
self.mock_object(instance.db, 'share_network_update')
self.mock_object(
instance, '_allocate_network', mock.Mock(return_value=allocations))
result = instance.allocate_network(
self.context, self.share_server, share_network, count=2)
self.assertEqual(allocations, result)
instance.db.share_network_update.assert_has_calls([])
instance._allocate_network.assert_called_once_with(
self.context, self.share_server, share_network, count=2)
def test_allocate_network_with_admin_label(self):
instance = self._get_instance(label='admin')
allocations = ['foo', 'bar']
self.mock_object(instance.db, 'share_network_update')
self.mock_object(
instance, '_allocate_network', mock.Mock(return_value=allocations))
fake_share_network = {'nova_net_id': 'fake_nova_net_id'}
result = instance.allocate_network(
self.context, self.share_server, fake_share_network, count=2)
self.assertTrue(hasattr(instance, 'label'))
self.assertEqual('admin', instance.label)
self.assertEqual(allocations, result)
instance.db.share_network_update.assert_has_calls([])
instance._allocate_network.assert_called_once_with(
self.context, self.share_server, fake_share_network, count=2)
def test_allocate_network_different_nova_net_id_is_set(self):
instance = self._get_instance()
share_network = dict(
id='fake_share_network', nova_net_id='foobar')
self.mock_object(instance.db, 'share_network_update')
self.mock_object(instance, '_allocate_network')
self.assertRaises(
exception.NetworkBadConfigurationException,
instance.allocate_network,
self.context, self.share_server, share_network, count=3)
instance.db.share_network_update.assert_has_calls([])
instance._allocate_network.assert_has_calls([])
@ddt.data(
dict(id='foo', neutron_net_id='bar'),
dict(id='foo', neutron_subnet_id='quuz'),
dict(id='foo', neutron_net_id='bar', neutron_subnet_id='quuz'))
def test_allocate_network_neutron_data_exist(self, sn):
instance = self._get_instance()
self.mock_object(instance.db, 'share_network_update')
self.mock_object(instance, '_allocate_network')
self.assertRaises(
exception.NetworkBadConfigurationException,
instance.allocate_network,
self.context, self.share_server, sn, count=3)
instance.db.share_network_update.assert_has_calls([])
instance._allocate_network.assert_has_calls([])

View File

@ -1187,7 +1187,6 @@ class HuaweiShareDriverTestCase(test.TestCase):
'cidr': '111.111.111.0/24',
'neutron_net_id': 'fake_neutron_net_id',
'neutron_subnet_id': 'fake_neutron_subnet_id',
'nova_net_id': '',
'security_services': '',
'network_allocations': self.fake_network_allocations,
'network_type': 'vlan',

View File

@ -420,17 +420,6 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
self.assertEqual('Default', result)
def test_create_ipspace_not_neutron(self):
self.library._client.features.IPSPACES = True
network_info = copy.deepcopy(fake.NETWORK_INFO)
network_info['neutron_subnet_id'] = None
network_info['nova_net_id'] = 'fake_nova_net_id'
result = self.library._create_ipspace(network_info)
self.assertEqual('Default', result)
def test_create_ipspace_already_present(self):
self.library._client.features.IPSPACES = True

View File

@ -2796,7 +2796,6 @@ class ShareManagerTestCase(test.TestCase):
cidr='fake_cidr',
neutron_net_id='fake_neutron_net_id',
neutron_subnet_id='fake_neutron_subnet_id',
nova_net_id='fake_nova_net_id',
security_services='fake_security_services',
network_type='fake_network_type')
expected = dict(
@ -2805,7 +2804,6 @@ class ShareManagerTestCase(test.TestCase):
cidr=fake_share_network['cidr'],
neutron_net_id=fake_share_network['neutron_net_id'],
neutron_subnet_id=fake_share_network['neutron_subnet_id'],
nova_net_id=fake_share_network['nova_net_id'],
security_services=fake_share_network['security_services'],
network_allocations=(
fake_network_allocations_get_for_share_server()),

View File

@ -30,7 +30,7 @@ ShareGroup = [
help="The minimum api microversion is configured to be the "
"value of the minimum microversion supported by Manila."),
cfg.StrOpt("max_api_microversion",
default="2.25",
default="2.26",
help="The maximum api microversion is configured to be the "
"value of the latest microversion supported by Manila."),
cfg.StrOpt("region",

View File

@ -118,7 +118,6 @@ class ShareNetworksNegativeTest(base.BaseSharesTest):
new_sn = self.create_share_network(
neutron_net_id=share_network['neutron_net_id'],
neutron_subnet_id=share_network['neutron_subnet_id'],
nova_net_id=share_network['nova_net_id'],
cleanup_in_class=False)
# Create share with share network

View File

@ -0,0 +1,5 @@
---
upgrade:
- Removed support for ``nova_net_id`` in share_networks API and in the
ShareNetwork DB model. Also removed the nova network plugins themselves
and corresponding manila.conf options.