From 3a03a0e10dfc797413536f8c8024c0ddf380f6c3 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Mon, 20 Mar 2017 19:39:35 -0400 Subject: [PATCH] Remove deprecated network APIs These were deprecated in Newton: aaebeb05a03e34281a091dc6dfc4672b01cdfbbb The 'find network' convenience helper when booting a server only works with neutron now, and assumes the 'network' endpoint is in the service catalog. The functional tests are changed to use python-neutronclient for listing and finding the network to use. At this point, we don't have any nova-network CI jobs that will work with novaclient, so the non-voting mitaka nova-network job is also being removed in change I63b36fb8acc5c9a273e6adcb271df16d0f71031e. As noted in the release note, the only remaining pure nova-network CLI/API that will work is for listing virtual interfaces, which is only implemented for nova-network within Nova. The functional tests for this API are removed since we don't have any nova-network CI jobs that will test it besides unit tests. Long-term we'll likely deprecate the os-virtual-interfaces API as well and replace it with the os-interface API. Change-Id: I8c520100a0016eed3959619c71dae037ebd72939 --- .../tests/functional/api/test_servers.py | 2 +- novaclient/tests/functional/base.py | 46 ++--- .../functional/v2/legacy/test_servers.py | 2 +- .../v2/legacy/test_virtual_interface.py | 30 ---- .../functional/v2/test_virtual_interface.py | 27 --- .../tests/unit/fixture_data/networks.py | 61 ------- novaclient/tests/unit/v2/fakes.py | 21 --- novaclient/tests/unit/v2/test_networks.py | 119 ------------- novaclient/tests/unit/v2/test_shell.py | 81 +-------- novaclient/v2/client.py | 20 --- novaclient/v2/networks.py | 157 +----------------- novaclient/v2/shell.py | 46 +---- ...ke-rm-deprecated-net-272aeb62b329a5bc.yaml | 6 +- test-requirements.txt | 1 + 14 files changed, 32 insertions(+), 587 deletions(-) delete mode 100644 novaclient/tests/functional/v2/legacy/test_virtual_interface.py delete mode 100644 novaclient/tests/functional/v2/test_virtual_interface.py delete mode 100644 novaclient/tests/unit/fixture_data/networks.py delete mode 100644 novaclient/tests/unit/v2/test_networks.py diff --git a/novaclient/tests/functional/api/test_servers.py b/novaclient/tests/functional/api/test_servers.py index 936bfeac9..4eca50671 100644 --- a/novaclient/tests/functional/api/test_servers.py +++ b/novaclient/tests/functional/api/test_servers.py @@ -33,4 +33,4 @@ class TestServersAPI(base.ClientTestBase): self.fail("Server %s did not go ACTIVE after 60s" % server) ips = self.client.servers.ips(server) - self.assertIn(self.network.label, ips) + self.assertIn(self.network.name, ips) diff --git a/novaclient/tests/functional/base.py b/novaclient/tests/functional/base.py index 864321c30..a374601f6 100644 --- a/novaclient/tests/functional/base.py +++ b/novaclient/tests/functional/base.py @@ -21,6 +21,7 @@ from keystoneauth1 import identity from keystoneauth1 import session as ksession from keystoneclient import client as keystoneclient from keystoneclient import discover as keystone_discover +from neutronclient.v2_0 import client as neutronclient import os_client_config from oslo_utils import uuidutils import tempest.lib.cli.base @@ -29,6 +30,7 @@ import testtools import novaclient import novaclient.api_versions import novaclient.client +from novaclient.v2 import networks import novaclient.v2.shell BOOT_IS_COMPLETE = ("login as 'cirros' user. default password: " @@ -79,7 +81,7 @@ def pick_network(networks): network_name = os.environ.get('OS_NOVACLIENT_NETWORK') if network_name: for network in networks: - if network.label == network_name: + if network.name == network_name: return network raise NoNetworkException() return networks[0] @@ -224,21 +226,20 @@ class ClientTestBase(testtools.TestCase): self.image = CACHE["image"] if "network" not in CACHE: - tested_api_version = self.client.api_version - proxy_api_version = novaclient.api_versions.APIVersion('2.35') - if tested_api_version > proxy_api_version: - self.client.api_version = proxy_api_version - try: - # TODO(mriedem): Get the networks from neutron if using neutron - networks = self.client.networks.list() - # Keep track of whether or not there are multiple networks - # available to the given tenant because if so, a specific - # network ID has to be passed in on server create requests - # otherwise the server POST will fail with a 409. - CACHE['multiple_networks'] = len(networks) > 1 - CACHE["network"] = pick_network(networks) - finally: - self.client.api_version = tested_api_version + # Get the networks from neutron. + neutron = neutronclient.Client(session=session) + neutron_networks = neutron.list_networks()['networks'] + # Convert the neutron dicts to Network objects. + nets = [] + for network in neutron_networks: + nets.append(networks.Network( + networks.NeutronManager, network)) + # Keep track of whether or not there are multiple networks + # available to the given tenant because if so, a specific + # network ID has to be passed in on server create requests + # otherwise the server POST will fail with a 409. + CACHE['multiple_networks'] = len(nets) > 1 + CACHE["network"] = pick_network(nets) self.network = CACHE["network"] self.multiple_networks = CACHE['multiple_networks'] @@ -264,15 +265,6 @@ class ClientTestBase(testtools.TestCase): password=passwd) self.cinder = cinderclient.Client(auth=auth, session=session) - if "use_neutron" not in CACHE: - # check to see if we're running with neutron or not - for service in self.keystone.services.list(): - if service.type == 'network': - CACHE["use_neutron"] = True - break - else: - CACHE["use_neutron"] = False - def _get_novaclient(self, session): nc = novaclient.client.Client("2", session=session) @@ -500,10 +492,6 @@ class ClientTestBase(testtools.TestCase): project = self.keystone.tenants.find(name=name) return project.id - def skip_if_neutron(self): - if CACHE["use_neutron"]: - self.skipTest('nova-network is not available') - def _cleanup_server(self, server_id): """Deletes a server and waits for it to be gone.""" self.client.servers.delete(server_id) diff --git a/novaclient/tests/functional/v2/legacy/test_servers.py b/novaclient/tests/functional/v2/legacy/test_servers.py index 86280e1b6..86d035ae6 100644 --- a/novaclient/tests/functional/v2/legacy/test_servers.py +++ b/novaclient/tests/functional/v2/legacy/test_servers.py @@ -67,7 +67,7 @@ class TestServersBootNovaClient(base.ClientTestBase): "--nic net-name=%(net-name)s" % {"name": uuidutils.generate_uuid(), "image": self.image.id, "flavor": self.flavor.id, - "net-name": self.network.label})) + "net-name": self.network.name})) server_id = self._get_value_from_the_table(server_info, "id") self.client.servers.delete(server_id) diff --git a/novaclient/tests/functional/v2/legacy/test_virtual_interface.py b/novaclient/tests/functional/v2/legacy/test_virtual_interface.py deleted file mode 100644 index 8e934f650..000000000 --- a/novaclient/tests/functional/v2/legacy/test_virtual_interface.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2015 IBM Corp. -# 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 novaclient.tests.functional import base - - -class TestVirtualInterfacesNovaClient(base.ClientTestBase): - """Virtual Interfaces functional tests.""" - - COMPUTE_API_VERSION = "2.1" - - def test_virtual_interface_list(self): - # os-virtual-interfaces does not proxy to neutron - self.skip_if_neutron() - server = self._create_server() - output = self.nova('virtual-interface-list %s' % server.id) - self.assertTrue(len(output.split("\n")) > 5, - "Output table of `virtual-interface-list` for the test" - " server should not be empty.") - return output diff --git a/novaclient/tests/functional/v2/test_virtual_interface.py b/novaclient/tests/functional/v2/test_virtual_interface.py deleted file mode 100644 index cef930266..000000000 --- a/novaclient/tests/functional/v2/test_virtual_interface.py +++ /dev/null @@ -1,27 +0,0 @@ -# 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 novaclient.tests.functional.v2.legacy import test_virtual_interface - - -class TestVirtualInterfacesNovaClient( - test_virtual_interface.TestVirtualInterfacesNovaClient): - """Virtual Interfaces functional tests.""" - - COMPUTE_API_VERSION = "2.latest" - - def test_virtual_interface_list(self): - output = super(TestVirtualInterfacesNovaClient, - self).test_virtual_interface_list() - self.assertEqual(self.network.id, - self._get_column_value_from_single_row_table( - output, "Network ID")) diff --git a/novaclient/tests/unit/fixture_data/networks.py b/novaclient/tests/unit/fixture_data/networks.py deleted file mode 100644 index 51a4676fe..000000000 --- a/novaclient/tests/unit/fixture_data/networks.py +++ /dev/null @@ -1,61 +0,0 @@ -# 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 novaclient.tests.unit.fixture_data import base - - -class Fixture(base.Fixture): - - base_url = 'os-networks' - - def setUp(self): - super(Fixture, self).setUp() - - get_os_networks = { - 'networks': [ - { - "label": "1", - "cidr": "10.0.0.0/24", - 'project_id': '4ffc664c198e435e9853f2538fbcd7a7', - 'id': '1' - } - ] - } - - headers = self.json_headers - - self.requests_mock.get(self.url(), - json=get_os_networks, - headers=headers) - - def post_os_networks(request, context): - return {'network': request.json()} - - self.requests_mock.post(self.url(), - json=post_os_networks, - headers=headers) - - get_os_networks_1 = {'network': {"label": "1", "cidr": "10.0.0.0/24"}} - - self.requests_mock.get(self.url(1), - json=get_os_networks_1, - headers=headers) - - self.requests_mock.delete(self.url('networkdelete'), - status_code=202, - headers=headers) - - for u in ('add', 'networkdisassociate/action', 'networktest/action', - '1/action', '2/action'): - self.requests_mock.post(self.url(u), - status_code=202, - headers=headers) diff --git a/novaclient/tests/unit/v2/fakes.py b/novaclient/tests/unit/v2/fakes.py index 465485548..1aaf76d4f 100644 --- a/novaclient/tests/unit/v2/fakes.py +++ b/novaclient/tests/unit/v2/fakes.py @@ -1781,27 +1781,6 @@ class FakeSessionClient(base_client.SessionClient): return (200, {}, {"networks": networks_by_name[name]}) - def get_os_networks(self, **kw): - return (200, {}, {'networks': [{"label": "1", "cidr": "10.0.0.0/24", - 'project_id': - '4ffc664c198e435e9853f2538fbcd7a7', - 'id': '1', 'vlan': '1234'}]}) - - def delete_os_networks_1(self, **kw): - return (202, {}, None) - - def post_os_networks(self, **kw): - return (202, {}, {'network': kw}) - - def post_os_networks_add(self, **kw): - return (202, {}, None) - - def post_os_networks_1_action(self, **kw): - return (202, {}, None) - - def post_os_networks_2_action(self, **kw): - return (202, {}, None) - def get_os_availability_zone_detail(self, **kw): return (200, {}, { "availabilityZoneInfo": [ diff --git a/novaclient/tests/unit/v2/test_networks.py b/novaclient/tests/unit/v2/test_networks.py deleted file mode 100644 index 1b17af660..000000000 --- a/novaclient/tests/unit/v2/test_networks.py +++ /dev/null @@ -1,119 +0,0 @@ -# -# 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 novaclient.tests.unit.fixture_data import client -from novaclient.tests.unit.fixture_data import networks as data -from novaclient.tests.unit import utils -from novaclient.tests.unit.v2 import fakes -from novaclient.v2 import networks - - -class NetworksTest(utils.FixturedTestCase): - - client_fixture_class = client.V1 - data_fixture_class = data.Fixture - - def test_list_networks(self): - fl = self.cs.networks.list() - self.assert_request_id(fl, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('GET', '/os-networks') - for f in fl: - self.assertIsInstance(f, networks.Network) - - def test_get_network(self): - f = self.cs.networks.get(1) - self.assert_request_id(f, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('GET', '/os-networks/1') - self.assertIsInstance(f, networks.Network) - - def test_delete(self): - ret = self.cs.networks.delete('networkdelete') - self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('DELETE', '/os-networks/networkdelete') - - def test_create(self): - f = self.cs.networks.create(label='foo') - self.assert_request_id(f, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('POST', '/os-networks', - {'network': {'label': 'foo'}}) - self.assertIsInstance(f, networks.Network) - - def test_create_allparams(self): - params = { - 'label': 'bar', - 'bridge': 'br0', - 'bridge_interface': 'int0', - 'cidr': '192.0.2.0/24', - 'cidr_v6': '2001:DB8::/32', - 'dns1': '1.1.1.1', - 'dns2': '1.1.1.2', - 'fixed_cidr': '198.51.100.0/24', - 'gateway': '192.0.2.1', - 'gateway_v6': '2001:DB8::1', - 'multi_host': 'T', - 'priority': '1', - 'project_id': '1', - 'vlan': 5, - 'vlan_start': 1, - 'vpn_start': 1, - 'mtu': 1500, - 'enable_dhcp': 'T', - 'dhcp_server': '1920.2.2', - 'share_address': 'T', - 'allowed_start': '192.0.2.10', - 'allowed_end': '192.0.2.20', - } - - f = self.cs.networks.create(**params) - self.assert_request_id(f, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('POST', '/os-networks', {'network': params}) - self.assertIsInstance(f, networks.Network) - - def test_associate_project(self): - f = self.cs.networks.associate_project('networktest') - self.assert_request_id(f, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('POST', '/os-networks/add', - {'id': 'networktest'}) - - def test_associate_host(self): - f = self.cs.networks.associate_host('networktest', 'testHost') - self.assert_request_id(f, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('POST', '/os-networks/networktest/action', - {'associate_host': 'testHost'}) - - def test_disassociate(self): - f = self.cs.networks.disassociate('networkdisassociate') - self.assert_request_id(f, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('POST', - '/os-networks/networkdisassociate/action', - {'disassociate': None}) - - def test_disassociate_host_only(self): - f = self.cs.networks.disassociate('networkdisassociate', True, False) - self.assert_request_id(f, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('POST', - '/os-networks/networkdisassociate/action', - {'disassociate_host': None}) - - def test_disassociate_project(self): - f = self.cs.networks.disassociate('networkdisassociate', False, True) - self.assert_request_id(f, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('POST', - '/os-networks/networkdisassociate/action', - {'disassociate_project': None}) - - def test_add(self): - f = self.cs.networks.add('networkadd') - self.assert_request_id(f, fakes.FAKE_REQUEST_ID_LIST) - self.assert_called('POST', '/os-networks/add', - {'id': 'networkadd'}) diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py index b3fbacc00..266b89a6e 100644 --- a/novaclient/tests/unit/v2/test_shell.py +++ b/novaclient/tests/unit/v2/test_shell.py @@ -822,61 +822,7 @@ class ShellTest(utils.TestCase): '--nic net-id=net-id1,net-id=net-id2 some-server' % FAKE_UUID_1) self.assertRaises(exceptions.CommandError, self.run_command, cmd) - @mock.patch('novaclient.v2.client.Client.has_neutron', return_value=False) - def test_boot_nics_net_name(self, has_neutron): - cmd = ('boot --image %s --flavor 1 ' - '--nic net-name=1 some-server' % FAKE_UUID_1) - self.run_command(cmd) - self.assert_called_anytime( - 'POST', '/servers', - { - 'server': { - 'flavorRef': '1', - 'name': 'some-server', - 'imageRef': FAKE_UUID_1, - 'min_count': 1, - 'max_count': 1, - 'networks': [ - {'uuid': '1'}, - ], - }, - }, - ) - - @mock.patch('novaclient.v2.client.Client.has_neutron', return_value=False) - def test_boot_nics_net_name_nova_net_2_36(self, has_neutron): - orig_find_network = novaclient.v2.shell._find_network_id_novanet - - def stubbed_find_network(cs, net_name): - # assert that we dropped back to 2.35 - self.assertEqual(api_versions.APIVersion('2.35'), - cs.client.api_version) - return orig_find_network(cs, net_name) - - cmd = ('boot --image %s --flavor 1 ' - '--nic net-name=1 some-server' % FAKE_UUID_1) - with mock.patch.object(novaclient.v2.shell, '_find_network_id_novanet', - side_effect=stubbed_find_network) as find_net: - self.run_command(cmd, api_version='2.36') - find_net.assert_called_once_with(self.shell.cs, '1') - self.assert_called_anytime( - 'POST', '/servers', - { - 'server': { - 'flavorRef': '1', - 'name': 'some-server', - 'imageRef': FAKE_UUID_1, - 'min_count': 1, - 'max_count': 1, - 'networks': [ - {'uuid': '1'}, - ], - }, - }, - ) - - @mock.patch('novaclient.v2.client.Client.has_neutron', return_value=True) - def test_boot_nics_net_name_neutron(self, has_neutron): + def test_boot_nics_net_name_neutron(self): cmd = ('boot --image %s --flavor 1 ' '--nic net-name=private some-server' % FAKE_UUID_1) self.run_command(cmd) @@ -896,8 +842,7 @@ class ShellTest(utils.TestCase): }, ) - @mock.patch('novaclient.v2.client.Client.has_neutron', return_value=True) - def test_boot_nics_net_name_neutron_dup(self, has_neutron): + def test_boot_nics_net_name_neutron_dup(self): cmd = ('boot --image %s --flavor 1 ' '--nic net-name=duplicate some-server' % FAKE_UUID_1) # this should raise a multiple matches error @@ -906,8 +851,7 @@ class ShellTest(utils.TestCase): with testtools.ExpectedException(exceptions.CommandError, msg): self.run_command(cmd) - @mock.patch('novaclient.v2.client.Client.has_neutron', return_value=True) - def test_boot_nics_net_name_neutron_blank(self, has_neutron): + def test_boot_nics_net_name_neutron_blank(self): cmd = ('boot --image %s --flavor 1 ' '--nic net-name=blank some-server' % FAKE_UUID_1) # this should raise a multiple matches error @@ -919,25 +863,6 @@ class ShellTest(utils.TestCase): # out other tests, and they should check the string in the # CommandError, because it's not really enough to distinguish # between various errors. - @mock.patch('novaclient.v2.client.Client.has_neutron', return_value=False) - def test_boot_nics_net_name_not_found(self, has_neutron): - cmd = ('boot --image %s --flavor 1 ' - '--nic net-name=some-net some-server' % FAKE_UUID_1) - self.assertRaises(exceptions.ResourceNotFound, self.run_command, cmd) - - @mock.patch('novaclient.v2.client.Client.has_neutron', return_value=False) - @mock.patch( - 'novaclient.tests.unit.v2.fakes.FakeSessionClient.get_os_networks') - def test_boot_nics_net_name_multiple_matches(self, mock_networks_list, - has_neutron): - mock_networks_list.return_value = (200, {}, { - 'networks': [{"label": "some-net", 'id': '1'}, - {"label": "some-net", 'id': '2'}]}) - - cmd = ('boot --image %s --flavor 1 ' - '--nic net-name=some-net some-server' % FAKE_UUID_1) - self.assertRaises(exceptions.NoUniqueMatch, self.run_command, cmd) - @mock.patch('novaclient.v2.shell._find_network_id', return_value='net-id') def test_boot_nics_net_name_and_net_id(self, mock_find_network_id): cmd = ('boot --image %s --flavor 1 ' diff --git a/novaclient/v2/client.py b/novaclient/v2/client.py index 4b504853d..b85077392 100644 --- a/novaclient/v2/client.py +++ b/novaclient/v2/client.py @@ -15,8 +15,6 @@ import logging -from keystoneauth1.exceptions import catalog as key_ex - from novaclient import client from novaclient import exceptions from novaclient.i18n import _ @@ -155,7 +153,6 @@ class Client(object): self.certs = certs.CertificateManager(self) self.volumes = volumes.VolumeManager(self) self.keypairs = keypairs.KeypairManager(self) - self.networks = networks.NetworkManager(self) self.neutron = networks.NeutronManager(self) self.quota_classes = quota_classes.QuotaClassSetManager(self) self.quotas = quotas.QuotaSetManager(self) @@ -278,23 +275,6 @@ class Client(object): def reset_timings(self): self.client.reset_timings() - def has_neutron(self): - """Check the service catalog to figure out if we have neutron. - - This is an intermediary solution for the window of time where - we still have nova-network support in the client, but we - expect most people have neutron. This ensures that if they - have neutron we understand, we talk to it, if they don't, we - fail back to nova proxies. - """ - try: - endpoint = self.client.get_endpoint(service_type='network') - if endpoint: - return True - return False - except key_ex.EndpointNotFound: - return False - def authenticate(self): """Authenticate against the server. diff --git a/novaclient/v2/networks.py b/novaclient/v2/networks.py index 36a694232..8c1b923d5 100644 --- a/novaclient/v2/networks.py +++ b/novaclient/v2/networks.py @@ -16,7 +16,6 @@ """ Network interface. """ -from novaclient import api_versions from novaclient import base from novaclient import exceptions from novaclient.i18n import _ @@ -24,21 +23,13 @@ from novaclient.i18n import _ class Network(base.Resource): """ - A network. + A network as defined in the Networking (Neutron) API. """ HUMAN_ID = True - NAME_ATTR = "label" + NAME_ATTR = "name" def __repr__(self): - return "" % self.label - - def delete(self): - """ - DEPRECATED: Delete this network. - - :returns: An instance of novaclient.base.TupleWithMeta - """ - return self.manager.delete(self) + return "" % self.name class NeutronManager(base.Manager): @@ -72,145 +63,3 @@ class NeutronManager(base.Manager): else: matches[0].append_request_ids(matches.request_ids) return matches[0] - - -class NetworkManager(base.ManagerWithFind): - """ - DEPRECATED: Manage :class:`Network` resources. - """ - resource_class = Network - - @api_versions.deprecated_after('2.35') - def list(self): - """ - DEPRECATED: Get a list of all networks. - - :rtype: list of :class:`Network`. - """ - return self._list("/os-networks", "networks") - - @api_versions.deprecated_after('2.35') - def get(self, network): - """ - DEPRECATED: Get a specific network. - - :param network: The ID of the :class:`Network` to get. - :rtype: :class:`Network` - """ - return self._get("/os-networks/%s" % base.getid(network), - "network") - - @api_versions.deprecated_after('2.35') - def delete(self, network): - """ - DEPRECATED: Delete a specific network. - - :param network: The ID of the :class:`Network` to delete. - :returns: An instance of novaclient.base.TupleWithMeta - """ - return self._delete("/os-networks/%s" % base.getid(network)) - - @api_versions.deprecated_after('2.35') - def create(self, **kwargs): - """ - DEPRECATED: Create (allocate) a network. The following parameters are - optional except for label; cidr or cidr_v6 must be specified, too. - - :param label: str - :param bridge: str - :param bridge_interface: str - :param cidr: str - :param cidr_v6: str - :param dns1: str - :param dns2: str - :param fixed_cidr: str - :param gateway: str - :param gateway_v6: str - :param multi_host: str - :param priority: str - :param project_id: str - :param vlan: int - :param vlan_start: int - :param vpn_start: int - :param mtu: int - :param enable_dhcp: int - :param dhcp_server: str - :param share_address: int - :param allowed_start: str - :param allowed_end: str - - :rtype: object of :class:`Network` - """ - body = {"network": kwargs} - return self._create('/os-networks', body, 'network') - - @api_versions.deprecated_after('2.35') - def disassociate(self, network, disassociate_host=True, - disassociate_project=True): - """ - DEPRECATED: Disassociate a specific network from project and/or host. - - :param network: The ID of the :class:`Network`. - :param disassociate_host: Whether to disassociate the host - :param disassociate_project: Whether to disassociate the project - :returns: An instance of novaclient.base.TupleWithMeta - """ - if disassociate_host and disassociate_project: - body = {"disassociate": None} - elif disassociate_project: - body = {"disassociate_project": None} - elif disassociate_host: - body = {"disassociate_host": None} - else: - raise exceptions.CommandError( - _("Must disassociate either host or project or both")) - - resp, body = self.api.client.post("/os-networks/%s/action" % - base.getid(network), body=body) - - return self.convert_into_with_meta(body, resp) - - @api_versions.deprecated_after('2.35') - def associate_host(self, network, host): - """ - DEPRECATED: Associate a specific network with a host. - - :param network: The ID of the :class:`Network`. - :param host: The name of the host to associate the network with - :returns: An instance of novaclient.base.TupleWithMeta - """ - resp, body = self.api.client.post("/os-networks/%s/action" % - base.getid(network), - body={"associate_host": host}) - - return self.convert_into_with_meta(body, resp) - - @api_versions.deprecated_after('2.35') - def associate_project(self, network): - """ - DEPRECATED: Associate a specific network with a project. - - The project is defined by the project authenticated against - - :param network: The ID of the :class:`Network`. - :returns: An instance of novaclient.base.TupleWithMeta - """ - resp, body = self.api.client.post("/os-networks/add", - body={"id": network}) - - return self.convert_into_with_meta(body, resp) - - @api_versions.deprecated_after('2.35') - def add(self, network=None): - """ - DEPRECATED: Associates the current project with a network. Network can - be chosen automatically or provided explicitly. - - :param network: The ID of the :class:`Network` to associate (optional). - :returns: An instance of novaclient.base.TupleWithMeta - """ - resp, body = self.api.client.post("/os-networks/add", - body={"id": base.getid(network) - if network else None}) - - return self.convert_into_with_meta(body, resp) diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py index bf3bcc96b..6b525521d 100644 --- a/novaclient/v2/shell.py +++ b/novaclient/v2/shell.py @@ -2037,7 +2037,7 @@ def _find_flavor(cs, flavor): return cs.flavors.find(ram=flavor) -def _find_network_id_neutron(cs, net_name): +def _find_network_id(cs, net_name): """Get unique network ID from network name from neutron""" try: return cs.neutron.find_network(net_name).id @@ -2045,50 +2045,6 @@ def _find_network_id_neutron(cs, net_name): raise exceptions.CommandError(six.text_type(e)) -def _find_network_id(cs, net_name): - """Find the network id for a network name. - - If we have access to neutron in the service catalog, use neutron - for this lookup, otherwise use nova. This ensures that we do the - right thing in the future. - - Once nova network support is deleted, we can delete this check and - the has_neutron function. - """ - if cs.has_neutron(): - return _find_network_id_neutron(cs, net_name) - else: - # The network proxy API methods were deprecated in 2.36 and will return - # a 404 so we fallback to 2.35 to maintain a transition for CLI users. - want_version = api_versions.APIVersion('2.35') - cur_version = cs.api_version - if cs.api_version > want_version: - cs.api_version = want_version - try: - return _find_network_id_novanet(cs, net_name) - finally: - cs.api_version = cur_version - - -def _find_network_id_novanet(cs, net_name): - """Get unique network ID from network name.""" - network_id = None - for net_info in cs.networks.list(): - if net_name == net_info.label: - if network_id is not None: - msg = (_("Multiple network name matches found for name '%s', " - "use network ID to be more specific.") % net_name) - raise exceptions.NoUniqueMatch(msg) - else: - network_id = net_info.id - - if network_id is None: - msg = (_("No network name match for name '%s'") % net_name) - raise exceptions.ResourceNotFound(msg % {'network': net_name}) - else: - return network_id - - @utils.arg('server', metavar='', help=_('Name or ID of server.')) @utils.arg( 'network_id', diff --git a/releasenotes/notes/pike-rm-deprecated-net-272aeb62b329a5bc.yaml b/releasenotes/notes/pike-rm-deprecated-net-272aeb62b329a5bc.yaml index fa2faf379..1798debe4 100644 --- a/releasenotes/notes/pike-rm-deprecated-net-272aeb62b329a5bc.yaml +++ b/releasenotes/notes/pike-rm-deprecated-net-272aeb62b329a5bc.yaml @@ -1,6 +1,9 @@ --- prelude: > - Deprecated network-related resource commands have been removed. + Deprecated network-related resource commands and python API bindings + have been removed. From this point on, python-novaclient will no longer + work with nova-network *except* for the ``nova virtual-interface-list`` + command. upgrade: - | The following deprecated network-related resource commands have been @@ -61,6 +64,7 @@ upgrade: * novaclient.v2.floating_ips * novaclient.v2.floating_ips_bulk * novaclient.v2.fping + * novaclient.v2.networks * novaclient.v2.security_group_default_rules * novaclient.v2.security_group_rules * novaclient.v2.security_groups diff --git a/test-requirements.txt b/test-requirements.txt index bf0a5f559..7d4b1391d 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -11,6 +11,7 @@ mock>=2.0 # BSD python-keystoneclient>=3.8.0 # Apache-2.0 python-cinderclient>=2.0.1 # Apache-2.0 python-glanceclient>=2.5.0 # Apache-2.0 +python-neutronclient>=5.1.0 # Apache-2.0 requests-mock>=1.1 # Apache-2.0 sphinx>=1.5.1 # BSD os-client-config>=1.22.0 # Apache-2.0