Remove Nova Net option for share networks

Nova network was deprecated in Newton and is no longer supported for
regular deployments in Ocata [1].  In manila itself, changes [2] and
[3] remove nova network plugin support in manila services and remove
the nova-network-id field from the database model for share networks.

Add a new micro-version in which nova-network-id options are no longer
allowed when creating or modifying share networks.

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

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

Closes-Bug: #1656756

Change-Id: Ic27b7d26a5a7d1100e57ee8a857fc45fc3b0a909
This commit is contained in:
Tom Barron 2016-12-16 12:00:53 -05:00
parent 31cd7b16b1
commit 41505d0f89
9 changed files with 364 additions and 97 deletions

View File

@ -27,7 +27,7 @@ from manilaclient import utils
LOG = logging.getLogger(__name__)
MAX_VERSION = '2.24'
MAX_VERSION = '2.26'
MIN_VERSION = '2.0'
DEPRECATED_VERSION = '1.0'
_VERSIONED_METHOD_MAP = {}

View File

@ -200,7 +200,7 @@ class BaseTestCase(base.ClientTestBase):
@classmethod
def create_share_network(cls, name=None, description=None,
nova_net_id=None, neutron_net_id=None,
neutron_net_id=None,
neutron_subnet_id=None, client=None,
cleanup_in_class=True, microversion=None):
if client is None:
@ -208,7 +208,6 @@ class BaseTestCase(base.ClientTestBase):
share_network = client.create_share_network(
name=name,
description=description,
nova_net_id=nova_net_id,
neutron_net_id=neutron_net_id,
neutron_subnet_id=neutron_subnet_id,
microversion=microversion,

View File

@ -42,7 +42,6 @@ class ShareNetworksReadWriteTest(base.BaseTestCase):
@ddt.data(
{'name': data_utils.rand_name('autotest_share_network_name')},
{'description': 'fake_description'},
{'nova_net_id': 'fake_nova_net_id'},
{'neutron_net_id': 'fake_neutron_net_id',
'neutron_subnet_id': 'fake_neutron_subnet_id'},
)
@ -52,7 +51,6 @@ class ShareNetworksReadWriteTest(base.BaseTestCase):
expected_data = {
'name': 'None',
'description': 'None',
'nova_net_id': 'None',
'neutron_net_id': 'None',
'neutron_subnet_id': 'None',
}
@ -72,39 +70,13 @@ class ShareNetworksReadWriteTest(base.BaseTestCase):
self.assertEqual(self.neutron_net_id, get['neutron_net_id'])
self.assertEqual(self.neutron_subnet_id, get['neutron_subnet_id'])
# We did not set Nova data, so, we expect these fields to be set
# to None.
self.assertEqual('None', get['nova_net_id'])
def test_get_share_network_with_nova_data(self):
name = data_utils.rand_name('autotest')
description = 'fake_description'
nova_net_id = 'fake_nova_net_id'
create = self.create_share_network(
name=name,
description=description,
nova_net_id=nova_net_id,
cleanup_in_class=False)
self.assertEqual(name, create['name'])
self.assertEqual(description, create['description'])
self.assertEqual(nova_net_id, create['nova_net_id'])
# We did not set Neutron data, so, we expect these fields to be set
# to None.
self.assertEqual('None', create['neutron_net_id'])
self.assertEqual('None', create['neutron_subnet_id'])
@ddt.data(
{'name': data_utils.rand_name('autotest_share_network_name')},
{'description': 'fake_description'},
{'nova_net_id': 'fake_nova_net_id'},
{'neutron_net_id': 'fake_neutron_net_id',
'neutron_subnet_id': 'fake_neutron_subnet_id'},
{'name': '""'},
{'description': '""'},
{'nova_net_id': '""'},
{'neutron_net_id': '""'},
{'neutron_subnet_id': '""'},
)
@ -116,7 +88,6 @@ class ShareNetworksReadWriteTest(base.BaseTestCase):
expected_data = {
'name': 'None',
'description': 'None',
'nova_net_id': 'None',
'neutron_net_id': 'None',
'neutron_subnet_id': 'None',
}

View File

@ -14,7 +14,6 @@
from six.moves.urllib import parse
import manilaclient
from manilaclient import api_versions
from manilaclient.common import httpclient
from manilaclient.tests.unit import fakes
@ -25,16 +24,18 @@ from manilaclient.v2 import client
class FakeClient(fakes.FakeClient, client.Client):
def __init__(self, *args, **kwargs):
api_version = kwargs.get('version') or api_versions.MAX_VERSION
client.Client.__init__(self, 'username', 'password',
'project_id', 'auth_url',
extensions=kwargs.get('extensions'),
version=manilaclient.API_MAX_VERSION,)
version=api_version)
self.client = FakeHTTPClient(**kwargs)
class FakeHTTPClient(httpclient.HTTPClient):
def __init__(self, **kwargs):
api_version = kwargs.get('version') or api_versions.MAX_VERSION
self.username = 'username'
self.password = 'password'
self.auth_url = 'auth_url'
@ -42,7 +43,7 @@ class FakeHTTPClient(httpclient.HTTPClient):
self.base_url = 'localhost'
self.default_headers = {
'X-Auth-Token': 'xabc123',
'X-Openstack-Manila-Api-Version': api_versions.MAX_VERSION,
'X-Openstack-Manila-Api-Version': api_version,
'Accept': 'application/json',
}

