diff --git a/ironic/db/sqlalchemy/alembic/versions/2353895ecfae_add_conductor_hardware_interfaces_table.py b/ironic/db/sqlalchemy/alembic/versions/2353895ecfae_add_conductor_hardware_interfaces_table.py new file mode 100644 index 0000000000..a8a792292d --- /dev/null +++ b/ironic/db/sqlalchemy/alembic/versions/2353895ecfae_add_conductor_hardware_interfaces_table.py @@ -0,0 +1,47 @@ +# 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 conductor_hardware_interfaces table + +Revision ID: 2353895ecfae +Revises: 1a59178ebdf6 +Create Date: 2016-12-12 15:17:22.065056 + +""" + +# revision identifiers, used by Alembic. +revision = '2353895ecfae' +down_revision = '1d6951876d68' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.create_table('conductor_hardware_interfaces', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=True), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.Column('conductor_id', sa.Integer(), nullable=False), + sa.Column('hardware_type', sa.String(length=255), + nullable=False), + sa.Column('interface_type', sa.String(length=16), + nullable=False), + sa.Column('interface_name', sa.String(length=255), + nullable=False), + sa.ForeignKeyConstraint(['conductor_id'], + ['conductors.id']), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint( + 'conductor_id', 'hardware_type', + 'interface_type', 'interface_name', + name='uniq_conductorhardwareinterfaces0')) diff --git a/ironic/db/sqlalchemy/models.py b/ironic/db/sqlalchemy/models.py index 208793d0c3..d24a1c8e29 100644 --- a/ironic/db/sqlalchemy/models.py +++ b/ironic/db/sqlalchemy/models.py @@ -88,6 +88,25 @@ class Conductor(Base): online = Column(Boolean, default=True) +class ConductorHardwareInterfaces(Base): + """Internal table used to track what is loaded on each conductor.""" + + __tablename__ = 'conductor_hardware_interfaces' + __table_args__ = ( + schema.UniqueConstraint( + 'conductor_id', + 'hardware_type', + 'interface_type', + 'interface_name', + name='uniq_conductorhardwareinterfaces0'), + table_args()) + id = Column(Integer, primary_key=True) + conductor_id = Column(Integer, ForeignKey('conductors.id'), nullable=False) + hardware_type = Column(String(255), nullable=False) + interface_type = Column(String(16), nullable=False) + interface_name = Column(String(255), nullable=False) + + class Node(Base): """Represents a bare metal node.""" diff --git a/ironic/tests/unit/db/sqlalchemy/test_migrations.py b/ironic/tests/unit/db/sqlalchemy/test_migrations.py index 1db1786653..6d6ff8ccde 100644 --- a/ironic/tests/unit/db/sqlalchemy/test_migrations.py +++ b/ironic/tests/unit/db/sqlalchemy/test_migrations.py @@ -630,6 +630,28 @@ class MigrationCheckersMixin(object): self.assertIsInstance(nodes.c.storage_interface.type, sqlalchemy.types.String) + def _check_2353895ecfae(self, engine, data): + ifaces = db_utils.get_table(engine, 'conductor_hardware_interfaces') + col_names = [column.name for column in ifaces.c] + expected_names = ['created_at', 'updated_at', 'id', 'conductor_id', + 'hardware_type', 'interface_type', 'interface_name'] + self.assertEqual(sorted(expected_names), sorted(col_names)) + + self.assertIsInstance(ifaces.c.created_at.type, + sqlalchemy.types.DateTime) + self.assertIsInstance(ifaces.c.updated_at.type, + sqlalchemy.types.DateTime) + self.assertIsInstance(ifaces.c.id.type, + sqlalchemy.types.Integer) + self.assertIsInstance(ifaces.c.conductor_id.type, + sqlalchemy.types.Integer) + self.assertIsInstance(ifaces.c.hardware_type.type, + sqlalchemy.types.String) + self.assertIsInstance(ifaces.c.interface_type.type, + sqlalchemy.types.String) + self.assertIsInstance(ifaces.c.interface_name.type, + sqlalchemy.types.String) + def test_upgrade_and_version(self): with patch_with_engine(self.engine): self.migration_api.upgrade('head')