Make resource class required

Allocation API requires a resource class, so we have to require it now.

Change-Id: Ic3729fb8aa02c82379eceb2a2555fc9c0ba9bc57
This commit is contained in:
Dmitry Tantsur 2019-03-01 15:38:24 +01:00
parent 6d85e21ed0
commit d64e020fd0
5 changed files with 22 additions and 26 deletions

View File

@ -164,7 +164,7 @@ def _parse_args(args, config):
deploy.add_argument('--ssh-public-key', help='SSH public key to load') deploy.add_argument('--ssh-public-key', help='SSH public key to load')
deploy.add_argument('--hostname', help='Host name to use, defaults to ' deploy.add_argument('--hostname', help='Host name to use, defaults to '
'Node\'s name or UUID') 'Node\'s name or UUID')
deploy.add_argument('--resource-class', deploy.add_argument('--resource-class', required=True,
help='node resource class to deploy') help='node resource class to deploy')
deploy.add_argument('--conductor-group', deploy.add_argument('--conductor-group',
help='conductor group to pick the node from') help='conductor group to pick the node from')

View File

@ -64,7 +64,7 @@ class Provisioner(_utils.GetNodeMixin):
self._dry_run = dry_run self._dry_run = dry_run
def reserve_node(self, resource_class=None, conductor_group=None, def reserve_node(self, resource_class, conductor_group=None,
capabilities=None, traits=None, candidates=None, capabilities=None, traits=None, candidates=None,
predicate=None): predicate=None):
"""Find and reserve a suitable node. """Find and reserve a suitable node.
@ -91,10 +91,6 @@ class Provisioner(_utils.GetNodeMixin):
:raises: :py:class:`metalsmith.exceptions.ReservationFailed` :raises: :py:class:`metalsmith.exceptions.ReservationFailed`
""" """
capabilities = capabilities or {} capabilities = capabilities or {}
if resource_class is None:
warnings.warn("Not providing resource_class is deprecated as it's "
"not compatible with the proposed allocation API",
DeprecationWarning)
if candidates: if candidates:
nodes = [self._get_node(node) for node in candidates] nodes = [self._get_node(node) for node in candidates]

View File