View File

@ -12,14 +12,19 @@
# 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 itertools
import mock
from manilaclient import api_versions
from manilaclient import exceptions
from manilaclient.tests.unit import utils
from manilaclient.tests.unit.v2 import fakes
from manilaclient.v2 import share_networks
@ddt.ddt
class ShareNetworkTest(utils.TestCase):
class _FakeShareNetwork(object):
@ -39,17 +44,24 @@ class ShareNetworkTest(utils.TestCase):
'description': 'new whatever',
}
def test_create(self):
body_expected = {share_networks.RESOURCE_NAME: self.values}
@ddt.data("2.25", "2.26")
def test_create(self, microversion):
api_version = api_versions.APIVersion(microversion)
values = self.values.copy()
if (api_version >= api_versions.APIVersion("2.26")):
del(values['nova_net_id'])
body_expected = {share_networks.RESOURCE_NAME: values}
with mock.patch.object(self.manager, '_create', fakes.fake_create):
result = self.manager.create(**self.values)
manager = share_networks.ShareNetworkManager(
fakes.FakeClient(api_version=api_version))
with mock.patch.object(manager, '_create', fakes.fake_create):
result = manager.create(**values)
self.assertEqual(result['url'], share_networks.RESOURCES_PATH)
self.assertEqual(result['resp_key'], share_networks.RESOURCE_NAME)
self.assertEqual(
result['body'],
body_expected)
body_expected,
result['body'])
def test_delete_str(self):
share_nw = 'fake share nw'
@ -101,25 +113,25 @@ class ShareNetworkTest(utils.TestCase):
expected_path,
share_networks.RESOURCES_NAME)
def test_update_str(self):
share_nw = 'fake share nw'
body_expected = {share_networks.RESOURCE_NAME: self.values}
@ddt.data(*itertools.product(
["2.25", "2.26"],
['fake share nw', _FakeShareNetwork()]
))
@ddt.unpack
def test_update_share_network(self, microversion, share_nw):
api_version = api_versions.APIVersion(microversion)
values = self.values.copy()
if (api_version >= api_versions.APIVersion("2.26")):
del(values['nova_net_id'])
body_expected = {share_networks.RESOURCE_NAME: values}
with mock.patch.object(self.manager, '_update', fakes.fake_update):
result = self.manager.update(share_nw, **self.values)
manager = share_networks.ShareNetworkManager(
fakes.FakeClient(api_version=api_version))
with mock.patch.object(manager, '_update', fakes.fake_update):
result = manager.update(share_nw, **values)
id = share_nw.id if hasattr(share_nw, 'id') else share_nw
self.assertEqual(result['url'],
share_networks.RESOURCE_PATH % share_nw)
self.assertEqual(result['resp_key'], share_networks.RESOURCE_NAME)
self.assertEqual(result['body'], body_expected)
def test_update_obj(self):
share_nw = self._FakeShareNetwork()
body_expected = {share_networks.RESOURCE_NAME: self.values}
with mock.patch.object(self.manager, '_update', fakes.fake_update):
result = self.manager.update(share_nw, **self.values)
self.assertEqual(result['url'],
share_networks.RESOURCE_PATH % share_nw.id)
share_networks.RESOURCE_PATH % id)
self.assertEqual(result['resp_key'], share_networks.RESOURCE_NAME)
self.assertEqual(result['body'], body_expected)

