Add node() and ports() to NodeInfo
Will be useful for plugins once we pass NodeInfo in. Implements: blueprint plugin-interface-v2 Change-Id: If2060095d7f4c11bd25ea0e0e2fd5e8aca1d53a5
This commit is contained in:
parent
83fab1031f
commit
3ac546b157
@ -113,8 +113,7 @@ def introspect(uuid, new_ipmi_credentials=None):
|
||||
|
||||
def _background_introspect(ironic, cached_node):
|
||||
# TODO(dtantsur): pagination
|
||||
macs = [p.address for p in ironic.node.list_ports(cached_node.uuid,
|
||||
limit=0)]
|
||||
macs = [p.address for p in cached_node.ports(ironic)]
|
||||
if macs:
|
||||
cached_node.add_attribute(node_cache.MACS_ATTRIBUTE, macs)
|
||||
LOG.info(_LI('Whitelisting MAC\'s %(macs)s for node %(node)s on the'
|
||||
|
@ -53,12 +53,15 @@ MACS_ATTRIBUTE = 'mac'
|
||||
class NodeInfo(object):
|
||||
"""Record about a node in the cache."""
|
||||
|
||||
def __init__(self, uuid, started_at, finished_at=None, error=None):
|
||||
def __init__(self, uuid, started_at, finished_at=None, error=None,
|
||||
node=None, ports=None):
|
||||
self.uuid = uuid
|
||||
self.started_at = started_at
|
||||
self.finished_at = finished_at
|
||||
self.error = error
|
||||
self.invalidate_cache()
|
||||
self._node = node
|
||||
self._ports = ports
|
||||
|
||||
@property
|
||||
def options(self):
|
||||
@ -129,6 +132,22 @@ class NodeInfo(object):
|
||||
def invalidate_cache(self):
|
||||
"""Clear all cached info, so that it's reloaded next time."""
|
||||
self._options = None
|
||||
self._node = None
|
||||
self._ports = None
|
||||
|
||||
def node(self, ironic=None):
|
||||
"""Get Ironic node object associated with the cached node record."""
|
||||
if self._node is None:
|
||||
ironic = utils.get_client() if ironic is None else ironic
|
||||
self._node = ironic.node.get(self.uuid)
|
||||
return self._node
|
||||
|
||||
def ports(self, ironic=None):
|
||||
"""Get Ironic port objects associated with the cached node record."""
|
||||
if self._ports is None:
|
||||
ironic = utils.get_client() if ironic is None else ironic
|
||||
self._ports = ironic.node.list_ports(self.uuid, limit=0)
|
||||
return self._ports
|
||||
|
||||
|
||||
def init():
|
||||
|
@ -84,7 +84,7 @@ def process(node_info):
|
||||
|
||||
ironic = utils.get_client()
|
||||
try:
|
||||
node = ironic.node.get(cached_node.uuid)
|
||||
node = cached_node.node(ironic)
|
||||
except exceptions.NotFound:
|
||||
msg = (_('Node UUID %s was found in cache, but is not found in Ironic')
|
||||
% cached_node.uuid)
|
||||
|
@ -38,12 +38,12 @@ class BaseTest(test_base.NodeTest):
|
||||
provision_state='foobar')
|
||||
self.ports = [mock.Mock(address=m) for m in self.macs]
|
||||
self.cached_node = mock.Mock(uuid=self.uuid, options={})
|
||||
self.cached_node.ports.return_value = self.ports
|
||||
|
||||
def _prepare(self, client_mock):
|
||||
cli = client_mock.return_value
|
||||
cli.node.get.return_value = self.node
|
||||
cli.node.validate.return_value = mock.Mock(power={'result': True})
|
||||
cli.node.list_ports.return_value = self.ports
|
||||
return cli
|
||||
|
||||
|
||||
@ -62,10 +62,10 @@ class TestIntrospect(BaseTest):
|
||||
|
||||
cli.node.get.assert_called_once_with(self.uuid)
|
||||
cli.node.validate.assert_called_once_with(self.uuid)
|
||||
cli.node.list_ports.assert_called_once_with(self.uuid, limit=0)
|
||||
|
||||
add_mock.assert_called_once_with(self.uuid,
|
||||
bmc_address=self.bmc_address)
|
||||
self.cached_node.ports.assert_called_once_with(cli)
|
||||
self.cached_node.add_attribute.assert_called_once_with('mac',
|
||||
self.macs)
|
||||
filters_mock.assert_called_with(cli)
|
||||
@ -102,7 +102,7 @@ class TestIntrospect(BaseTest):
|
||||
|
||||
cli.node.get.assert_called_once_with(self.uuid)
|
||||
cli.node.validate.assert_called_with(self.uuid)
|
||||
cli.node.list_ports.assert_called_once_with(self.uuid, limit=0)
|
||||
self.cached_node.ports.assert_called_once_with(cli)
|
||||
|
||||
add_mock.assert_called_once_with(self.uuid,
|
||||
bmc_address=self.bmc_address)
|
||||
@ -152,16 +152,15 @@ class TestIntrospect(BaseTest):
|
||||
cli = client_mock.return_value
|
||||
cli.node.get.return_value = self.node_compat
|
||||
cli.node.validate.return_value = mock.Mock(power={'result': True})
|
||||
cli.node.list_ports.return_value = self.ports
|
||||
add_mock.return_value = mock.Mock(uuid=self.node_compat.uuid,
|
||||
options={})
|
||||
add_mock.return_value.ports.return_value = self.ports
|
||||
|
||||
introspect.introspect(self.node_compat.uuid)
|
||||
|
||||
cli.node.get.assert_called_once_with(self.node_compat.uuid)
|
||||
cli.node.validate.assert_called_once_with(self.node_compat.uuid)
|
||||
cli.node.list_ports.assert_called_once_with(self.node_compat.uuid,
|
||||
limit=0)
|
||||
add_mock.return_value.ports.assert_called_once_with(cli)
|
||||
|
||||
add_mock.assert_called_once_with(self.node_compat.uuid,
|
||||
bmc_address=None)
|
||||
@ -176,12 +175,12 @@ class TestIntrospect(BaseTest):
|
||||
|
||||
def test_no_macs(self, client_mock, add_mock, filters_mock):
|
||||
cli = self._prepare(client_mock)
|
||||
cli.node.list_ports.return_value = []
|
||||
self.ports[:] = []
|
||||
add_mock.return_value = self.cached_node
|
||||
|
||||
introspect.introspect(self.node.uuid)
|
||||
|
||||
cli.node.list_ports.assert_called_once_with(self.uuid, limit=0)
|
||||
self.cached_node.ports.assert_called_once_with(cli)
|
||||
|
||||
add_mock.assert_called_once_with(self.uuid,
|
||||
bmc_address=self.bmc_address)
|
||||
@ -205,7 +204,7 @@ class TestIntrospect(BaseTest):
|
||||
'Cannot get node',
|
||||
introspect.introspect, self.uuid)
|
||||
|
||||
self.assertEqual(0, cli.node.list_ports.call_count)
|
||||
self.assertEqual(0, self.cached_node.ports.call_count)
|
||||
self.assertEqual(0, filters_mock.call_count)
|
||||
self.assertEqual(0, cli.node.set_power_state.call_count)
|
||||
self.assertFalse(add_mock.called)
|
||||
@ -223,7 +222,7 @@ class TestIntrospect(BaseTest):
|
||||
introspect.introspect, self.uuid)
|
||||
|
||||
cli.node.validate.assert_called_once_with(self.uuid)
|
||||
self.assertEqual(0, cli.node.list_ports.call_count)
|
||||
self.assertEqual(0, self.cached_node.ports.call_count)
|
||||
self.assertEqual(0, filters_mock.call_count)
|
||||
self.assertEqual(0, cli.node.set_power_state.call_count)
|
||||
self.assertFalse(add_mock.called)
|
||||
@ -238,7 +237,7 @@ class TestIntrospect(BaseTest):
|
||||
'node %s with provision state "active"' % self.uuid,
|
||||
introspect.introspect, self.uuid)
|
||||
|
||||
self.assertEqual(0, cli.node.list_ports.call_count)
|
||||
self.assertEqual(0, self.cached_node.ports.call_count)
|
||||
self.assertEqual(0, filters_mock.call_count)
|
||||
self.assertEqual(0, cli.node.set_power_state.call_count)
|
||||
self.assertFalse(add_mock.called)
|
||||
|
@ -321,3 +321,64 @@ class TestNodeInfoOptions(test_base.NodeTest):
|
||||
|
||||
new = node_cache.NodeInfo(uuid=self.uuid, started_at=3.14)
|
||||
self.assertEqual(data, new.options['name'])
|
||||
|
||||
|
||||
@mock.patch.object(utils, 'get_client')
|
||||
class TestNodeCacheIronicObjects(unittest.TestCase):
|
||||
def test_node_provided(self, mock_ironic):
|
||||
node_info = node_cache.NodeInfo(uuid='uuid', started_at=0,
|
||||
node=mock.sentinel.node)
|
||||
self.assertIs(mock.sentinel.node, node_info.node())
|
||||
self.assertIs(mock.sentinel.node, node_info.node(ironic='ironic'))
|
||||
self.assertFalse(mock_ironic.called)
|
||||
|
||||
def test_node_not_provided(self, mock_ironic):
|
||||
mock_ironic.return_value.node.get.return_value = mock.sentinel.node
|
||||
node_info = node_cache.NodeInfo(uuid='uuid', started_at=0)
|
||||
|
||||
self.assertIs(mock.sentinel.node, node_info.node())
|
||||
self.assertIs(node_info.node(), node_info.node())
|
||||
|
||||
mock_ironic.assert_called_once_with()
|
||||
mock_ironic.return_value.node.get.assert_called_once_with('uuid')
|
||||
|
||||
def test_node_ironic_arg(self, mock_ironic):
|
||||
ironic2 = mock.Mock()
|
||||
ironic2.node.get.return_value = mock.sentinel.node
|
||||
node_info = node_cache.NodeInfo(uuid='uuid', started_at=0)
|
||||
|
||||
self.assertIs(mock.sentinel.node, node_info.node(ironic=ironic2))
|
||||
self.assertIs(node_info.node(), node_info.node(ironic=ironic2))
|
||||
|
||||
self.assertFalse(mock_ironic.called)
|
||||
ironic2.node.get.assert_called_once_with('uuid')
|
||||
|
||||
def test_ports_provided(self, mock_ironic):
|
||||
node_info = node_cache.NodeInfo(uuid='uuid', started_at=0,
|
||||
ports=mock.sentinel.ports)
|
||||
self.assertIs(mock.sentinel.ports, node_info.ports())
|
||||
self.assertIs(mock.sentinel.ports, node_info.ports(ironic='ironic'))
|
||||
self.assertFalse(mock_ironic.called)
|
||||
|
||||
def test_ports_not_provided(self, mock_ironic):
|
||||
mock_ironic.return_value.node.list_ports.return_value = (
|
||||
mock.sentinel.ports)
|
||||
node_info = node_cache.NodeInfo(uuid='uuid', started_at=0)
|
||||
|
||||
self.assertIs(mock.sentinel.ports, node_info.ports())
|
||||
self.assertIs(node_info.ports(), node_info.ports())
|
||||
|
||||
mock_ironic.assert_called_once_with()
|
||||
mock_ironic.return_value.node.list_ports.assert_called_once_with(
|
||||
'uuid', limit=0)
|
||||
|
||||
def test_ports_ironic_arg(self, mock_ironic):
|
||||
ironic2 = mock.Mock()
|
||||
ironic2.node.list_ports.return_value = mock.sentinel.ports
|
||||
node_info = node_cache.NodeInfo(uuid='uuid', started_at=0)
|
||||
|
||||
self.assertIs(mock.sentinel.ports, node_info.ports(ironic=ironic2))
|
||||
self.assertIs(node_info.ports(), node_info.ports(ironic=ironic2))
|
||||
|
||||
self.assertFalse(mock_ironic.called)
|
||||
ironic2.node.list_ports.assert_called_once_with('uuid', limit=0)
|
||||
|
@ -343,7 +343,9 @@ class TestProcessNode(BaseTest):
|
||||
self.cli.port.create.side_effect = self.ports
|
||||
self.cli.node.update.return_value = self.node
|
||||
|
||||
def call(self):
|
||||
@mock.patch.object(utils, 'get_client')
|
||||
def call(self, mock_cli):
|
||||
mock_cli.return_value = self.cli
|
||||
return process._process_node(self.cli, self.node, self.data,
|
||||
self.cached_node)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user