Updates Alembic migration to better match SQLAlchemy models

The original Alembic migration script was autogenerated, then
subsequently modified by hand. Between these two aspects, some
correspondence to the corresponding SQLAlchemy models was lost:

* Columns were specified independently of corresponding foreign key
  and primary key constraints; besides making it more difficult to
  follow the code between models and the migration script, there was a
  loss of integrity constraints: a variable association must exist for
  every entity that mixes in VariableMixin as a base was not being
  enforced at the database level with an appropriate not-null; this
  causes problems for use of variables for any such object that is not
  constructed by models code, most notably via direct usage of the
  database. (See specifically
  https://bugs.launchpad.net/craton/+bug/1668251, fixed with this
  change.)

* The column created_at would always be set by model-using code; but
  this was not enforced at the database level by ensuring it was not
  null.

* Children should be deleted if the parent is deleted (we do not
  support "soft delete" in Craton).

In addition, all constraints are now named (the original intent of
this change, so as to ensure the feasibility of future migrations),
and they are also named in a consistent fashion.

Note that this change does not support many-to-many deletions (as seen
in https://bugs.launchpad.net/craton/+bug/1668308), but SQLAlchemy
does provide support for this at the model level. A future change can
address this without requiring Alembic support.

There's no direct testing of this change, but it is implicitly, and
rather strongly, tested by the overall functional tests that are used;
and to a lesser extent by some of the unit tests. This is in part
because this change has strengthened constraints, not weakened them.

Change-Id: I1f84c29610127de12c292a210fd003ae07bd6462
Closes-bug: 1665066
Closes-bug: 1668251
This commit is contained in:
Jim Baker 2017-03-29 11:25:22 -06:00
parent 96b6a40288
commit 7f1d3d8f53
3 changed files with 267 additions and 224 deletions

View File

@ -20,269 +20,342 @@ import sqlalchemy_utils
def upgrade():
op.create_table(
'variable_association',
sa.Column('created_at', sa.DateTime, nullable=True),
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('id', sa.Integer, nullable=False),
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('discriminator', sa.String(length=50), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table(
'variables',
sa.Column('created_at', sa.DateTime, nullable=True),
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('association_id', sa.Integer),
sa.Column('key_', sa.String(length=255), nullable=False),
sa.Column('value_', sa.JSON,
nullable=True),
sa.PrimaryKeyConstraint('association_id', 'key_'),
sa.ForeignKeyConstraint(
['association_id'], ['variable_association.id'],
'fk_variables_variable_association')
)
op.create_table(
'access_secrets',
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('cert', sa.Text(), nullable=True),
sa.PrimaryKeyConstraint('id')
sa.Column(
'association_id', sa.Integer,
sa.ForeignKey(
'variable_association.id',
name='fk_variables__variables_association',
ondelete='cascade'),
primary_key=True),
sa.Column('key_', sa.String(length=255), primary_key=True),
sa.Column('value_', sa.JSON, nullable=True),
)
op.create_index(
op.f('ix_variables_keys'), 'variables', ['key_'], unique=False)
op.create_table(
'projects',
sa.Column('created_at', sa.DateTime, nullable=True),
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('id', sqlalchemy_utils.types.UUIDType(binary=False),
nullable=False),
sa.Column('variable_association_id', sa.Integer),
sa.Column(
'id', sqlalchemy_utils.types.UUIDType(binary=False),
primary_key=True),
sa.Column(
'variable_association_id', sa.Integer,
sa.ForeignKey(
'variable_association.id',
name='fk_projects__variable_association'),
nullable=False),
sa.Column('name', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(
['variable_association_id'], ['variable_association.id'],
'fk_projects_variable_association')
)
op.create_table(
'clouds',
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('project_id', sqlalchemy_utils.types.UUIDType(binary=False),
nullable=False),
sa.Column('variable_association_id', sa.Integer),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('note', sa.Text, nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint(
'project_id', 'name',
name='uq_cloud0projectid0name'),
sa.ForeignKeyConstraint(['project_id'], ['projects.id']),
sa.ForeignKeyConstraint(
['variable_association_id'], ['variable_association.id'],
'fk_clouds_variable_association')
)
op.create_index(op.f('ix_clouds_project_id'),
'clouds', ['project_id'], unique=False)
op.create_table(
'regions',
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('project_id', sqlalchemy_utils.types.UUIDType(binary=False),
nullable=False),
sa.Column('cloud_id', sa.Integer, nullable=False),
sa.Column('variable_association_id', sa.Integer),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('note', sa.Text, nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint(
'cloud_id', 'name',
name='uq_region0cloudid0name'),
sa.ForeignKeyConstraint(['project_id'], ['projects.id']),
sa.ForeignKeyConstraint(['cloud_id'], ['clouds.id']),
sa.ForeignKeyConstraint(
['variable_association_id'], ['variable_association.id'],
'fk_regions_variable_association')
)
op.create_index(op.f('ix_regions_project_id'),
'regions', ['project_id'], unique=False)
op.create_index(op.f('ix_regions_cloud_id'),
'regions', ['cloud_id'], unique=False)
op.create_table(
'users',
sa.Column('created_at', sa.DateTime, nullable=True),
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('id', sa.Integer, nullable=False),
sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False),
nullable=False),
sa.Column('variable_association_id', sa.Integer),
sa.Column('id', sa.Integer, primary_key=True),
sa.Column(
'project_id', sqlalchemy_utils.types.UUIDType(binary=False),
sa.ForeignKey(
'projects.id', name='fk_users__projects', ondelete='cascade'),
nullable=False),
sa.Column(
'variable_association_id', sa.Integer,
sa.ForeignKey(
'variable_association.id',
name='fk_users__variable_association'),
nullable=False),
sa.Column('username', sa.String(length=255), nullable=True),
sa.Column('api_key', sa.String(length=36), nullable=True),
sa.Column('is_root', sa.Boolean, nullable=True),
sa.Column('is_admin', sa.Boolean, nullable=True),
sa.Column('roles', sa.JSON,
nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint(
'username', 'project_id',
name='uq_user0username0project'),
sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ),
sa.ForeignKeyConstraint(
['variable_association_id'], ['variable_association.id'],
'fk_users_variable_association')
name='uq_users_username_project_id'),
)
op.create_index(op.f('ix_users_project_id'), 'users', ['project_id'],
unique=False)
op.create_index(
op.f('ix_users_project_id'), 'users', ['project_id'], unique=False)
op.create_table(
'cells',
sa.Column('created_at', sa.DateTime, nullable=True),
'clouds',
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('id', sa.Integer, nullable=False),
sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False),
nullable=False),
sa.Column('cloud_id', sa.Integer, nullable=False),
sa.Column('region_id', sa.Integer, nullable=False),
sa.Column('variable_association_id', sa.Integer),
sa.Column('id', sa.Integer, primary_key=True),
sa.Column(
'project_id', sqlalchemy_utils.types.UUIDType(binary=False),
sa.ForeignKey(
'projects.id', name='fk_clouds__projects', ondelete='cascade'),
nullable=False),
sa.Column(
'variable_association_id', sa.Integer,
sa.ForeignKey(
'variable_association.id',
name='fk_clouds__variable_association'),
nullable=False),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('note', sa.Text, nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint(
'region_id', 'name', name='uq_cell0regionid0name'),
sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ),
sa.ForeignKeyConstraint(['cloud_id'], ['clouds.id'], ),
sa.ForeignKeyConstraint(['region_id'], ['regions.id'], ),
sa.ForeignKeyConstraint(
['variable_association_id'], ['variable_association.id'],
'fk_cells_variable_association')
'project_id', 'name',
name='uq_clouds__project_id__name'),
)
op.create_index(
op.f('ix_cells_project_id'), 'cells', ['project_id'],
unique=False)
op.f('ix_clouds_project_id'), 'clouds', ['project_id'], unique=False)
op.create_table(
'regions',
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('id', sa.Integer, primary_key=True),
sa.Column(
'project_id', sqlalchemy_utils.types.UUIDType(binary=False),
sa.ForeignKey(
'projects.id',
name='fk_projects__regions', ondelete='cascade')),
sa.Column(
'cloud_id', sa.Integer,
sa.ForeignKey(
'clouds.id', name='fk_regions__clouds', ondelete='cascade'),
nullable=False),
sa.Column(
'variable_association_id', sa.Integer,
sa.ForeignKey(
'variable_association.id',
name='fk_regions__variable_association'),
nullable=False),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('note', sa.Text, nullable=True),
sa.UniqueConstraint(
'cloud_id', 'name', name='uq_regions__cloud_id__name'),
)
op.create_index(
op.f('ix_cells_cloud_id'), 'cells', ['cloud_id'],
unique=False)
op.f('ix_regions_project_id'), 'regions', ['project_id'], unique=False)
op.create_index(
op.f('ix_cells_region_id'), 'cells', ['region_id'],
unique=False)
op.f('ix_regions_cloud_id'), 'regions', ['cloud_id'], unique=False)
op.create_table(
'cells',
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('id', sa.Integer, primary_key=True),
sa.Column(
'project_id', sqlalchemy_utils.types.UUIDType(binary=False),
sa.ForeignKey(
'projects.id', name='fk_cells__projects', ondelete='cascade'),
nullable=False),
sa.Column(
'cloud_id', sa.Integer,
sa.ForeignKey(
'clouds.id', name='fk_cells__clouds', ondelete='cascade'),
nullable=False),
sa.Column(
'region_id', sa.Integer,
sa.ForeignKey(
'regions.id', name='fk_cells__regions', ondelete='cascade'),
nullable=False),
sa.Column(
'variable_association_id', sa.Integer,
sa.ForeignKey(
'variable_association.id',
name='fk_cells__variable_association'),
nullable=False),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('note', sa.Text, nullable=True),
sa.UniqueConstraint(
'region_id', 'name', name='uq_cells__region_id__name'),
)
op.create_index(
op.f('ix_cells_project_id'), 'cells', ['project_id'], unique=False)
op.create_index(
op.f('ix_cells_cloud_id'), 'cells', ['cloud_id'], unique=False)
op.create_index(
op.f('ix_cells_region_id'), 'cells', ['region_id'], unique=False)
op.create_table(
'networks',
sa.Column('created_at', sa.DateTime, nullable=True),
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('id', sa.Integer, nullable=False),
sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False),
nullable=False),
sa.Column('cloud_id', sa.Integer, nullable=False),
sa.Column('region_id', sa.Integer, nullable=False),
sa.Column('cell_id', sa.Integer, nullable=True),
sa.Column('variable_association_id', sa.Integer),
sa.Column('id', sa.Integer, primary_key=True),
sa.Column(
'project_id', sqlalchemy_utils.types.UUIDType(binary=False),
sa.ForeignKey(
'projects.id',
name='fk_networks__projects', ondelete='cascade'),
nullable=False),
sa.Column(
'cloud_id', sa.Integer,
sa.ForeignKey(
'clouds.id', name='fk_networks__clouds', ondelete='cascade'),
nullable=False),
sa.Column(
'region_id', sa.Integer,
sa.ForeignKey(
'regions.id', name='fk_networks__regions', ondelete='cascade'),
nullable=False),
sa.Column(
'cell_id', sa.Integer,
sa.ForeignKey(
'cells.id', name='fk_networks__cells', ondelete='cascade'),
nullable=True),
sa.Column(
'variable_association_id', sa.Integer,
sa.ForeignKey(
'variable_association.id',
name='fk_networks__variable_association'),
nullable=False),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('cidr', sa.String(length=255), nullable=True),
sa.Column('gateway', sa.String(length=255), nullable=True),
sa.Column('netmask', sa.String(length=255), nullable=True),
sa.Column('ip_block_type', sa.String(length=255), nullable=True),
sa.Column('nss', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint("name", "project_id", "region_id",
name="uq_name0projectid0regionid"),
sa.ForeignKeyConstraint(['project_id'], ['projects.id']),
sa.ForeignKeyConstraint(['cloud_id'], ['clouds.id']),
sa.ForeignKeyConstraint(['region_id'], ['regions.id']),
sa.ForeignKeyConstraint(['cell_id'], ['cells.id']),
sa.ForeignKeyConstraint(
['variable_association_id'], ['variable_association.id'],
'fk_networks_variable_association')
sa.UniqueConstraint(
'name', 'project_id', 'region_id',
name='uq_networks__name__project_id__region_id'),
)
op.create_index(
op.f('ix_networks_cell_id'), 'networks', ['cell_id'],
unique=False)
op.f('ix_networks_cell_id'), 'networks', ['cell_id'], unique=False)
op.create_index(
op.f('ix_networks_project_id'), 'networks', ['project_id'],
unique=False)
op.create_index(
op.f('ix_networks_region_id'), 'networks', ['region_id'],
unique=False)
op.create_table(
'devices',
sa.Column('created_at', sa.DateTime, nullable=True),
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('id', sa.Integer, nullable=False),
sa.Column('type', sa.String(length=50), nullable=True),
sa.Column('id', sa.Integer, primary_key=True),
sa.Column(
'project_id', sqlalchemy_utils.types.UUIDType(binary=False),
sa.ForeignKey(
'projects.id',
name='fk_devices__projects', ondelete='cascade'),
nullable=False),
sa.Column(
'cloud_id', sa.Integer,
sa.ForeignKey(
'clouds.id', name='fk_devices__clouds', ondelete='cascade'),
nullable=False),
sa.Column(
'region_id', sa.Integer,
sa.ForeignKey(
'regions.id', name='fk_devices__regions', ondelete='cascade'),
nullable=False),
sa.Column(
'cell_id', sa.Integer,
sa.ForeignKey(
'cells.id', name='fk_devices__cells', ondelete='cascade'),
nullable=True),
sa.Column(
'parent_id', sa.Integer,
sa.ForeignKey('devices.id', name='fk_devices__devices'),
nullable=True),
sa.Column(
'variable_association_id', sa.Integer,
sa.ForeignKey(
'variable_association.id',
name='fk_devices__variable_association'),
nullable=False),
sa.Column('type', sa.String(length=50), nullable=False),
sa.Column('device_type', sa.String(length=255), nullable=False),
sa.Column('name', sa.String(length=255), nullable=False),
sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False),
nullable=False),
sa.Column('cloud_id', sa.Integer, nullable=False),
sa.Column('region_id', sa.Integer, nullable=False),
sa.Column('cell_id', sa.Integer, nullable=True),
sa.Column('parent_id', sa.Integer, nullable=True),
sa.Column('access_secret_id', sa.Integer, nullable=True),
sa.Column('variable_association_id', sa.Integer),
sa.Column('ip_address',
sqlalchemy_utils.types.IPAddressType(length=64),
nullable=False),
sa.Column(
'ip_address',
sqlalchemy_utils.types.IPAddressType(length=64),
nullable=False),
sa.Column('active', sa.Boolean(), nullable=True),
sa.Column('note', sa.Text(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('region_id', 'name',
name='uq_device0regionid0name'),
sa.ForeignKeyConstraint(['project_id'], ['projects.id']),
sa.ForeignKeyConstraint(['cloud_id'], ['clouds.id']),
sa.ForeignKeyConstraint(['region_id'], ['regions.id']),
sa.ForeignKeyConstraint(['cell_id'], ['cells.id']),
sa.ForeignKeyConstraint(['access_secret_id'], ['access_secrets.id']),
sa.ForeignKeyConstraint(['parent_id'], ['devices.id']),
sa.ForeignKeyConstraint(
['variable_association_id'], ['variable_association.id'],
'fk_devices_variable_association')
)
op.create_index(
op.f('ix_devices_cell_id'), 'devices', ['cell_id'],
unique=False)
op.f('ix_devices_cell_id'), 'devices', ['cell_id'], unique=False)
op.create_index(
op.f('ix_devices_project_id'), 'devices', ['project_id'],
unique=False)
op.f('ix_devices_project_id'), 'devices', ['project_id'], unique=False)
op.create_index(
op.f('ix_devices_region_id'), 'devices', ['region_id'],
unique=False)
op.f('ix_devices_region_id'), 'devices', ['region_id'], unique=False)
op.create_index(
op.f('ix_devices_cloud_id'), 'devices', ['cloud_id'],
unique=False)
op.f('ix_devices_cloud_id'), 'devices', ['cloud_id'], unique=False)
op.create_table(
'hosts',
sa.Column(
'id', sa.Integer,
sa.ForeignKey(
'devices.id', name='fk_hosts_devices', ondelete='cascade'),
'devices.id', name='fk_hosts__devices', ondelete='cascade'),
primary_key=True)
)
op.create_table(
'network_devices',
sa.Column(
'id', sa.Integer,
sa.ForeignKey(
'devices.id',
name='fk_network_devices_devices', ondelete='cascade'),
name='fk_network_devices__devices', ondelete='cascade'),
primary_key=True),
sa.Column('model_name', sa.String(length=255), nullable=True),
sa.Column('os_version', sa.String(length=255), nullable=True),
sa.Column('vlans', sa.JSON,
nullable=True)
)
op.create_table(
'labels',
sa.Column('created_at', sa.DateTime, nullable=True),
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('device_id', sa.Integer, nullable=False),
sa.Column('label', sa.String(length=255), nullable=False),
sa.PrimaryKeyConstraint('device_id', 'label'),
sa.ForeignKeyConstraint(
['device_id'], ['devices.id'],
'fk_labels_devices')
sa.Column(
'device_id', sa.Integer,
sa.ForeignKey(
'devices.id',
name='fk_labels__devices', ondelete='cascade'),
primary_key=True),
sa.Column('label', sa.String(length=255), primary_key=True),
)
op.create_index(
op.f('ix_devices_labels'), 'labels', ['label', 'device_id'])
op.create_table(
'network_interfaces',
sa.Column('created_at', sa.DateTime, nullable=True),
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('updated_at', sa.DateTime, nullable=True),
sa.Column('id', sa.Integer, nullable=False),
sa.Column('variable_association_id', sa.Integer),
sa.Column('id', sa.Integer, primary_key=True),
sa.Column(
'project_id', sqlalchemy_utils.types.UUIDType(binary=False),
sa.ForeignKey(
'projects.id',
name='fk_network_interfaces__projects', ondelete='cascade'),
nullable=False),
sa.Column(
'device_id', sa.Integer,
sa.ForeignKey(
'devices.id',
name='fk_network_interfaces__devices', ondelete='cascade'),
nullable=False),
sa.Column(
'network_id', sa.Integer,
sa.ForeignKey(
'networks.id',
name='fk_network_interfaces__networks'),
nullable=True),
sa.Column(
'variable_association_id', sa.Integer,
sa.ForeignKey(
'variable_association.id',
name='fk_network_interfaces__variable_association'),
nullable=False),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('interface_type', sa.String(length=255), nullable=True),
sa.Column('vlan_id', sa.Integer, nullable=True),
@ -294,30 +367,19 @@ def upgrade():
sa.Column('cdp', sa.String(length=255), nullable=True),
sa.Column('security', sa.String(length=255), nullable=True),
sa.Column(
'device_id', sa.Integer,
sa.ForeignKey(
'devices.id',
name='fk_network_interfaces_devices', ondelete='cascade'),
'ip_address',
sqlalchemy_utils.types.IPAddressType(length=64),
nullable=False),
sa.Column('network_id', sa.Integer, nullable=True),
sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False),
nullable=False),
sa.Column('ip_address',
sqlalchemy_utils.types.IPAddressType(length=64),
nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint(
'device_id', 'name', name='uq_netinter0deviceid0name'),
sa.ForeignKeyConstraint(['project_id'], ['projects.id']),
sa.ForeignKeyConstraint(['network_id'], ['networks.id'], ),
sa.ForeignKeyConstraint(
['variable_association_id'], ['variable_association.id'],
'fk_network_interfaces_variable_association')
'device_id', 'name',
name='uq_network_interfaces__device_id__name'),
)
def downgrade():
op.drop_table('network_interfaces')
op.drop_index(op.f('ix_devices_labels'), table_name='labels')
op.drop_table('labels')
op.drop_table('network_devices')
op.drop_table('hosts')
op.drop_index(op.f('ix_networks_region_id'), table_name='networks')
@ -335,14 +397,13 @@ def downgrade():
op.drop_index(op.f('ix_cells_project_id'), table_name='cells')
op.drop_table('cells')
op.drop_index(op.f('ix_users_project_id'), table_name='users')
op.drop_table('users')
op.drop_index(op.f('ix_regions_project_id'), table_name='regions')
op.drop_index(op.f('ix_regions_cloud_id'), table_name='regions')
op.drop_table('regions')
op.drop_index(op.f('ix_clouds_project_id'), table_name='clouds')
op.drop_table('clouds')
op.drop_table('users')
op.drop_table('projects')
op.drop_table('labels')
op.drop_table('access_secrets')
op.drop_index(op.f('ix_variable_keys'), table_name='variables')
op.drop_table('variables')
op.drop_table('variable_association')

