baremetal: Make api validate mac address
Check if the address in the form of xx:xx:xx:xx:xx:xx. Closes-Bug: 1238595 Change-Id: Idcba745a011604d7664b62d88f1dede88d10443d
This commit is contained in:
parent
79d0ce6171
commit
d3524fb501
|
@ -15,6 +15,7 @@
|
|||
|
||||
"""The bare-metal admin extension."""
|
||||
|
||||
import netaddr
|
||||
import webob
|
||||
|
||||
from nova.api.openstack import extensions
|
||||
|
@ -55,6 +56,20 @@ def _make_interface_elem(elem):
|
|||
elem.set(f)
|
||||
|
||||
|
||||
def is_valid_mac(address):
|
||||
"""Verify the format of a MAC addres."""
|
||||
|
||||
class mac_dialect(netaddr.mac_eui48):
|
||||
word_fmt = '%.02x'
|
||||
word_sep = ':'
|
||||
|
||||
try:
|
||||
na = netaddr.EUI(address, dialect=mac_dialect)
|
||||
except Exception:
|
||||
return False
|
||||
return str(na) == address.lower()
|
||||
|
||||
|
||||
class NodeTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
node_elem = xmlutil.TemplateElement('node', selector='node')
|
||||
|
@ -142,6 +157,11 @@ class BareMetalNodeController(wsgi.Controller):
|
|||
authorize(context)
|
||||
values = body['node'].copy()
|
||||
prov_mac_address = values.pop('prov_mac_address', None)
|
||||
if (prov_mac_address is not None
|
||||
and not is_valid_mac(prov_mac_address)):
|
||||
raise webob.exc.HTTPBadRequest(
|
||||
explanation=_("Must specify address "
|
||||
"in the form of xx:xx:xx:xx:xx:xx"))
|
||||
node = db.bm_node_create(context, values)
|
||||
node = self._node_dict(node)
|
||||
if prov_mac_address:
|
||||
|
@ -181,6 +201,10 @@ class BareMetalNodeController(wsgi.Controller):
|
|||
address = body['address']
|
||||
datapath_id = body.get('datapath_id')
|
||||
port_no = body.get('port_no')
|
||||
if not is_valid_mac(address):
|
||||
raise webob.exc.HTTPBadRequest(
|
||||
explanation=_("Must specify address "
|
||||
"in the form of xx:xx:xx:xx:xx:xx"))
|
||||
if_id = db.bm_interface_create(context,
|
||||
bm_node_id=id,
|
||||
address=address,
|
||||
|
|
|
@ -154,6 +154,68 @@ class BareMetalNodesTest(test.NoDBTestCase):
|
|||
node = fake_node_ext_status(id=100)
|
||||
self._test_create(node, ext_status=True)
|
||||
|
||||
def test_create_with_prov_mac_address(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': [],
|
||||
}
|
||||
intf = {
|
||||
'address': '1a:B2:3C:4d:e5:6f',
|
||||
'datapath_id': None,
|
||||
'id': None,
|
||||
'port_no': None,
|
||||
}
|
||||
|
||||
request = node.copy()
|
||||
request['prov_mac_address'] = intf['address']
|
||||
|
||||
db_node = node.copy()
|
||||
db_node['id'] = 100
|
||||
|
||||
response = node.copy()
|
||||
response.update(id=db_node['id'],
|
||||
instance_uuid=None,
|
||||
interfaces=[intf])
|
||||
del response['pm_password']
|
||||
|
||||
self.mox.StubOutWithMock(db, 'bm_node_create')
|
||||
self.mox.StubOutWithMock(db, 'bm_interface_create')
|
||||
self.mox.StubOutWithMock(db, 'bm_interface_get')
|
||||
db.bm_node_create(self.context, node).AndReturn(db_node)
|
||||
self.ext_mgr.is_loaded('os-baremetal-ext-status').AndReturn(False)
|
||||
db.bm_interface_create(self.context,
|
||||
bm_node_id=db_node['id'],
|
||||
address=intf['address'],
|
||||
datapath_id=intf['datapath_id'],
|
||||
port_no=intf['port_no']).AndReturn(1000)
|
||||
db.bm_interface_get(self.context, 1000).AndReturn(intf)
|
||||
self.mox.ReplayAll()
|
||||
res_dict = self.controller.create(self.request, {'node': request})
|
||||
self.assertEqual({'node': response}, res_dict)
|
||||
|
||||
def test_create_with_invalid_prov_mac_address(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,
|
||||
'prov_mac_address': 'INVALID!!',
|
||||
}
|
||||
self.assertRaises(exc.HTTPBadRequest,
|
||||
self.controller.create,
|
||||
self.request, {'node': node})
|
||||
|
||||
def test_delete(self):
|
||||
self.mox.StubOutWithMock(db, 'bm_node_destroy')
|
||||
db.bm_node_destroy(self.context, 1)
|
||||
|
@ -193,7 +255,7 @@ class BareMetalNodesTest(test.NoDBTestCase):
|
|||
|
||||
def test_add_interface(self):
|
||||
node_id = 1
|
||||
address = '11:22:33:44:55:66'
|
||||
address = '11:22:33:ab:cd:ef'
|
||||
body = {'add_interface': {'address': address}}
|
||||
self.mox.StubOutWithMock(db, 'bm_node_get')
|
||||
self.mox.StubOutWithMock(db, 'bm_interface_create')
|
||||
|
@ -212,6 +274,18 @@ class BareMetalNodesTest(test.NoDBTestCase):
|
|||
self.assertEqual(12345, res_dict['interface']['id'])
|
||||
self.assertEqual(address, res_dict['interface']['address'])
|
||||
|
||||
def test_add_interface_invalid_address(self):
|
||||
node_id = 1
|
||||
body = {'add_interface': {'address': ''}}
|
||||
self.mox.StubOutWithMock(db, 'bm_node_get')
|
||||
db.bm_node_get(self.context, node_id)
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(exc.HTTPBadRequest,
|
||||
self.controller._add_interface,
|
||||
self.request,
|
||||
node_id,
|
||||
body)
|
||||
|
||||
def test_remove_interface(self):
|
||||
node_id = 1
|
||||
interfaces = [{'id': 1},
|
||||
|
@ -283,3 +357,17 @@ class BareMetalNodesTest(test.NoDBTestCase):
|
|||
self.request,
|
||||
node_id,
|
||||
body)
|
||||
|
||||
def test_is_valid_mac(self):
|
||||
self.assertFalse(baremetal_nodes.is_valid_mac(None))
|
||||
self.assertTrue(baremetal_nodes.is_valid_mac("52:54:00:cf:2d:31"))
|
||||
self.assertTrue(baremetal_nodes.is_valid_mac(u"52:54:00:cf:2d:31"))
|
||||
self.assertFalse(baremetal_nodes.is_valid_mac("127.0.0.1"))
|
||||
self.assertFalse(baremetal_nodes.is_valid_mac("not:a:mac:address"))
|
||||
self.assertFalse(baremetal_nodes.is_valid_mac("52-54-00-cf-2d-31"))
|
||||
self.assertFalse(baremetal_nodes.is_valid_mac("5254.00cf.2d31"))
|
||||
self.assertFalse(baremetal_nodes.is_valid_mac("52:54:0:cf:2d:31"))
|
||||
self.assertFalse(baremetal_nodes.is_valid_mac("aa bb cc dd ee ff"))
|
||||
self.assertTrue(baremetal_nodes.is_valid_mac("AA:BB:CC:DD:EE:FF"))
|
||||
self.assertFalse(baremetal_nodes.is_valid_mac("AA BB CC DD EE FF"))
|
||||
self.assertFalse(baremetal_nodes.is_valid_mac("AA-BB-CC-DD-EE-FF"))
|
||||
|
|
Loading…
Reference in New Issue