From eef8473fa868323d4975e624341a2f1834a0ed03 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Thu, 5 Sep 2013 15:19:31 -0700 Subject: [PATCH] Revert baremetal v3 API extension Baremetal is scheduled to be deprecated in Nova soon. Since the V3 API is experimental in Havana, we should revert the extension to avoid maintenance of the extension and its tests for no real gain. Things have changed enough since it was added that a simple git-revert won't work. This reverts the following changes: 5de5ae1b5d3763dbcf14bf3b4d43199ad5255adf 92c9975bd2d53624ae595b895c2e96991ee43778 2382186311794591fb4d35893ffa774157d6131b Mailing list discussion: http://lists.openstack.org/pipermail/openstack-dev/2013-September/014614.html Change-Id: I3bdc7234f91eb4f9078ee24d7ab093b28f9930c9 --- etc/nova/policy.json | 2 - .../compute/plugins/v3/baremetal_nodes.py | 231 ------------------ .../plugins/v3/test_baremetal_nodes.py | 220 ----------------- nova/tests/fake_policy.py | 1 - setup.cfg | 1 - 5 files changed, 455 deletions(-) delete mode 100644 nova/api/openstack/compute/plugins/v3/baremetal_nodes.py delete mode 100644 nova/tests/api/openstack/compute/plugins/v3/test_baremetal_nodes.py diff --git a/etc/nova/policy.json b/etc/nova/policy.json index e2e0e0337269..5cbefb200dde 100644 --- a/etc/nova/policy.json +++ b/etc/nova/policy.json @@ -61,8 +61,6 @@ "compute_extension:v3:os-attach-interfaces": "", "compute_extension:v3:os-attach-interfaces:discoverable": "", "compute_extension:baremetal_nodes": "rule:admin_api", - "compute_extension:v3:os-baremetal-nodes": "rule:admin_api", - "compute_extension:v3:os-baremetal-nodes:discoverable": "", "compute_extension:cells": "rule:admin_api", "compute_extension:v3:os-cells": "rule:admin_api", "compute_extension:v3:os-cells:discoverable": "", diff --git a/nova/api/openstack/compute/plugins/v3/baremetal_nodes.py b/nova/api/openstack/compute/plugins/v3/baremetal_nodes.py deleted file mode 100644 index bebdd3ab8a7f..000000000000 --- a/nova/api/openstack/compute/plugins/v3/baremetal_nodes.py +++ /dev/null @@ -1,231 +0,0 @@ -# Copyright (c) 2013 NTT DOCOMO, 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. - -"""The bare-metal admin extension.""" - -import webob - -from nova.api.openstack import extensions -from nova.api.openstack import wsgi -from nova.api.openstack import xmlutil -from nova import exception -from nova.openstack.common.gettextutils import _ -from nova.virt.baremetal import db - -ALIAS = 'os-baremetal-nodes' -authorize = extensions.extension_authorizer('compute', - 'v3:' + ALIAS) - -node_fields = ['id', 'cpus', 'local_gb', 'memory_mb', 'pm_address', - 'pm_user', - 'service_host', 'terminal_port', 'instance_uuid', - ] - -interface_fields = ['id', 'address', 'datapath_id', 'port_no'] - - -def _node_dict(node_ref): - d = {} - for f in node_fields: - d[f] = node_ref.get(f) - return d - - -def _interface_dict(interface_ref): - d = {} - for f in interface_fields: - d[f] = interface_ref.get(f) - return d - - -def _make_node_elem(elem): - for f in node_fields: - elem.set(f) - - -def _make_interface_elem(elem): - for f in interface_fields: - elem.set(f) - - -class NodeTemplate(xmlutil.TemplateBuilder): - def construct(self): - node_elem = xmlutil.TemplateElement('node', selector='node') - _make_node_elem(node_elem) - ifs_elem = xmlutil.TemplateElement('interfaces') - if_elem = xmlutil.SubTemplateElement(ifs_elem, 'interface', - selector='interfaces') - _make_interface_elem(if_elem) - node_elem.append(ifs_elem) - return xmlutil.MasterTemplate(node_elem, 1) - - -class NodesTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('nodes') - node_elem = xmlutil.SubTemplateElement(root, 'node', selector='nodes') - _make_node_elem(node_elem) - ifs_elem = xmlutil.TemplateElement('interfaces') - if_elem = xmlutil.SubTemplateElement(ifs_elem, 'interface', - selector='interfaces') - _make_interface_elem(if_elem) - node_elem.append(ifs_elem) - return xmlutil.MasterTemplate(root, 1) - - -class InterfaceTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('interface', selector='interface') - _make_interface_elem(root) - return xmlutil.MasterTemplate(root, 1) - - -class BareMetalNodeController(wsgi.Controller): - """The Bare-Metal Node API controller for the OpenStack API.""" - - @extensions.expected_errors(()) - @wsgi.serializers(xml=NodesTemplate) - def index(self, req): - context = req.environ['nova.context'] - authorize(context) - nodes_from_db = db.bm_node_get_all(context) - nodes = [] - for node_from_db in nodes_from_db: - try: - ifs = db.bm_interface_get_all_by_bm_node_id( - context, node_from_db['id']) - except exception.NodeNotFound: - ifs = [] - node = _node_dict(node_from_db) - node['interfaces'] = [_interface_dict(i) for i in ifs] - nodes.append(node) - return {'nodes': nodes} - - @extensions.expected_errors(404) - @wsgi.serializers(xml=NodeTemplate) - def show(self, req, id): - context = req.environ['nova.context'] - authorize(context) - try: - node = db.bm_node_get(context, id) - except exception.NodeNotFound as e: - raise webob.exc.HTTPNotFound(explanation=e.format_message()) - try: - ifs = db.bm_interface_get_all_by_bm_node_id(context, id) - except exception.NodeNotFound: - ifs = [] - node = _node_dict(node) - node['interfaces'] = [_interface_dict(i) for i in ifs] - return {'node': node} - - @extensions.expected_errors(()) - @wsgi.serializers(xml=NodeTemplate) - @wsgi.response(201) - def create(self, req, body): - context = req.environ['nova.context'] - authorize(context) - values = body['node'].copy() - prov_mac_address = values.pop('prov_mac_address', None) - node = db.bm_node_create(context, values) - node = _node_dict(node) - if prov_mac_address: - if_id = db.bm_interface_create(context, - bm_node_id=node['id'], - address=prov_mac_address, - datapath_id=None, - port_no=None) - if_ref = db.bm_interface_get(context, if_id) - node['interfaces'] = [_interface_dict(if_ref)] - else: - node['interfaces'] = [] - return {'node': node} - - @extensions.expected_errors(404) - def delete(self, req, id): - context = req.environ['nova.context'] - authorize(context) - try: - db.bm_node_destroy(context, id) - except exception.NodeNotFound as e: - raise webob.exc.HTTPNotFound(explanation=e.format_message()) - return webob.Response(status_int=202) - - def _check_node_exists(self, context, node_id): - try: - db.bm_node_get(context, node_id) - except exception.NodeNotFound as e: - raise webob.exc.HTTPNotFound(explanation=e.format_message()) - - @extensions.expected_errors(404) - @wsgi.serializers(xml=InterfaceTemplate) - @wsgi.action('add_interface') - def _add_interface(self, req, id, body): - context = req.environ['nova.context'] - authorize(context) - self._check_node_exists(context, id) - body = body['add_interface'] - address = body['address'] - datapath_id = body.get('datapath_id') - port_no = body.get('port_no') - if_id = db.bm_interface_create(context, - bm_node_id=id, - address=address, - datapath_id=datapath_id, - port_no=port_no) - if_ref = db.bm_interface_get(context, if_id) - return {'interface': _interface_dict(if_ref)} - - @extensions.expected_errors((400, 404)) - @wsgi.response(202) - @wsgi.action('remove_interface') - def _remove_interface(self, req, id, body): - context = req.environ['nova.context'] - authorize(context) - self._check_node_exists(context, id) - body = body['remove_interface'] - if_id = body.get('id') - address = body.get('address') - if not if_id and not address: - raise webob.exc.HTTPBadRequest( - explanation=_("Must specify id or address")) - ifs = db.bm_interface_get_all_by_bm_node_id(context, id) - for i in ifs: - if if_id and if_id != i['id']: - continue - if address and address != i['address']: - continue - db.bm_interface_destroy(context, i['id']) - return - raise webob.exc.HTTPNotFound() - - -class BaremetalNodes(extensions.V3APIExtensionBase): - """Admin-only bare-metal node administration.""" - - name = "BareMetalNodes" - alias = ALIAS - namespace = "http://docs.openstack.org/compute/ext/baremetal_nodes/api/v3" - version = 1 - - def get_resources(self): - resources = [] - res = extensions.ResourceExtension(ALIAS, - BareMetalNodeController(), - member_actions={"action": "POST", }) - resources.append(res) - return resources - - def get_controller_extensions(self): - return [] diff --git a/nova/tests/api/openstack/compute/plugins/v3/test_baremetal_nodes.py b/nova/tests/api/openstack/compute/plugins/v3/test_baremetal_nodes.py deleted file mode 100644 index 0ab5097946b6..000000000000 --- a/nova/tests/api/openstack/compute/plugins/v3/test_baremetal_nodes.py +++ /dev/null @@ -1,220 +0,0 @@ -# Copyright (c) 2013 NTT DOCOMO, INC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from webob import exc - -from nova.api.openstack.compute.plugins.v3 import baremetal_nodes -from nova import context -from nova import exception -from nova import test -from nova.virt.baremetal import db - - -class FakeRequest(object): - - def __init__(self, context): - self.environ = {"nova.context": context} - - -class BareMetalNodesTest(test.TestCase): - - def setUp(self): - super(BareMetalNodesTest, self).setUp() - - self.context = context.get_admin_context() - self.controller = baremetal_nodes.BareMetalNodeController() - self.request = FakeRequest(self.context) - - def test_create(self): - node = { - 'service_host': "host", - 'cpus': 8, - 'memory_mb': 8192, - 'local_gb': 128, - 'pm_address': "10.1.2.3", - 'pm_user': "pm_user", - 'pm_password': "pm_pass", - 'terminal_port': 8000, - 'interfaces': [], - } - response = node.copy() - response['id'] = 100 - del response['pm_password'] - response['instance_uuid'] = None - self.mox.StubOutWithMock(db, 'bm_node_create') - db.bm_node_create(self.context, node).AndReturn(response) - self.mox.ReplayAll() - res_dict = self.controller.create(self.request, {'node': node}) - self.assertEqual({'node': response}, res_dict) - self.assertEqual(self.controller.create.wsgi_code, 201) - - def test_delete(self): - self.mox.StubOutWithMock(db, 'bm_node_destroy') - db.bm_node_destroy(self.context, 1) - self.mox.ReplayAll() - self.controller.delete(self.request, 1) - - def test_delete_node_not_found(self): - self.mox.StubOutWithMock(db, 'bm_node_destroy') - db.bm_node_destroy(self.context, 1).\ - AndRaise(exception.NodeNotFound(node_id=1)) - self.mox.ReplayAll() - self.assertRaises( - exc.HTTPNotFound, - self.controller.delete, - self.request, - 1) - - def test_index(self): - nodes = [{'id': 1}, - {'id': 2}, - ] - interfaces = [{'id': 1, 'address': '11:11:11:11:11:11'}, - {'id': 2, 'address': '22:22:22:22:22:22'}, - ] - self.mox.StubOutWithMock(db, 'bm_node_get_all') - self.mox.StubOutWithMock(db, 'bm_interface_get_all_by_bm_node_id') - db.bm_node_get_all(self.context).AndReturn(nodes) - db.bm_interface_get_all_by_bm_node_id(self.context, 1).\ - AndRaise(exception.NodeNotFound(node_id=1)) - db.bm_interface_get_all_by_bm_node_id(self.context, 2).\ - AndReturn(interfaces) - self.mox.ReplayAll() - res_dict = self.controller.index(self.request) - self.assertEqual(2, len(res_dict['nodes'])) - self.assertEqual([], res_dict['nodes'][0]['interfaces']) - self.assertEqual(2, len(res_dict['nodes'][1]['interfaces'])) - - def test_show(self): - node_id = 1 - node = {'id': node_id} - interfaces = [{'id': 1, 'address': '11:11:11:11:11:11'}, - {'id': 2, 'address': '22:22:22:22:22:22'}, - ] - self.mox.StubOutWithMock(db, 'bm_node_get') - self.mox.StubOutWithMock(db, 'bm_interface_get_all_by_bm_node_id') - db.bm_node_get(self.context, node_id).AndReturn(node) - db.bm_interface_get_all_by_bm_node_id(self.context, node_id).\ - AndReturn(interfaces) - self.mox.ReplayAll() - res_dict = self.controller.show(self.request, node_id) - self.assertEqual(node_id, res_dict['node']['id']) - self.assertEqual(2, len(res_dict['node']['interfaces'])) - - def test_show_no_interfaces(self): - node_id = 1 - node = {'id': node_id} - self.mox.StubOutWithMock(db, 'bm_node_get') - self.mox.StubOutWithMock(db, 'bm_interface_get_all_by_bm_node_id') - db.bm_node_get(self.context, node_id).AndReturn(node) - db.bm_interface_get_all_by_bm_node_id(self.context, node_id).\ - AndRaise(exception.NodeNotFound(node_id=node_id)) - self.mox.ReplayAll() - res_dict = self.controller.show(self.request, node_id) - self.assertEqual(node_id, res_dict['node']['id']) - self.assertEqual(0, len(res_dict['node']['interfaces'])) - - def test_add_interface(self): - node_id = 1 - address = '11:22:33:44:55:66' - body = {'add_interface': {'address': address}} - self.mox.StubOutWithMock(db, 'bm_node_get') - self.mox.StubOutWithMock(db, 'bm_interface_create') - self.mox.StubOutWithMock(db, 'bm_interface_get') - db.bm_node_get(self.context, node_id) - db.bm_interface_create(self.context, - bm_node_id=node_id, - address=address, - datapath_id=None, - port_no=None).\ - AndReturn(12345) - db.bm_interface_get(self.context, 12345).\ - AndReturn({'id': 12345, 'address': address}) - self.mox.ReplayAll() - res_dict = self.controller._add_interface(self.request, node_id, body) - self.assertEqual(12345, res_dict['interface']['id']) - self.assertEqual(address, res_dict['interface']['address']) - - def test_remove_interface(self): - node_id = 1 - interfaces = [{'id': 1}, - {'id': 2}, - {'id': 3}, - ] - body = {'remove_interface': {'id': 2}} - self.mox.StubOutWithMock(db, 'bm_node_get') - self.mox.StubOutWithMock(db, 'bm_interface_get_all_by_bm_node_id') - self.mox.StubOutWithMock(db, 'bm_interface_destroy') - db.bm_node_get(self.context, node_id) - db.bm_interface_get_all_by_bm_node_id(self.context, node_id).\ - AndReturn(interfaces) - db.bm_interface_destroy(self.context, 2) - self.mox.ReplayAll() - self.controller._remove_interface(self.request, node_id, body) - - def test_remove_interface_by_address(self): - node_id = 1 - interfaces = [{'id': 1, 'address': '11:11:11:11:11:11'}, - {'id': 2, 'address': '22:22:22:22:22:22'}, - {'id': 3, 'address': '33:33:33:33:33:33'}, - ] - self.mox.StubOutWithMock(db, 'bm_node_get') - self.mox.StubOutWithMock(db, 'bm_interface_get_all_by_bm_node_id') - self.mox.StubOutWithMock(db, 'bm_interface_destroy') - db.bm_node_get(self.context, node_id) - db.bm_interface_get_all_by_bm_node_id(self.context, node_id).\ - AndReturn(interfaces) - db.bm_interface_destroy(self.context, 2) - self.mox.ReplayAll() - body = {'remove_interface': {'address': '22:22:22:22:22:22'}} - self.controller._remove_interface(self.request, node_id, body) - - def test_remove_interface_no_id_no_address(self): - node_id = 1 - self.mox.StubOutWithMock(db, 'bm_node_get') - db.bm_node_get(self.context, node_id) - self.mox.ReplayAll() - body = {'remove_interface': {}} - self.assertRaises(exc.HTTPBadRequest, - self.controller._remove_interface, - self.request, - node_id, - body) - - def test_add_interface_node_not_found(self): - node_id = 1 - self.mox.StubOutWithMock(db, 'bm_node_get') - db.bm_node_get(self.context, node_id).\ - AndRaise(exception.NodeNotFound(node_id=node_id)) - self.mox.ReplayAll() - body = {'add_interface': {'address': '11:11:11:11:11:11'}} - self.assertRaises(exc.HTTPNotFound, - self.controller._add_interface, - self.request, - node_id, - body) - - def test_remove_interface_node_not_found(self): - node_id = 1 - self.mox.StubOutWithMock(db, 'bm_node_get') - db.bm_node_get(self.context, node_id).\ - AndRaise(exception.NodeNotFound(node_id=node_id)) - self.mox.ReplayAll() - body = {'remove_interface': {'address': '11:11:11:11:11:11'}} - self.assertRaises(exc.HTTPNotFound, - self.controller._remove_interface, - self.request, - node_id, - body) diff --git a/nova/tests/fake_policy.py b/nova/tests/fake_policy.py index d5a4b81003b1..3d420c149180 100644 --- a/nova/tests/fake_policy.py +++ b/nova/tests/fake_policy.py @@ -135,7 +135,6 @@ policy_data = """ "compute_extension:attach_interfaces": "", "compute_extension:v3:os-attach-interfaces": "", "compute_extension:baremetal_nodes": "", - "compute_extension:v3:os-baremetal-nodes": "", "compute_extension:cells": "", "compute_extension:v3:os-cells": "", "compute_extension:certificates": "", diff --git a/setup.cfg b/setup.cfg index 8ad14b6139c6..830c2a713f03 100644 --- a/setup.cfg +++ b/setup.cfg @@ -62,7 +62,6 @@ nova.api.v3.extensions = aggregates = nova.api.openstack.compute.plugins.v3.aggregates:Aggregates attach_interfaces = nova.api.openstack.compute.plugins.v3.attach_interfaces:AttachInterfaces availability_zone = nova.api.openstack.compute.plugins.v3.availability_zone:AvailabilityZone - baremetal_nodes = nova.api.openstack.compute.plugins.v3.baremetal_nodes:BaremetalNodes block_device_mapping = nova.api.openstack.compute.plugins.v3.block_device_mapping:BlockDeviceMapping cells = nova.api.openstack.compute.plugins.v3.cells:Cells certificates = nova.api.openstack.compute.plugins.v3.certificates:Certificates