View File

@ -244,6 +244,7 @@ class Project(Base, VariableMixin):
devices = relationship('Device', back_populates='project')
users = relationship('User', back_populates='project')
networks = relationship('Network', back_populates='project')
interfaces = relationship('NetworkInterface', back_populates='project')
class User(Base, VariableMixin):
@ -258,11 +259,11 @@ class User(Base, VariableMixin):
nullable=False)
username = Column(String(255))
api_key = Column(String(36))
# root = craton admin that can create other pojects/usrs
# root = craton admin that can create other projects/users
is_root = Column(Boolean, default=False)
# admin = project context admin
is_admin = Column(Boolean, default=False)
roles = Column(JSON)
_repr_columns = [id, username]
project = relationship('Project', back_populates='users')
@ -371,7 +372,6 @@ class Device(Base, VariableMixin):
project_id = Column(
UUIDType(binary=False), ForeignKey('projects.id'), index=True,
nullable=False)
access_secret_id = Column(Integer, ForeignKey('access_secrets.id'))
parent_id = Column(Integer, ForeignKey('devices.id'))
ip_address = Column(IPAddressType, nullable=False)
device_type = Column(String(255), nullable=False)
@ -389,7 +389,6 @@ class Device(Base, VariableMixin):
'Label', back_populates='device', collection_class=set,
cascade='all, delete-orphan', lazy='joined')
labels = association_proxy('related_labels', 'label')
access_secret = relationship('AccessSecret', back_populates='devices')
interfaces = relationship('NetworkInterface', back_populates='device')
children = relationship(
'Device', backref=backref('parent', remote_side=[id]))
@ -462,7 +461,7 @@ class Host(Device):
}
class NetworkInterface(Base):
class NetworkInterface(Base, VariableMixin):
__tablename__ = 'network_interfaces'
__table_args__ = (
UniqueConstraint("device_id", "name",
@ -485,10 +484,12 @@ class NetworkInterface(Base):
device_id = Column(Integer, ForeignKey('devices.id'))
network_id = Column(Integer, ForeignKey('networks.id'), nullable=True)
network = relationship('Network', back_populates="devices",
cascade='all', lazy='joined')
device = relationship('Device', back_populates="interfaces",
cascade='all', lazy='joined')
project = relationship(
'Project', back_populates='interfaces', cascade='all', lazy='joined')
network = relationship(
'Network', back_populates='interfaces', cascade='all', lazy='joined')
device = relationship(
'Device', back_populates='interfaces', cascade='all', lazy='joined')
class Network(Base, VariableMixin):
@ -518,7 +519,7 @@ class Network(Base, VariableMixin):
cloud = relationship('Cloud', back_populates='networks')
region = relationship('Region', back_populates='networks')
cell = relationship('Cell', back_populates='networks')
devices = relationship('NetworkInterface', back_populates='network')
interfaces = relationship('NetworkInterface', back_populates='network')
class NetworkDevice(Device):
@ -550,21 +551,3 @@ class Label(Base):
self.label = label
device = relationship("Device", back_populates="related_labels")
class AccessSecret(Base):
"""Represents a secret for accessing a host. It may be shared.
For now we assume a PEM-encoded certificate that wraps the private
key. Such certs may or may not be encrypted; if encrypted, the
configuration specifies how to interact with other systems, such
as Barbican or Hashicorp Vault, to retrieve secret data to unlock
this cert.
Note that this does not include secrets such as Ansible vault
files; those are stored outside the inventory database as part of
the configuration.
"""
__tablename__ = 'access_secrets'
id = Column(Integer, primary_key=True)
cert = Column(Text)
devices = relationship('Device', back_populates='access_secret')

View File

@ -20,7 +20,6 @@ mysqladmin flush-privileges
##############
/craton/bin/craton-dbsync --config-file=/craton/etc/craton-api-conf.sample upgrade
####################################
# Create initial project and users #
####################################