@ -94,36 +94,29 @@ class Base(testtools.TestCase):
class TestReserveNode(Base): class TestReserveNode(Base):
RSC = 'baremetal'
def _node(self, **kwargs): def _node(self, **kwargs):
kwargs.setdefault('id', '000') kwargs.setdefault('id', '000')
kwargs.setdefault('properties', {'local_gb': 100}) kwargs.setdefault('properties', {'local_gb': 100})
kwargs.setdefault('instance_info', {}) kwargs.setdefault('instance_info', {})
kwargs.setdefault('instance_id', None) kwargs.setdefault('instance_id', None)
kwargs.setdefault('is_maintenance', False) kwargs.setdefault('is_maintenance', False)
kwargs.setdefault('resource_class', self.RSC)
return mock.Mock(spec=NODE_FIELDS, **kwargs) return mock.Mock(spec=NODE_FIELDS, **kwargs)
def test_no_nodes(self): def test_no_nodes(self):
self.api.baremetal.nodes.return_value = [] self.api.baremetal.nodes.return_value = []
self.assertRaises(exceptions.NodesNotFound, self.assertRaises(exceptions.NodesNotFound,
self.pr.reserve_node, resource_class='control') self.pr.reserve_node, self.RSC)
self.assertFalse(self.api.baremetal.update_node.called) self.assertFalse(self.api.baremetal.update_node.called)
def test_simple_ok(self): def test_simple_ok(self):
nodes = [self._node(resource_class='control')]
self.api.baremetal.nodes.return_value = nodes
node = self.pr.reserve_node('control')
self.assertIn(node, nodes)
self.api.baremetal.update_node.assert_called_once_with(
node, instance_id=node.id, instance_info={})
def test_any_resource_class(self):
nodes = [self._node()] nodes = [self._node()]
self.api.baremetal.nodes.return_value = nodes self.api.baremetal.nodes.return_value = nodes
node = self.pr.reserve_node() node = self.pr.reserve_node(self.RSC)
self.assertIn(node, nodes) self.assertIn(node, nodes)
self.api.baremetal.update_node.assert_called_once_with( self.api.baremetal.update_node.assert_called_once_with(
@ -131,14 +124,13 @@ class TestReserveNode(Base):
def test_with_capabilities(self): def test_with_capabilities(self):
nodes = [ nodes = [
self._node(properties={'local_gb': 100, 'capabilities': caps}, self._node(properties={'local_gb': 100, 'capabilities': caps})
resource_class='control')
for caps in ['answer:1', 'answer:42', None] for caps in ['answer:1', 'answer:42', None]
] ]
expected = nodes[1] expected = nodes[1]
self.api.baremetal.nodes.return_value = nodes self.api.baremetal.nodes.return_value = nodes
node = self.pr.reserve_node('control', capabilities={'answer': '42'}) node = self.pr.reserve_node(self.RSC, capabilities={'answer': '42'})
self.assertIs(node, expected) self.assertIs(node, expected)
self.api.baremetal.update_node.assert_called_once_with( self.api.baremetal.update_node.assert_called_once_with(
@ -152,7 +144,7 @@ class TestReserveNode(Base):
expected = nodes[1] expected = nodes[1]
self.api.baremetal.nodes.return_value = nodes self.api.baremetal.nodes.return_value = nodes
node = self.pr.reserve_node(traits=['foo', 'answer:42']) node = self.pr.reserve_node(self.RSC, traits=['foo', 'answer:42'])
self.assertIs(node, expected) self.assertIs(node, expected)
self.api.baremetal.update_node.assert_called_once_with( self.api.baremetal.update_node.assert_called_once_with(
@ -165,6 +157,7 @@ class TestReserveNode(Base):
self.api.baremetal.nodes.return_value = nodes[:] self.api.baremetal.nodes.return_value = nodes[:]
node = self.pr.reserve_node( node = self.pr.reserve_node(
self.RSC,
predicate=lambda node: 100 < node.properties['local_gb'] < 200) predicate=lambda node: 100 < node.properties['local_gb'] < 200)
self.assertEqual(node, nodes[1]) self.assertEqual(node, nodes[1])
@ -178,6 +171,7 @@ class TestReserveNode(Base):
self.assertRaisesRegex(exceptions.CustomPredicateFailed, self.assertRaisesRegex(exceptions.CustomPredicateFailed,
'custom predicate', 'custom predicate',
self.pr.reserve_node, self.pr.reserve_node,
self.RSC,
predicate=lambda node: False) predicate=lambda node: False)
self.assertFalse(self.api.baremetal.update_node.called) self.assertFalse(self.api.baremetal.update_node.called)
@ -185,7 +179,7 @@ class TestReserveNode(Base):
def test_provided_node(self): def test_provided_node(self):
nodes = [self._node()] nodes = [self._node()]
node = self.pr.reserve_node(candidates=nodes) node = self.pr.reserve_node(self.RSC, candidates=nodes)
self.assertEqual(node, nodes[0]) self.assertEqual(node, nodes[0])
self.assertFalse(self.api.baremetal.nodes.called) self.assertFalse(self.api.baremetal.nodes.called)
@ -195,7 +189,7 @@ class TestReserveNode(Base):
def test_provided_nodes(self): def test_provided_nodes(self):
nodes = [self._node(), self._node()] nodes = [self._node(), self._node()]
node = self.pr.reserve_node(candidates=nodes) node = self.pr.reserve_node(self.RSC, candidates=nodes)
self.assertEqual(node, nodes[0]) self.assertEqual(node, nodes[0])
self.assertFalse(self.api.baremetal.nodes.called) self.assertFalse(self.api.baremetal.nodes.called)
@ -227,7 +221,8 @@ class TestReserveNode(Base):
'capabilities': 'cat:meow'}, 'capabilities': 'cat:meow'},
conductor_group='loc1')] conductor_group='loc1')]
node = self.pr.reserve_node(conductor_group='loc1', node = self.pr.reserve_node(self.RSC,
conductor_group='loc1',
candidates=nodes, candidates=nodes,
capabilities={'cat': 'meow'}) capabilities={'cat': 'meow'})

View File

@ -0,0 +1,5 @@
---
upgrade:
- |
The ``resource_class`` argument to ``reserve_node``, as well as the
``--resource-class`` CLI argument, are now required.

View File

@ -115,7 +115,7 @@ Each instances has the following attributes:
- subnet: private-subnet1 - subnet: private-subnet1
``resource_class`` (defaults to ``metalsmith_resource_class``) ``resource_class`` (defaults to ``metalsmith_resource_class``)
requested node's resource class. requested node's resource class. Mandatory.
``root_size`` (defaults to ``metalsmith_root_size``) ``root_size`` (defaults to ``metalsmith_root_size``)
size of the root partition (in GiB), if partition images are used. size of the root partition (in GiB), if partition images are used.