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:

  5de5ae1b5d
  92c9975bd2
  2382186311

Mailing list discussion:

http://lists.openstack.org/pipermail/openstack-dev/2013-September/014614.html

Change-Id: I3bdc7234f91eb4f9078ee24d7ab093b28f9930c9
This commit is contained in:
Dan Smith 2013-09-05 15:19:31 -07:00
parent 3119dafeb5
commit eef8473fa8
5 changed files with 0 additions and 455 deletions

View File

@ -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": "",

View File

@ -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 []

View File

@ -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)

View File

@ -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": "",

View File

@ -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