From 4c7712b33af402f7b9f7b6c80f41b3b8a776f732 Mon Sep 17 00:00:00 2001 From: Zhenguo Niu Date: Thu, 8 Oct 2015 10:23:13 +0800 Subject: [PATCH] Add db migration and model for tags table Change-Id: I2a812c59a0883dec5cb53af13d7ebd21c16c83b3 Implements: blueprint nodes-tagging --- .../versions/48d6c242bb9b_add_node_tags.py | 46 +++++++++++++++++++ ironic/db/sqlalchemy/models.py | 14 +++++- .../unit/db/sqlalchemy/test_migrations.py | 14 ++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 ironic/db/sqlalchemy/alembic/versions/48d6c242bb9b_add_node_tags.py diff --git a/ironic/db/sqlalchemy/alembic/versions/48d6c242bb9b_add_node_tags.py b/ironic/db/sqlalchemy/alembic/versions/48d6c242bb9b_add_node_tags.py new file mode 100644 index 0000000000..e57d98cf63 --- /dev/null +++ b/ironic/db/sqlalchemy/alembic/versions/48d6c242bb9b_add_node_tags.py @@ -0,0 +1,46 @@ +# 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 tags + +Revision ID: 48d6c242bb9b +Revises: 516faf1bb9b1 +Create Date: 2015-10-08 10:07:33.779516 + +""" + +# revision identifiers, used by Alembic. +revision = '48d6c242bb9b' +down_revision = '516faf1bb9b1' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.create_table( + 'node_tags', + sa.Column('created_at', sa.DateTime(), nullable=True), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.Column('node_id', sa.Integer(), nullable=False, + autoincrement=False), + sa.Column('tag', sa.String(length=255), nullable=False), + sa.ForeignKeyConstraint(['node_id'], ['nodes.id'], ), + sa.PrimaryKeyConstraint('node_id', 'tag'), + mysql_ENGINE='InnoDB', + mysql_DEFAULT_CHARSET='UTF8' + ) + op.create_index('node_tags_idx', 'node_tags', ['tag'], unique=False) + + +def downgrade(): + op.drop_table('node_tags') diff --git a/ironic/db/sqlalchemy/models.py b/ironic/db/sqlalchemy/models.py index 6465a5749d..be82ff6fe9 100644 --- a/ironic/db/sqlalchemy/models.py +++ b/ironic/db/sqlalchemy/models.py @@ -23,7 +23,7 @@ from oslo_db import options as db_options from oslo_db.sqlalchemy import models from oslo_db.sqlalchemy import types as db_types import six.moves.urllib.parse as urlparse -from sqlalchemy import Boolean, Column, DateTime +from sqlalchemy import Boolean, Column, DateTime, Index from sqlalchemy import ForeignKey, Integer from sqlalchemy import schema, String, Text from sqlalchemy.ext.declarative import declarative_base @@ -165,3 +165,15 @@ class Port(Base): address = Column(String(18)) node_id = Column(Integer, ForeignKey('nodes.id'), nullable=True) extra = Column(db_types.JsonEncodedDict) + + +class NodeTag(Base): + """Represents a tag of a bare metal node.""" + + __tablename__ = 'node_tags' + __table_args__ = ( + Index('node_tags_idx', 'tag'), + table_args()) + node_id = Column(Integer, ForeignKey('nodes.id'), + primary_key=True, nullable=False) + tag = Column(String(255), primary_key=True, nullable=False) diff --git a/ironic/tests/unit/db/sqlalchemy/test_migrations.py b/ironic/tests/unit/db/sqlalchemy/test_migrations.py index 29551476b0..aaf58b2ba8 100644 --- a/ironic/tests/unit/db/sqlalchemy/test_migrations.py +++ b/ironic/tests/unit/db/sqlalchemy/test_migrations.py @@ -393,6 +393,20 @@ class MigrationCheckersMixin(object): node = nodes.select(nodes.c.uuid == uuid).execute().first() self.assertEqual(bigstring, node['driver']) + def _check_48d6c242bb9b(self, engine, data): + node_tags = db_utils.get_table(engine, 'node_tags') + col_names = [column.name for column in node_tags.c] + self.assertIn('tag', col_names) + self.assertIsInstance(node_tags.c.tag.type, + sqlalchemy.types.String) + nodes = db_utils.get_table(engine, 'nodes') + data = {'id': '123', 'name': 'node1'} + nodes.insert().execute(data) + data = {'node_id': '123', 'tag': 'tag1'} + node_tags.insert().execute(data) + tag = node_tags.select(node_tags.c.node_id == '123').execute().first() + self.assertEqual('tag1', tag['tag']) + def test_upgrade_and_version(self): with patch_with_engine(self.engine): self.migration_api.upgrade('head')