View File

@ -95,8 +95,12 @@ class ShellTest(test_utils.TestCase):
client.get_client_class = self.old_get_client_class
super(ShellTest, self).tearDown()
def run_command(self, cmd):
self.shell.main(cmd.split())
def run_command(self, cmd, version=None):
if version:
args = ['--os-share-api-version', version] + cmd.split()
else:
args = cmd.split()
self.shell.main(args)
def assert_called(self, method, url, body=None, **kwargs):
return self.shell.cs.assert_called(method, url, body, **kwargs)
@ -1058,19 +1062,16 @@ class ShellTest(test_utils.TestCase):
{},
{'--name': 'fake_name'},
{'--description': 'fake_description'},
{'--nova_net_id': 'fake_nova_net_id'},
{'--neutron_net_id': 'fake_neutron_net_id'},
{'--neutron_subnet_id': 'fake_neutron_subnet_id'},
{'--description': 'fake_description',
'--name': 'fake_name',
'--neutron_net_id': 'fake_neutron_net_id',
'--neutron_subnet_id': 'fake_neutron_subnet_id',
'--nova_net_id': 'fake_nova_net_id'})
'--neutron_subnet_id': 'fake_neutron_subnet_id'})
def test_share_network_create(self, data):
cmd = 'share-network-create'
for k, v in data.items():
cmd += ' ' + k + ' ' + v
self.run_command(cmd)
self.assert_called('POST', '/share-networks')
@ -1078,24 +1079,21 @@ class ShellTest(test_utils.TestCase):
@ddt.data(
{'--name': 'fake_name'},
{'--description': 'fake_description'},
{'--nova_net_id': 'fake_nova_net_id'},
{'--neutron_net_id': 'fake_neutron_net_id'},
{'--neutron_subnet_id': 'fake_neutron_subnet_id'},
{'--description': 'fake_description',
'--name': 'fake_name',
'--neutron_net_id': 'fake_neutron_net_id',
'--neutron_subnet_id': 'fake_neutron_subnet_id',
'--nova_net_id': 'fake_nova_net_id'},
'--neutron_subnet_id': 'fake_neutron_subnet_id'},
{'--name': '""'},
{'--description': '""'},
{'--nova_net_id': '""'},
{'--neutron_net_id': '""'},
{'--neutron_subnet_id': '""'},
{'--description': '""',
'--name': '""',
'--neutron_net_id': '""',
'--neutron_subnet_id': '""',
'--nova_net_id': '""'},)
},)
def test_share_network_update(self, data):
cmd = 'share-network-update 1111'
expected = dict()
@ -1195,19 +1193,6 @@ class ShellTest(test_utils.TestCase):
mock.ANY,
fields=['id', 'name'])
@mock.patch.object(cliutils, 'print_list', mock.Mock())
def test_share_network_list_nova_net_id_aliases(self):
for command in ['--nova-net-id', '--nova-net_id',
'--nova_net-id', '--nova_net_id']:
self.run_command('share-network-list %s fake-id' % command)
self.assert_called(
'GET',
'/share-networks/detail?nova_net_id=fake-id',
)
cliutils.print_list.assert_called_with(
mock.ANY,
fields=['id', 'name'])
@mock.patch.object(cliutils, 'print_list', mock.Mock())
def test_share_network_list_neutron_net_id_aliases(self):
for command in ['--neutron-net-id', '--neutron-net_id',

View File

@ -20,6 +20,7 @@ except ImportError:
import six
from manilaclient import api_versions
from manilaclient import base
from manilaclient.common.apiclient import base as common_base
from manilaclient import exceptions
@ -49,6 +50,7 @@ class ShareNetworkManager(base.ManagerWithFind):
"""Manage :class:`ShareNetwork` resources."""
resource_class = ShareNetwork
@api_versions.wraps("1.0", "2.25")
def create(self, neutron_net_id=None, neutron_subnet_id=None,
nova_net_id=None, name=None, description=None):
"""Create share network.
@ -76,6 +78,31 @@ class ShareNetworkManager(base.ManagerWithFind):
return self._create(RESOURCES_PATH, body, RESOURCE_NAME)
@api_versions.wraps("2.26") # noqa
def create(self, neutron_net_id=None, neutron_subnet_id=None,
name=None, description=None):
"""Create share network.
:param neutron_net_id: ID of Neutron network
:param neutron_subnet_id: ID of Neutron subnet
:param name: share network name
:param description: share network description
:rtype: :class:`ShareNetwork`
"""
values = {}
if neutron_net_id:
values['neutron_net_id'] = neutron_net_id
if neutron_subnet_id:
values['neutron_subnet_id'] = neutron_subnet_id
if name:
values['name'] = name
if description:
values['description'] = description
body = {RESOURCE_NAME: values}
return self._create(RESOURCES_PATH, body, RESOURCE_NAME)
def add_security_service(self, share_network, security_service):
"""Associate given security service with a share network.
@ -121,6 +148,7 @@ class ShareNetworkManager(base.ManagerWithFind):
return self._get(RESOURCE_PATH % common_base.getid(share_network),
RESOURCE_NAME)
@api_versions.wraps("1.0", "2.25")
def update(self, share_network, neutron_net_id=None,
neutron_subnet_id=None, nova_net_id=None,
name=None, description=None):
@ -154,6 +182,38 @@ class ShareNetworkManager(base.ManagerWithFind):
body,
RESOURCE_NAME)
@api_versions.wraps("2.26") # noqa
def update(self, share_network, neutron_net_id=None,
neutron_subnet_id=None, name=None,
description=None):
"""Updates a share network.
:param share_network: share network to update.
:rtype: :class:`ShareNetwork`
"""
values = {}
if neutron_net_id is not None:
values['neutron_net_id'] = neutron_net_id
if neutron_subnet_id is not None:
values['neutron_subnet_id'] = neutron_subnet_id
if name is not None:
values['name'] = name
if description is not None:
values['description'] = description
for k, v in six.iteritems(values):
if v == '':
values[k] = None
if not values:
msg = "Must specify fields to be updated"
raise exceptions.CommandError(msg)
body = {RESOURCE_NAME: values}
return self._update(RESOURCE_PATH % common_base.getid(share_network),
body,
RESOURCE_NAME)
def delete(self, share_network):
"""Delete a share network.

View File

@ -1934,13 +1934,16 @@ def do_reset_state(cs, args):
share.reset_state(args.state)
@api_versions.wraps("1.0", "2.25")
@cliutils.arg(
'--nova-net-id',
'--nova-net_id', '--nova_net_id', '--nova_net-id', # aliases
metavar='<nova-net-id>',
default=None,
action='single_alias',
help="Nova net ID. Used to set up network for share servers.")
help="Nova net ID. Used to set up network for share servers. This "
"option is deprecated and will be rejected in newer releases "
"of OpenStack Manila.")
@cliutils.arg(
'--neutron-net-id',
'--neutron-net_id', '--neutron_net_id', '--neutron_net-id',
@ -1968,17 +1971,58 @@ def do_reset_state(cs, args):
help="Share network description.")
def do_share_network_create(cs, args):
"""Create description for network used by the tenant."""
values = dict(
neutron_net_id=args.neutron_net_id,
neutron_subnet_id=args.neutron_subnet_id,
nova_net_id=args.nova_net_id,
name=args.name,
description=args.description)
values = {
'neutron_net_id': args.neutron_net_id,
'neutron_subnet_id': args.neutron_subnet_id,
'nova_net_id': args.nova_net_id,
'name': args.name,
'description': args.description,
}
share_network = cs.share_networks.create(**values)
info = share_network._info.copy()
cliutils.print_dict(info)
@api_versions.wraps("2.26") # noqa
@cliutils.arg(
'--neutron-net-id',
'--neutron-net_id', '--neutron_net_id', '--neutron_net-id',
metavar='<neutron-net-id>',
default=None,
action='single_alias',
help="Neutron network ID. Used to set up network for share servers.")
@cliutils.arg(
'--neutron-subnet-id',
'--neutron-subnet_id', '--neutron_subnet_id', '--neutron_subnet-id',
metavar='<neutron-subnet-id>',
default=None,
action='single_alias',
help="Neutron subnet ID. Used to set up network for share servers. "
"This subnet should belong to specified neutron network.")
@cliutils.arg(
'--name',
metavar='<name>',
default=None,
help="Share network name.")
@cliutils.arg(
'--description',
metavar='<description>',
default=None,
help="Share network description.")
def do_share_network_create(cs, args):
"""Create description for network used by the tenant."""
values = {
'neutron_net_id': args.neutron_net_id,
'neutron_subnet_id': args.neutron_subnet_id,
'name': args.name,
'description': args.description,
}
share_network = cs.share_networks.create(**values)
info = share_network._info.copy()
cliutils.print_dict(info)
@api_versions.wraps("1.0", "2.25")
@cliutils.arg(
'share_network',
metavar='<share-network>',
@ -1989,7 +2033,9 @@ def do_share_network_create(cs, args):
metavar='<nova-net-id>',
default=None,
action='single_alias',
help="Nova net ID. Used to set up network for share servers.")
help="Nova net ID. Used to set up network for share servers. This "
"option is deprecated and will be rejected in newer releases "
"of OpenStack Manila.")
@cliutils.arg(
'--neutron-net-id',
'--neutron-net_id', '--neutron_net_id', '--neutron_net-id',
@ -2017,12 +2063,59 @@ def do_share_network_create(cs, args):
help="Share network description.")
def do_share_network_update(cs, args):
"""Update share network data."""
values = dict(
neutron_net_id=args.neutron_net_id,
neutron_subnet_id=args.neutron_subnet_id,
nova_net_id=args.nova_net_id,
name=args.name,
description=args.description)
values = {
'neutron_net_id': args.neutron_net_id,
'neutron_subnet_id': args.neutron_subnet_id,
'nova_net_id': args.nova_net_id,
'name': args.name,
'description': args.description,
}
share_network = _find_share_network(
cs, args.share_network).update(**values)
info = share_network._info.copy()
cliutils.print_dict(info)
@api_versions.wraps("2.26") # noqa
@cliutils.arg(
'share_network',
metavar='<share-network>',
help='Name or ID of share network to update.')
@cliutils.arg(
'--neutron-net-id',
'--neutron-net_id', '--neutron_net_id', '--neutron_net-id',
metavar='<neutron-net-id>',
default=None,
action='single_alias',
help="Neutron network ID. Used to set up network for share servers. This "
"option is deprecated and will be rejected in newer releases of "
"OpenStack Manila.")
@cliutils.arg(
'--neutron-subnet-id',
'--neutron-subnet_id', '--neutron_subnet_id', '--neutron_subnet-id',
metavar='<neutron-subnet-id>',
default=None,
action='single_alias',
help="Neutron subnet ID. Used to set up network for share servers. "
"This subnet should belong to specified neutron network.")
@cliutils.arg(
'--name',
metavar='<name>',
default=None,
help="Share network name.")
@cliutils.arg(
'--description',
metavar='<description>',
default=None,
help="Share network description.")
def do_share_network_update(cs, args):
"""Update share network data."""
values = {
'neutron_net_id': args.neutron_net_id,
'neutron_subnet_id': args.neutron_subnet_id,
'name': args.name,
'description': args.description,
}
share_network = _find_share_network(
cs, args.share_network).update(**values)
info = share_network._info.copy()
@ -2040,6 +2133,7 @@ def do_share_network_show(cs, args):
cliutils.print_dict(info)
@api_versions.wraps("1.0", "2.25")
@cliutils.arg(
'--all-tenants',
dest='all_tenants',
@ -2090,7 +2184,8 @@ def do_share_network_show(cs, args):
metavar='<nova_net_id>',
action='single_alias',
default=None,
help='Filter results by Nova net ID.')
help='Filter results by Nova net ID. This option is deprecated and will '
'be rejected in newer releases of OpenStack Manila.')
@cliutils.arg(
'--neutron-net-id',
'--neutron_net_id', '--neutron_net-id', '--neutron-net_id', # aliases
@ -2184,6 +2279,143 @@ def do_share_network_list(cs, args):
cliutils.print_list(share_networks, fields=fields)
@api_versions.wraps("2.26") # noqa
@cliutils.arg(
'--all-tenants',
dest='all_tenants',
metavar='<0|1>',
nargs='?',
type=int,
const=1,
default=0,
help='Display information from all tenants (Admin only).')
@cliutils.arg(
'--project-id',
'--project_id', # alias
metavar='<project_id>',
action='single_alias',
default=None,
help='Filter results by project ID.')
@cliutils.arg(
'--name',
metavar='<name>',
default=None,
help='Filter results by name.')
@cliutils.arg(
'--created-since',
'--created_since', # alias
metavar='<created_since>',
action='single_alias',
default=None,
help='''Return only share networks created since given date. '''
'''The date is in the format 'yyyy-mm-dd'.''')
@cliutils.arg(
'--created-before',
'--created_before', # alias
metavar='<created_before>',
action='single_alias',
default=None,
help='''Return only share networks created until given date. '''
'''The date is in the format 'yyyy-mm-dd'.''')
@cliutils.arg(
'--security-service',
'--security_service', # alias
metavar='<security_service>',
action='single_alias',
default=None,
help='Filter results by attached security service.')
@cliutils.arg(
'--neutron-net-id',
'--neutron_net_id', '--neutron_net-id', '--neutron-net_id', # aliases
metavar='<neutron_net_id>',
action='single_alias',
default=None,
help='Filter results by neutron net ID.')
@cliutils.arg(
'--neutron-subnet-id',
'--neutron_subnet_id', '--neutron-subnet_id', # aliases
'--neutron_subnet-id', # alias
metavar='<neutron_subnet_id>',
action='single_alias',
default=None,
help='Filter results by neutron subnet ID.')
@cliutils.arg(
'--network-type',
'--network_type', # alias
metavar='<network_type>',
action='single_alias',
default=None,
help='Filter results by network type.')
@cliutils.arg(
'--segmentation-id',
'--segmentation_id', # alias
metavar='<segmentation_id>',
type=int,
action='single_alias',
default=None,
help='Filter results by segmentation ID.')
@cliutils.arg(
'--cidr',
metavar='<cidr>',
default=None,
help='Filter results by CIDR.')
@cliutils.arg(
'--ip-version',
'--ip_version', # alias
metavar='<ip_version>',
type=int,
action='single_alias',
default=None,
help='Filter results by IP version.')
@cliutils.arg(
'--offset',
metavar='<offset>',
type=int,
default=None,
help='Start position of share networks listing.')
@cliutils.arg(
'--limit',
metavar='<limit>',
type=int,
default=None,
help='Number of share networks to return per request.')
@cliutils.arg(
'--columns',
metavar='<columns>',
type=str,
default=None,
help='Comma separated list of columns to be displayed '
'e.g. --columns "id"')
def do_share_network_list(cs, args):
"""Get a list of network info."""
all_tenants = int(os.environ.get("ALL_TENANTS", args.all_tenants))
search_opts = {
'all_tenants': all_tenants,
'project_id': args.project_id,
'name': args.name,
'created_since': args.created_since,
'created_before': args.created_before,
'neutron_net_id': args.neutron_net_id,
'neutron_subnet_id': args.neutron_subnet_id,
'network_type': args.network_type,
'segmentation_id': args.segmentation_id,
'cidr': args.cidr,
'ip_version': args.ip_version,
'offset': args.offset,
'limit': args.limit,
}
if args.security_service:
search_opts['security_service_id'] = _find_security_service(
cs, args.security_service).id
share_networks = cs.share_networks.list(search_opts=search_opts)
fields = ['id', 'name']
if args.columns is not None:
fields = _split_columns(columns=args.columns)
cliutils.print_list(share_networks, fields=fields)
@cliutils.arg(
'share_network',
metavar='<share-network>',

View File

@ -0,0 +1,7 @@
---
upgrade:
- |
Added new microversion in which ``nova-net-id`` option is no longer allowed
for share-network create or update commands. Nova networking was deprecated
in OpenStack in Newton and is no longer supported for general deployments in
Ocata.