Periodically check nodes' existance
Add below procedure to periodic_clean_up() in order to sync data with Ironic. * Get Ironic's node list by executing python-ironicclient's node.list() * Compare above Ironic-node-list and cache * If node in cache is not exist in Ironic-node-list, delete data from cache. Change-Id: I606b0a76559b8bd2845d58146086b1019712dc34 Implements: blueprint delete-db-api
This commit is contained in:
parent
59d3676bca
commit
399ffda676
|
@ -174,11 +174,20 @@ def periodic_clean_up(period): # pragma: no cover
|
|||
try:
|
||||
if node_cache.clean_up():
|
||||
firewall.update_filters()
|
||||
sync_with_ironic()
|
||||
except Exception:
|
||||
LOG.exception(_LE('Periodic clean up of node cache failed'))
|
||||
eventlet.greenthread.sleep(period)
|
||||
|
||||
|
||||
def sync_with_ironic():
|
||||
ironic = utils.get_client()
|
||||
# TODO(yuikotakada): pagination
|
||||
ironic_nodes = ironic.node.list(limit=0)
|
||||
ironic_node_uuids = {node.uuid for node in ironic_nodes}
|
||||
node_cache.delete_nodes_not_in_list(ironic_node_uuids)
|
||||
|
||||
|
||||
def init():
|
||||
if utils.get_auth_strategy() != 'noauth':
|
||||
utils.add_auth_middleware(app)
|
||||
|
|
|
@ -183,13 +183,7 @@ def add_node(uuid, **attributes):
|
|||
"""
|
||||
started_at = time.time()
|
||||
with db.ensure_transaction() as session:
|
||||
(db.model_query(db.Node, session=session).filter_by(uuid=uuid).
|
||||
delete())
|
||||
(db.model_query(db.Attribute, session=session).filter_by(uuid=uuid).
|
||||
delete(synchronize_session=False))
|
||||
(db.model_query(db.Option, session=session).filter_by(uuid=uuid).
|
||||
delete())
|
||||
|
||||
_delete_node(uuid)
|
||||
db.Node(uuid=uuid, started_at=started_at).save(session)
|
||||
|
||||
node_info = NodeInfo(uuid=uuid, started_at=started_at)
|
||||
|
@ -201,12 +195,46 @@ def add_node(uuid, **attributes):
|
|||
return node_info
|
||||
|
||||
|
||||
def delete_nodes_not_in_list(uuids):
|
||||
"""Delete nodes which don't exist in Ironic node UUIDs.
|
||||
|
||||
:param uuids: Ironic node UUIDs
|
||||
"""
|
||||
inspector_uuids = _list_node_uuids()
|
||||
for uuid in inspector_uuids - uuids:
|
||||
LOG.warn(_LW('Node %s was deleted from Ironic, dropping from Ironic '
|
||||
'Inspector database'), uuid)
|
||||
_delete_node(uuid)
|
||||
|
||||
|
||||
def _delete_node(uuid, session=None):
|
||||
"""Delete information about a node.
|
||||
|
||||
:param uuid: Ironic node UUID
|
||||
"""
|
||||
with db.ensure_transaction(session) as session:
|
||||
(db.model_query(db.Node, session=session).filter_by(uuid=uuid).
|
||||
delete())
|
||||
(db.model_query(db.Attribute, session=session).filter_by(uuid=uuid).
|
||||
delete(synchronize_session=False))
|
||||
(db.model_query(db.Option, session=session).filter_by(uuid=uuid).
|
||||
delete())
|
||||
|
||||
|
||||
def active_macs():
|
||||
"""List all MAC's that are on introspection right now."""
|
||||
return ({x.value for x in db.model_query(db.Attribute.value).
|
||||
filter_by(name=MACS_ATTRIBUTE)})
|
||||
|
||||
|
||||
def _list_node_uuids():
|
||||
"""Get all nodes' uuid from cache.
|
||||
|
||||
:returns: Set of nodes' uuid.
|
||||
"""
|
||||
return {x.uuid for x in db.model_query(db.Node.uuid)}
|
||||
|
||||
|
||||
def get_node(uuid):
|
||||
"""Get node from cache by it's UUID.
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ class Base(base.NodeTest):
|
|||
self.cli.reset_mock()
|
||||
self.cli.node.get.return_value = self.node
|
||||
self.cli.node.update.return_value = self.node
|
||||
self.cli.node.list.return_value = [self.node]
|
||||
|
||||
# https://github.com/openstack/ironic-inspector/blob/master/HTTP-API.rst # noqa
|
||||
self.data = {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import time
|
||||
import unittest
|
||||
|
||||
|
@ -56,6 +57,41 @@ class TestNodeCache(test_base.NodeTest):
|
|||
('mac', self.macs[1], self.uuid)],
|
||||
[(row.name, row.value, row.uuid) for row in res])
|
||||
|
||||
def test__delete_node(self):
|
||||
session = db.get_session()
|
||||
with session.begin():
|
||||
db.Node(uuid=self.node.uuid).save(session)
|
||||
db.Attribute(name='mac', value='11:22:11:22:11:22',
|
||||
uuid=self.uuid).save(session)
|
||||
data = {'s': 'value', 'b': True, 'i': 42}
|
||||
encoded = json.dumps(data)
|
||||
db.Option(uuid=self.uuid, name='name', value=encoded).save(
|
||||
session)
|
||||
|
||||
node_cache._delete_node(self.uuid)
|
||||
session = db.get_session()
|
||||
row_node = db.model_query(db.Node).filter_by(
|
||||
uuid=self.uuid).first()
|
||||
self.assertIsNone(row_node)
|
||||
row_attribute = db.model_query(db.Attribute).filter_by(
|
||||
uuid=self.uuid).first()
|
||||
self.assertIsNone(row_attribute)
|
||||
row_option = db.model_query(db.Option).filter_by(
|
||||
uuid=self.uuid).first()
|
||||
self.assertIsNone(row_option)
|
||||
|
||||
@mock.patch.object(node_cache, '_list_node_uuids')
|
||||
@mock.patch.object(node_cache, '_delete_node')
|
||||
def test_delete_nodes_not_in_list(self, mock__delete_node,
|
||||
mock__list_node_uuids):
|
||||
uuid2 = 'uuid2'
|
||||
uuids = {self.uuid}
|
||||
mock__list_node_uuids.return_value = {self.uuid, uuid2}
|
||||
session = db.get_session()
|
||||
with session.begin():
|
||||
node_cache.delete_nodes_not_in_list(uuids)
|
||||
mock__delete_node.assert_called_once_with(uuid2)
|
||||
|
||||
def test_add_node_duplicate_mac(self):
|
||||
session = db.get_session()
|
||||
with session.begin():
|
||||
|
@ -78,6 +114,15 @@ class TestNodeCache(test_base.NodeTest):
|
|||
self.assertEqual({'11:22:11:22:11:22', '22:11:22:11:22:11'},
|
||||
node_cache.active_macs())
|
||||
|
||||
def test__list_node_uuids(self):
|
||||
session = db.get_session()
|
||||
with session.begin():
|
||||
db.Node(uuid=self.node.uuid).save(session)
|
||||
db.Node(uuid='uuid2').save(session)
|
||||
|
||||
node_uuid_list = node_cache._list_node_uuids()
|
||||
self.assertEqual({self.uuid, 'uuid2'}, node_uuid_list)
|
||||
|
||||
def test_add_attribute(self):
|
||||
session = db.get_session()
|
||||
with session.begin():
|
||||
|
|
Loading…
Reference in New Issue