diff options
author | Kaifeng Wang <kaifeng.w@gmail.com> | 2020-12-20 21:16:15 +0800 |
---|---|---|
committer | Julia Kreger <juliaashleykreger@gmail.com> | 2021-09-09 09:35:09 -0700 |
commit | fbaad948d870ffd18995f5494016798c8d3c9206 (patch) | |
tree | 617383da0c17b84194de5accba3f1340c84fa8c8 /ironic/db | |
parent | 8ea1a438d3f8715622798e01a709ea0dfab89f58 (diff) | |
download | ironic-fbaad948d870ffd18995f5494016798c8d3c9206.tar.gz |
Implements node history: database
This patch provides basic data model change to support node history.
Batch removal is not included in this patch.
Change-Id: I5c7cebd585ee84b5b57bd4690d4074baf0d05699
Story: 2002980
Task: 22989
Diffstat (limited to 'ironic/db')
-rw-r--r-- | ironic/db/api.py | 58 | ||||
-rw-r--r-- | ironic/db/sqlalchemy/alembic/versions/9ef41f07cb58_add_node_history_table.py | 52 | ||||
-rw-r--r-- | ironic/db/sqlalchemy/api.py | 54 | ||||
-rw-r--r-- | ironic/db/sqlalchemy/models.py | 20 |
4 files changed, 184 insertions, 0 deletions
diff --git a/ironic/db/api.py b/ironic/db/api.py index 697654d38..5b71d32bc 100644 --- a/ironic/db/api.py +++ b/ironic/db/api.py @@ -1322,3 +1322,61 @@ class Connection(object, metaclass=abc.ABCMeta): :param names: List of names to filter by. :returns: A list of deploy templates. """ + + @abc.abstractmethod + def create_node_history(self, values): + """Create a new history record. + + :param values: Dict of values. + """ + + @abc.abstractmethod + def destroy_node_history_by_uuid(self, history_uuid): + """Destroy a history record. + + :param history_uuid: The uuid of a history record + """ + + @abc.abstractmethod + def get_node_history_by_id(self, history_id): + """Return a node history representation. + + :param history_id: The id of a history record. + :returns: A history. + """ + + @abc.abstractmethod + def get_node_history_by_uuid(self, history_uuid): + """Return a node history representation. + + :param history_uuid: The uuid of a history record + :returns: A history. + """ + + @abc.abstractmethod + def get_node_history_list(self, limit=None, marker=None, + sort_key=None, sort_dir=None): + """Return a list of node history records + + :param limit: Maximum number of history records to return. + :param marker: the last item of the previous page; we return the next + result set. + :param sort_key: Attribute by which results should be sorted. + :param sort_dir: direction in which results should be sorted. + (asc, desc) + """ + + @abc.abstractmethod + def get_node_history_by_node_id(self, node_id, limit=None, marker=None, + sort_key=None, sort_dir=None): + """List all the history records for a given node. + + :param node_id: The integer node ID. + :param limit: Maximum number of history records to return. + :param marker: the last item of the previous page; we return the next + result set. + :param sort_key: Attribute by which results should be sorted + :param sort_dir: direction in which results should be sorted + (asc, desc) + :returns: A list of histories. + """ diff --git a/ironic/db/sqlalchemy/alembic/versions/9ef41f07cb58_add_node_history_table.py b/ironic/db/sqlalchemy/alembic/versions/9ef41f07cb58_add_node_history_table.py new file mode 100644 index 000000000..9f5b855ed --- /dev/null +++ b/ironic/db/sqlalchemy/alembic/versions/9ef41f07cb58_add_node_history_table.py @@ -0,0 +1,52 @@ +# 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. + +"""add_node_history_table + +Revision ID: 9ef41f07cb58 +Revises: c1846a214450 +Create Date: 2020-12-20 17:45:57.278649 + +""" + +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision = '9ef41f07cb58' +down_revision = 'c1846a214450' + + +def upgrade(): + op.create_table('node_history', + sa.Column('version', sa.String(length=15), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=True), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('uuid', sa.String(length=36), nullable=False), + sa.Column('conductor', sa.String(length=255), + nullable=True), + sa.Column('event_type', sa.String(length=255), + nullable=True), + sa.Column('severity', sa.String(length=255), + nullable=True), + sa.Column('event', sa.Text(), nullable=True), + sa.Column('user', sa.String(length=32), nullable=True), + sa.Column('node_id', sa.Integer(), nullable=True), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('uuid', name='uniq_history0uuid'), + sa.ForeignKeyConstraint(['node_id'], ['nodes.id'], ), + sa.Index('history_node_id_idx', 'node_id'), + sa.Index('history_uuid_idx', 'uuid'), + sa.Index('history_conductor_idx', 'conductor'), + mysql_ENGINE='InnoDB', + mysql_DEFAULT_CHARSET='UTF8') diff --git a/ironic/db/sqlalchemy/api.py b/ironic/db/sqlalchemy/api.py index 1de3add32..716c422dd 100644 --- a/ironic/db/sqlalchemy/api.py +++ b/ironic/db/sqlalchemy/api.py @@ -789,6 +789,11 @@ class Connection(api.Connection): models.Allocation).filter_by(node_id=node_id) allocation_query.delete() + # delete all history for this node + history_query = model_query( + models.NodeHistory).filter_by(node_id=node_id) + history_query.delete() + query.delete() def update_node(self, node_id, values): @@ -2275,3 +2280,52 @@ class Connection(api.Connection): query = (_get_deploy_template_query_with_steps() .filter(models.DeployTemplate.name.in_(names))) return query.all() + + @oslo_db_api.retry_on_deadlock + def create_node_history(self, values): + values['uuid'] = uuidutils.generate_uuid() + + history = models.NodeHistory() + history.update(values) + with _session_for_write() as session: + try: + session.add(history) + session.flush() + except db_exc.DBDuplicateEntry: + raise exception.NodeHistoryAlreadyExists(uuid=values['uuid']) + return history + + @oslo_db_api.retry_on_deadlock + def destroy_node_history_by_uuid(self, history_uuid): + with _session_for_write(): + query = model_query(models.NodeHistory).filter_by( + uuid=history_uuid) + count = query.delete() + if count == 0: + raise exception.NodeHistoryNotFound(history=history_uuid) + + def get_node_history_by_id(self, history_id): + query = model_query(models.NodeHistory).filter_by(id=history_id) + try: + return query.one() + except NoResultFound: + raise exception.NodeHistoryNotFound(history=history_id) + + def get_node_history_by_uuid(self, history_uuid): + query = model_query(models.NodeHistory).filter_by(uuid=history_uuid) + try: + return query.one() + except NoResultFound: + raise exception.NodeHistoryNotFound(history=history_uuid) + + def get_node_history_list(self, limit=None, marker=None, + sort_key=None, sort_dir=None): + return _paginate_query(models.NodeHistory, limit, marker, sort_key, + sort_dir) + + def get_node_history_by_node_id(self, node_id, limit=None, marker=None, + sort_key=None, sort_dir=None): + query = model_query(models.NodeHistory) + query = query.filter_by(node_id=node_id) + return _paginate_query(models.NodeHistory, limit, marker, + sort_key, sort_dir, query) diff --git a/ironic/db/sqlalchemy/models.py b/ironic/db/sqlalchemy/models.py index 6a1c73d62..8f3f6a564 100644 --- a/ironic/db/sqlalchemy/models.py +++ b/ironic/db/sqlalchemy/models.py @@ -417,6 +417,26 @@ class DeployTemplateStep(Base): ) +class NodeHistory(Base): + """Represents a history event of a bare metal node.""" + + __tablename__ = 'node_history' + __table_args__ = ( + schema.UniqueConstraint('uuid', name='uniq_history0uuid'), + Index('history_node_id_idx', 'node_id'), + Index('history_uuid_idx', 'uuid'), + Index('history_conductor_idx', 'conductor'), + table_args()) + id = Column(Integer, primary_key=True) + uuid = Column(String(36), nullable=False) + conductor = Column(String(255), nullable=True) + event_type = Column(String(255), nullable=True) + severity = Column(String(255), nullable=True) + event = Column(Text, nullable=True) + user = Column(String(32), nullable=True) + node_id = Column(Integer, ForeignKey('nodes.id'), nullable=True) + + def get_class(model_name): """Returns the model class with the specified name. |