Collapse SQL Migrations
SQL Migrations for Juno require the schema version to be at 036 which is the final verison for the Havana release. This limits the change sets that could affect assumptions made in earlier migration files. Migrating to before the Havana release migration is no longer supported. Change-Id: Ie58507473b92cb100a9d556985e7d7756f9649e4 bp: sql-migration-collapse-juno
This commit is contained in:
@@ -1,155 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
# Upgrade operations go here. Don't create your own engine; bind
|
||||
# migrate_engine to your metadata
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
# catalog
|
||||
|
||||
service_table = sql.Table(
|
||||
'service',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('type', sql.String(255)),
|
||||
sql.Column('extra', sql.Text()))
|
||||
service_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
endpoint_table = sql.Table(
|
||||
'endpoint',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('region', sql.String(255)),
|
||||
sql.Column('service_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('service.id'),
|
||||
nullable=False),
|
||||
sql.Column('extra', sql.Text()))
|
||||
endpoint_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
# identity
|
||||
|
||||
role_table = sql.Table(
|
||||
'role',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(255), unique=True, nullable=False))
|
||||
role_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
if migrate_engine.name == 'ibm_db_sa':
|
||||
# NOTE(blk-u): SQLAlchemy for PostgreSQL picks the name tenant_name_key
|
||||
# for the unique constraint, but for DB2 doesn't give the UC a name
|
||||
# unless we tell it to and there is no DDL to alter a column to drop
|
||||
# an unnamed unique constraint, so this code creates a named unique
|
||||
# constraint on the name column rather than an unnamed one.
|
||||
# (This is used in migration 16.)
|
||||
tenant_table = sql.Table(
|
||||
'tenant',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.UniqueConstraint('name', name='tenant_name_key'))
|
||||
else:
|
||||
tenant_table = sql.Table(
|
||||
'tenant',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('extra', sql.Text()))
|
||||
|
||||
tenant_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
metadata_table = sql.Table(
|
||||
'metadata',
|
||||
meta,
|
||||
sql.Column('user_id', sql.String(64), primary_key=True),
|
||||
sql.Column('tenant_id', sql.String(64), primary_key=True),
|
||||
sql.Column('data', sql.Text()))
|
||||
metadata_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
ec2_credential_table = sql.Table(
|
||||
'ec2_credential',
|
||||
meta,
|
||||
sql.Column('access', sql.String(64), primary_key=True),
|
||||
sql.Column('secret', sql.String(64)),
|
||||
sql.Column('user_id', sql.String(64)),
|
||||
sql.Column('tenant_id', sql.String(64)))
|
||||
ec2_credential_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
if migrate_engine.name == 'ibm_db_sa':
|
||||
# NOTE(blk-u): SQLAlchemy for PostgreSQL picks the name user_name_key
|
||||
# for the unique constraint, but for DB2 doesn't give the UC a name
|
||||
# unless we tell it to and there is no DDL to alter a column to drop
|
||||
# an unnamed unique constraint, so this code creates a named unique
|
||||
# constraint on the name column rather than an unnamed one.
|
||||
# (This is used in migration 16.)
|
||||
user_table = sql.Table(
|
||||
'user',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.UniqueConstraint('name', name='user_name_key'))
|
||||
else:
|
||||
user_table = sql.Table(
|
||||
'user',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('extra', sql.Text()))
|
||||
|
||||
user_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
user_tenant_membership_table = sql.Table(
|
||||
'user_tenant_membership',
|
||||
meta,
|
||||
sql.Column(
|
||||
'user_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('user.id'),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'tenant_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('tenant.id'),
|
||||
primary_key=True))
|
||||
user_tenant_membership_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
# token
|
||||
|
||||
token_table = sql.Table(
|
||||
'token',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('expires', sql.DateTime()),
|
||||
sql.Column('extra', sql.Text()))
|
||||
token_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
# Operations to reverse the above upgrade go here.
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
tables = ['user_tenant_membership', 'token', 'user', 'tenant', 'role',
|
||||
'metadata', 'ec2_credential', 'endpoint', 'service']
|
||||
for t in tables:
|
||||
table = sql.Table(t, meta, autoload=True)
|
||||
table.drop(migrate_engine, checkfirst=True)
|
||||
@@ -1,8 +0,0 @@
|
||||
drop table token;
|
||||
|
||||
CREATE TABLE token (
|
||||
id VARCHAR(64) NOT NULL,
|
||||
expires DATETIME,
|
||||
extra TEXT,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
@@ -1,27 +0,0 @@
|
||||
CREATE TABLE token_backup (
|
||||
id_hash VARCHAR(64) NOT NULL,
|
||||
id VARCHAR(1024),
|
||||
expires DATETIME,
|
||||
extra TEXT,
|
||||
PRIMARY KEY (id_hash)
|
||||
);
|
||||
|
||||
insert into token_backup
|
||||
select id as old_id,
|
||||
'',
|
||||
expires as old_expires,
|
||||
extra as old_extra from token;
|
||||
|
||||
drop table token;
|
||||
|
||||
CREATE TABLE token (
|
||||
id_hash VARCHAR(64) NOT NULL,
|
||||
id VARCHAR(1024),
|
||||
expires DATETIME,
|
||||
extra TEXT,
|
||||
PRIMARY KEY (id_hash)
|
||||
);
|
||||
|
||||
insert into token select * from token_backup;
|
||||
|
||||
drop table token_backup;
|
||||
@@ -1,41 +0,0 @@
|
||||
# Copyright (c) 2012 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from sqlalchemy import Column, MetaData, String, Table
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = Table('token', meta, autoload=True)
|
||||
old_id_col = token.c.id
|
||||
old_id_col.alter(name='id_hash')
|
||||
# Note: We obtain a new metadata reference to avoid
|
||||
# sqlalchemy.exc.ArgumentError:
|
||||
# Trying to redefine primary-key column 'id' as a non-primary-key...
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = Table('token', meta, autoload=True)
|
||||
new_id = Column("id", String(2048))
|
||||
token.create_column(new_id)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = Table('token', meta, autoload=True)
|
||||
token.drop_column('id')
|
||||
token = Table('token', meta, autoload=True)
|
||||
id_col = token.c.id_hash
|
||||
id_col.alter(name='id')
|
||||
@@ -1,3 +0,0 @@
|
||||
alter TABLE token ADD valid integer;
|
||||
update token set valid = 1;
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# Copyright 2012 OpenStack LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
# Upgrade operations go here. Don't create your own engine; bind
|
||||
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
# creating the column immediately with nullable=False fails with
|
||||
# PostgreSQL (LP 1068181), so do it in two steps instead
|
||||
valid = sql.Column(
|
||||
'valid', sql.Boolean(), sql.ColumnDefault(True), nullable=True)
|
||||
valid.create(token, populate_default=True)
|
||||
valid.alter(type=sql.Boolean(), default=True, nullable=False)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
token.drop_column('valid')
|
||||
@@ -1,41 +0,0 @@
|
||||
# Copyright (c) 2012 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from sqlalchemy import Column, MetaData, String, Table
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = Table('token', meta, autoload=True)
|
||||
old_id_col = token.c.id
|
||||
old_id_col.alter(name='id_hash')
|
||||
# Note: We obtain a new metadata reference to avoid
|
||||
# sqlalchemy.exc.ArgumentError:
|
||||
# Trying to redefine primary-key column 'id' as a non-primary-key...
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = Table('token', meta, autoload=True)
|
||||
new_id = Column("id", String(2048))
|
||||
token.create_column(new_id)
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = Table('token', meta, autoload=True)
|
||||
token.drop_column('id')
|
||||
token = Table('token', meta, autoload=True)
|
||||
id_col = token.c.id_hash
|
||||
id_col.alter(name='id')
|
||||
@@ -1,48 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
from sqlalchemy import MetaData
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
# Upgrade operations go here. Don't create your own engine; bind
|
||||
# migrate_engine to your metadata
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
if migrate_engine.name == "mysql":
|
||||
tables = ['tenant', 'user', 'role', 'token', 'service', 'metadata',
|
||||
'ec2_credential', 'endpoint', 'user_tenant_membership']
|
||||
sql = "SET foreign_key_checks = 0;"
|
||||
|
||||
for table in tables:
|
||||
sql += "ALTER TABLE %s CONVERT TO CHARACTER SET utf8;" % table
|
||||
sql += "SET foreign_key_checks = 1;"
|
||||
sql += "ALTER DATABASE %s DEFAULT CHARACTER SET utf8;" \
|
||||
% migrate_engine.url.database
|
||||
migrate_engine.execute(sql)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
# Operations to reverse the above upgrade go here.
|
||||
if migrate_engine.name == "mysql":
|
||||
tables = ['tenant', 'user', 'role', 'token', 'service', 'metadata',
|
||||
'ec2_credential', 'endpoint', 'user_tenant_membership']
|
||||
sql = "SET foreign_key_checks = 0;"
|
||||
|
||||
for table in tables:
|
||||
sql += "ALTER TABLE %s CONVERT TO CHARACTER SET latin1;" % table
|
||||
sql += "SET foreign_key_checks = 1;"
|
||||
sql += "ALTER DATABASE %s DEFAULT CHARACTER SET latin1;" \
|
||||
% migrate_engine.url.database
|
||||
@@ -1,37 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
policy_table = sql.Table(
|
||||
'policy',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('type', sql.String(255), nullable=False),
|
||||
sql.Column('blob', sql.Text(), nullable=False),
|
||||
sql.Column('extra', sql.Text()))
|
||||
policy_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
policy_table = sql.Table('policy', meta, autoload=True)
|
||||
policy_table.drop(migrate_engine, checkfirst=True)
|
||||
@@ -1,82 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
# Upgrade operations go here. Don't create your own engine; bind
|
||||
# migrate_engine to your metadata
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
domain_table = sql.Table(
|
||||
'domain',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('enabled', sql.Boolean, nullable=False, default=True),
|
||||
sql.Column('extra', sql.Text()))
|
||||
domain_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
sql.Table('user', meta, autoload=True)
|
||||
user_domain_metadata_table = sql.Table(
|
||||
'user_domain_metadata',
|
||||
meta,
|
||||
sql.Column(
|
||||
'user_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('user.id'),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'domain_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('domain.id'),
|
||||
primary_key=True),
|
||||
sql.Column('data', sql.Text()))
|
||||
user_domain_metadata_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
sql.Table('tenant', meta, autoload=True)
|
||||
credential_table = sql.Table(
|
||||
'credential',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('user_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('user.id'),
|
||||
nullable=False),
|
||||
sql.Column('project_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('tenant.id')),
|
||||
sql.Column('blob', sql.Text(), nullable=False),
|
||||
sql.Column('type', sql.String(255), nullable=False),
|
||||
sql.Column('extra', sql.Text()))
|
||||
credential_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
role = sql.Table('role', meta, autoload=True)
|
||||
extra = sql.Column('extra', sql.Text())
|
||||
role.create_column(extra)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
role = sql.Table('role', meta, autoload=True)
|
||||
role.drop_column('extra')
|
||||
|
||||
tables = ['user_domain_metadata', 'credential', 'domain']
|
||||
for t in tables:
|
||||
table = sql.Table(t, meta, autoload=True)
|
||||
table.drop(migrate_engine, checkfirst=True)
|
||||
@@ -1,57 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import json
|
||||
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy import orm
|
||||
|
||||
from keystone import config
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
"""Creates the default domain."""
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
domain_table = sql.Table('domain', meta, autoload=True)
|
||||
|
||||
domain = {
|
||||
'id': CONF.identity.default_domain_id,
|
||||
'name': 'Default',
|
||||
'enabled': True,
|
||||
'extra': json.dumps({
|
||||
'description': 'Owns users and tenants (i.e. projects) available '
|
||||
'on Identity API v2.'})}
|
||||
|
||||
session = orm.sessionmaker(bind=migrate_engine)()
|
||||
insert = domain_table.insert()
|
||||
insert.execute(domain)
|
||||
session.commit()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
"""Delete the default domain."""
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
sql.Table('domain', meta, autoload=True)
|
||||
session = orm.sessionmaker(bind=migrate_engine)()
|
||||
session.execute(
|
||||
'DELETE FROM domain WHERE id=:id',
|
||||
{'id': CONF.identity.default_domain_id})
|
||||
session.commit()
|
||||
@@ -1,110 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
from sqlalchemy import Column, MetaData, String, Table, Text, types
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
|
||||
# sqlite doesn't support dropping columns. Copy to a new table instead
|
||||
def downgrade_user_table_with_copy(meta, migrate_engine):
|
||||
maker = sessionmaker(bind=migrate_engine)
|
||||
session = maker()
|
||||
session.execute("ALTER TABLE user RENAME TO orig_user;")
|
||||
|
||||
user_table = Table(
|
||||
'user',
|
||||
meta,
|
||||
Column('id', String(64), primary_key=True),
|
||||
Column('name', String(64), unique=True, nullable=False),
|
||||
Column('extra', Text()))
|
||||
user_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
orig_user_table = Table('orig_user', meta, autoload=True)
|
||||
for user in session.query(orig_user_table):
|
||||
session.execute("insert into user (id, name, extra) "
|
||||
"values ( :id, :name, :extra);",
|
||||
{'id': user.id,
|
||||
'name': user.name,
|
||||
'extra': user.extra})
|
||||
session.execute("drop table orig_user;")
|
||||
session.close()
|
||||
|
||||
|
||||
def downgrade_tenant_table_with_copy(meta, migrate_engine):
|
||||
maker = sessionmaker(bind=migrate_engine)
|
||||
session = maker()
|
||||
session.execute("ALTER TABLE tenant RENAME TO orig_tenant;")
|
||||
|
||||
tenant_table = Table(
|
||||
'tenant',
|
||||
meta,
|
||||
Column('id', String(64), primary_key=True),
|
||||
Column('name', String(64), unique=True, nullable=False),
|
||||
Column('extra', Text()))
|
||||
tenant_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
orig_tenant_table = Table('orig_tenant', meta, autoload=True)
|
||||
for tenant in session.query(orig_tenant_table):
|
||||
session.execute("insert into tenant (id, name, extra) "
|
||||
"values ( :id, :name, :extra);",
|
||||
{'id': tenant.id,
|
||||
'name': tenant.name,
|
||||
'extra': tenant.extra})
|
||||
session.execute("drop table orig_tenant;")
|
||||
session.close()
|
||||
|
||||
|
||||
def downgrade_user_table_with_column_drop(meta, migrate_engine):
|
||||
user_table = Table('user', meta, autoload=True)
|
||||
user_table.drop_column(Column('password', String(128)))
|
||||
user_table.drop_column(Column('enabled', types.Boolean,
|
||||
default=True))
|
||||
|
||||
|
||||
def downgrade_tenant_table_with_column_drop(meta, migrate_engine):
|
||||
tenant_table = Table('tenant', meta, autoload=True)
|
||||
tenant_table.drop_column(Column('description', Text()))
|
||||
tenant_table.drop_column(Column('enabled', types.Boolean))
|
||||
|
||||
|
||||
def upgrade_user_table(meta, migrate_engine):
|
||||
user_table = Table('user', meta, autoload=True)
|
||||
user_table.create_column(Column('password', String(128)))
|
||||
user_table.create_column(Column('enabled', types.Boolean,
|
||||
default=True))
|
||||
|
||||
|
||||
def upgrade_tenant_table(meta, migrate_engine):
|
||||
tenant_table = Table('tenant', meta, autoload=True)
|
||||
tenant_table.create_column(Column('description', Text()))
|
||||
tenant_table.create_column(Column('enabled', types.Boolean))
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
upgrade_user_table(meta, migrate_engine)
|
||||
upgrade_tenant_table(meta, migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
if migrate_engine.name == 'sqlite':
|
||||
downgrade_user_table_with_copy(meta, migrate_engine)
|
||||
downgrade_tenant_table_with_copy(meta, migrate_engine)
|
||||
else:
|
||||
downgrade_user_table_with_column_drop(meta, migrate_engine)
|
||||
downgrade_tenant_table_with_column_drop(meta, migrate_engine)
|
||||
@@ -1,103 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import json
|
||||
|
||||
import six
|
||||
|
||||
from sqlalchemy import MetaData, Table
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
|
||||
DISABLED_VALUES = ['false', 'disabled', 'no', '0']
|
||||
|
||||
|
||||
def is_enabled(enabled):
|
||||
# no explicit value means enabled
|
||||
if enabled is True or enabled is None:
|
||||
return True
|
||||
if (isinstance(enabled, six.string_types)
|
||||
and enabled.lower() in DISABLED_VALUES):
|
||||
return False
|
||||
return bool(enabled)
|
||||
|
||||
|
||||
def downgrade_user_table(meta, migrate_engine, session):
|
||||
user_table = Table('user', meta, autoload=True)
|
||||
for user in session.query(user_table).all():
|
||||
extra = json.loads(user.extra)
|
||||
extra['password'] = user.password
|
||||
extra['enabled'] = '%r' % is_enabled(user.enabled)
|
||||
values = {'extra': json.dumps(extra)}
|
||||
update = user_table.update().\
|
||||
where(user_table.c.id == user.id).\
|
||||
values(values)
|
||||
migrate_engine.execute(update)
|
||||
|
||||
|
||||
def downgrade_tenant_table(meta, migrate_engine, session):
|
||||
tenant_table = Table('tenant', meta, autoload=True)
|
||||
for tenant in session.query(tenant_table).all():
|
||||
extra = json.loads(tenant.extra)
|
||||
extra['description'] = tenant.description
|
||||
extra['enabled'] = '%r' % is_enabled(tenant.enabled)
|
||||
values = {'extra': json.dumps(extra)}
|
||||
update = tenant_table.update().\
|
||||
where(tenant_table.c.id == tenant.id).\
|
||||
values(values)
|
||||
migrate_engine.execute(update)
|
||||
|
||||
|
||||
def upgrade_user_table(meta, migrate_engine, session):
|
||||
user_table = Table('user', meta, autoload=True)
|
||||
for user in session.query(user_table).all():
|
||||
extra = json.loads(user.extra)
|
||||
values = {'password': extra.pop('password', None),
|
||||
'enabled': is_enabled(extra.pop('enabled', True)),
|
||||
'extra': json.dumps(extra)}
|
||||
update = user_table.update().\
|
||||
where(user_table.c.id == user.id).\
|
||||
values(values)
|
||||
migrate_engine.execute(update)
|
||||
|
||||
|
||||
def upgrade_tenant_table(meta, migrate_engine, session):
|
||||
tenant_table = Table('tenant', meta, autoload=True)
|
||||
for tenant in session.query(tenant_table):
|
||||
extra = json.loads(tenant.extra)
|
||||
values = {'description': extra.pop('description', None),
|
||||
'enabled': is_enabled(extra.pop('enabled', True)),
|
||||
'extra': json.dumps(extra)}
|
||||
update = tenant_table.update().\
|
||||
where(tenant_table.c.id == tenant.id).\
|
||||
values(values)
|
||||
migrate_engine.execute(update)
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
upgrade_user_table(meta, migrate_engine, session)
|
||||
upgrade_tenant_table(meta, migrate_engine, session)
|
||||
session.commit()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
downgrade_user_table(meta, migrate_engine, session)
|
||||
downgrade_tenant_table(meta, migrate_engine, session)
|
||||
session.commit()
|
||||
@@ -1,68 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
from keystone.common.sql import migration_helpers
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
"""Create API-version specific endpoint tables."""
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
legacy_table = sql.Table('endpoint', meta, autoload=True)
|
||||
|
||||
renames = {'endpoint_v2': legacy_table}
|
||||
service_table = sql.Table('service', meta, autoload=True)
|
||||
constraints = [{'table': legacy_table,
|
||||
'fk_column': 'service_id',
|
||||
'ref_column': service_table.c.id}]
|
||||
migration_helpers.rename_tables_with_constraints(renames, constraints,
|
||||
migrate_engine)
|
||||
|
||||
sql.Table('service', meta, autoload=True)
|
||||
new_table = sql.Table(
|
||||
'endpoint_v3',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('legacy_endpoint_id', sql.String(64)),
|
||||
sql.Column('interface', sql.String(8), nullable=False),
|
||||
sql.Column('region', sql.String(255)),
|
||||
sql.Column('service_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('service.id'),
|
||||
nullable=False),
|
||||
sql.Column('url', sql.Text(), nullable=False),
|
||||
sql.Column('extra', sql.Text()))
|
||||
new_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
"""Replace API-version specific endpoint tables with one based on v2."""
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
new_table = sql.Table('endpoint_v3', meta, autoload=True)
|
||||
new_table.drop()
|
||||
|
||||
legacy_table = sql.Table('endpoint_v2', meta, autoload=True)
|
||||
|
||||
renames = {'endpoint': legacy_table}
|
||||
service_table = sql.Table('service', meta, autoload=True)
|
||||
constraints = [{'table': legacy_table,
|
||||
'fk_column': 'service_id',
|
||||
'ref_column': service_table.c.id}]
|
||||
migration_helpers.rename_tables_with_constraints(renames, constraints,
|
||||
migrate_engine)
|
||||
@@ -1,97 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import json
|
||||
import uuid
|
||||
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy import orm
|
||||
|
||||
|
||||
ENDPOINT_TYPES = ['public', 'internal', 'admin']
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
"""Split each legacy endpoint into separate records for each interface."""
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
legacy_table = sql.Table('endpoint_v2', meta, autoload=True)
|
||||
new_table = sql.Table('endpoint_v3', meta, autoload=True)
|
||||
|
||||
session = orm.sessionmaker(bind=migrate_engine)()
|
||||
for ref in session.query(legacy_table).all():
|
||||
# pull urls out of extra
|
||||
extra = json.loads(ref.extra)
|
||||
urls = dict((i, extra.pop('%surl' % i)) for i in ENDPOINT_TYPES)
|
||||
|
||||
for interface in ENDPOINT_TYPES:
|
||||
endpoint = {
|
||||
'id': uuid.uuid4().hex,
|
||||
'legacy_endpoint_id': ref.id,
|
||||
'interface': interface,
|
||||
'region': ref.region,
|
||||
'service_id': ref.service_id,
|
||||
'url': urls[interface],
|
||||
'extra': json.dumps(extra),
|
||||
}
|
||||
insert = new_table.insert().values(endpoint)
|
||||
migrate_engine.execute(insert)
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
"""Re-create the v2 endpoints table based on v3 endpoints."""
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
legacy_table = sql.Table('endpoint_v2', meta, autoload=True)
|
||||
new_table = sql.Table('endpoint_v3', meta, autoload=True)
|
||||
|
||||
session = orm.sessionmaker(bind=migrate_engine)()
|
||||
for ref in session.query(new_table).all():
|
||||
extra = json.loads(ref.extra)
|
||||
legacy_id = ref.legacy_endpoint_id or extra.get('legacy_endpoint_id')
|
||||
if not legacy_id:
|
||||
continue
|
||||
|
||||
q = session.query(legacy_table)
|
||||
q = q.filter_by(id=legacy_id)
|
||||
legacy_ref = q.first()
|
||||
if legacy_ref:
|
||||
# We already have one, so just update the extra
|
||||
# attribute with the urls.
|
||||
extra = json.loads(legacy_ref.extra)
|
||||
extra['%surl' % ref.interface] = ref.url
|
||||
values = {'extra': json.dumps(extra)}
|
||||
update = legacy_table.update().\
|
||||
where(legacy_table.c.id == legacy_ref.id).\
|
||||
values(values)
|
||||
migrate_engine.execute(update)
|
||||
else:
|
||||
# This is the first one of this legacy ID, so
|
||||
# we can insert instead.
|
||||
extra = json.loads(ref.extra)
|
||||
extra['%surl' % ref.interface] = ref.url
|
||||
endpoint = {
|
||||
'id': legacy_id,
|
||||
'region': ref.region,
|
||||
'service_id': ref.service_id,
|
||||
'extra': json.dumps(extra),
|
||||
}
|
||||
insert = legacy_table.insert().values(endpoint)
|
||||
migrate_engine.execute(insert)
|
||||
session.commit()
|
||||
session.close()
|
||||
@@ -1,65 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
from keystone.common.sql import migration_helpers
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
"""Replace API-version specific endpoint tables with one based on v3."""
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
legacy_table = sql.Table('endpoint_v2', meta, autoload=True)
|
||||
legacy_table.drop()
|
||||
|
||||
new_table = sql.Table('endpoint_v3', meta, autoload=True)
|
||||
|
||||
renames = {'endpoint': new_table}
|
||||
service_table = sql.Table('service', meta, autoload=True)
|
||||
constraints = [{'table': new_table,
|
||||
'fk_column': 'service_id',
|
||||
'ref_column': service_table.c.id}]
|
||||
migration_helpers.rename_tables_with_constraints(renames, constraints,
|
||||
migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
"""Create API-version specific endpoint tables."""
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
new_table = sql.Table('endpoint', meta, autoload=True)
|
||||
|
||||
renames = {'endpoint_v3': new_table}
|
||||
service_table = sql.Table('service', meta, autoload=True)
|
||||
constraints = [{'table': new_table,
|
||||
'fk_column': 'service_id',
|
||||
'ref_column': service_table.c.id}]
|
||||
migration_helpers.rename_tables_with_constraints(renames, constraints,
|
||||
migrate_engine)
|
||||
|
||||
sql.Table('service', meta, autoload=True)
|
||||
legacy_table = sql.Table(
|
||||
'endpoint_v2',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('region', sql.String(255)),
|
||||
sql.Column('service_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('service.id'),
|
||||
nullable=False),
|
||||
sql.Column('extra', sql.Text()))
|
||||
legacy_table.create(migrate_engine, checkfirst=True)
|
||||
@@ -1,93 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
sql.Table('domain', meta, autoload=True)
|
||||
group_table = sql.Table(
|
||||
'group',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('domain_id', sql.String(64), sql.ForeignKey('domain.id'),
|
||||
nullable=False),
|
||||
sql.Column('name', sql.String(64), nullable=False),
|
||||
sql.Column('description', sql.Text()),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.UniqueConstraint('domain_id', 'name'))
|
||||
group_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
sql.Table('user', meta, autoload=True)
|
||||
user_group_membership_table = sql.Table(
|
||||
'user_group_membership',
|
||||
meta,
|
||||
sql.Column(
|
||||
'user_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('user.id'),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'group_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('group.id'),
|
||||
primary_key=True))
|
||||
user_group_membership_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
sql.Table('tenant', meta, autoload=True)
|
||||
group_project_metadata_table = sql.Table(
|
||||
'group_project_metadata',
|
||||
meta,
|
||||
sql.Column(
|
||||
'group_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('group.id'),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'project_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('tenant.id'),
|
||||
primary_key=True),
|
||||
sql.Column('data', sql.Text()))
|
||||
group_project_metadata_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
group_domain_metadata_table = sql.Table(
|
||||
'group_domain_metadata',
|
||||
meta,
|
||||
sql.Column(
|
||||
'group_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('group.id'),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'domain_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('domain.id'),
|
||||
primary_key=True),
|
||||
sql.Column('data', sql.Text()))
|
||||
group_domain_metadata_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
tables = ['user_group_membership', 'group_project_metadata',
|
||||
'group_domain_metadata', 'group']
|
||||
for t in tables:
|
||||
table = sql.Table(t, meta, autoload=True)
|
||||
table.drop(migrate_engine, checkfirst=True)
|
||||
@@ -1,194 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from keystone.common.sql import migration_helpers
|
||||
|
||||
|
||||
def rename_with_constraints(meta, legacy_project_table_name,
|
||||
new_project_table_name,
|
||||
legacy_user_project_membership_table_name,
|
||||
new_user_project_membership_table_name):
|
||||
# Not all RDBMSs support renaming a table that has foreign key constraints
|
||||
# on it, so drop FK constraints before renaming and then replace FKs
|
||||
# afterwards.
|
||||
|
||||
credential_table = sql.Table('credential', meta, autoload=True)
|
||||
group_project_meta_table = sql.Table('group_project_metadata', meta,
|
||||
autoload=True)
|
||||
project_table = sql.Table(legacy_project_table_name, meta, autoload=True)
|
||||
user_project_membership_table = sql.Table(
|
||||
legacy_user_project_membership_table_name, meta, autoload=True)
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
|
||||
constraints = [{'table': credential_table,
|
||||
'fk_column': 'project_id',
|
||||
'ref_column': project_table.c.id},
|
||||
{'table': group_project_meta_table,
|
||||
'fk_column': 'project_id',
|
||||
'ref_column': project_table.c.id},
|
||||
{'table': user_project_membership_table,
|
||||
'fk_column': 'tenant_id',
|
||||
'ref_column': project_table.c.id},
|
||||
{'table': user_project_membership_table,
|
||||
'fk_column': 'user_id',
|
||||
'ref_column': user_table.c.id}]
|
||||
|
||||
renames = {
|
||||
new_project_table_name: project_table,
|
||||
new_user_project_membership_table_name: user_project_membership_table}
|
||||
|
||||
migration_helpers.rename_tables_with_constraints(renames, constraints,
|
||||
meta.bind)
|
||||
|
||||
|
||||
def upgrade_with_rename(meta, migrate_engine):
|
||||
legacy_project_table_name = 'tenant'
|
||||
new_project_table_name = 'project'
|
||||
legacy_user_project_membership_table_name = 'user_tenant_membership'
|
||||
new_user_project_membership_table_name = 'user_project_membership'
|
||||
rename_with_constraints(meta, legacy_project_table_name,
|
||||
new_project_table_name,
|
||||
legacy_user_project_membership_table_name,
|
||||
new_user_project_membership_table_name)
|
||||
|
||||
|
||||
def downgrade_with_rename(meta, migrate_engine):
|
||||
legacy_project_table_name = 'project'
|
||||
new_project_table_name = 'tenant'
|
||||
legacy_user_project_membership_table_name = 'user_project_membership'
|
||||
new_user_project_membership_table_name = 'user_tenant_membership'
|
||||
rename_with_constraints(meta, legacy_project_table_name,
|
||||
new_project_table_name,
|
||||
legacy_user_project_membership_table_name,
|
||||
new_user_project_membership_table_name)
|
||||
|
||||
|
||||
def upgrade_with_copy(meta, migrate_engine):
|
||||
sql.Table('user', meta, autoload=True)
|
||||
project_table = sql.Table(
|
||||
'project',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.Column('description', sql.Text(), nullable=True),
|
||||
sql.Column('enabled', sql.types.Boolean, default=True))
|
||||
project_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
user_project_membership_table = sql.Table(
|
||||
'user_project_membership',
|
||||
meta,
|
||||
sql.Column(
|
||||
'user_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('user.id'),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'tenant_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('project.id'),
|
||||
primary_key=True))
|
||||
user_project_membership_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
|
||||
tenant_table = sql.Table('tenant', meta, autoload=True)
|
||||
insert = project_table.insert()
|
||||
for tenant in session.query(tenant_table):
|
||||
insert.execute({'id': tenant.id,
|
||||
'name': tenant.name,
|
||||
'extra': tenant.extra,
|
||||
'description': tenant.description,
|
||||
'enabled': tenant.enabled})
|
||||
|
||||
user_tenant_membership_table = sql.Table('user_tenant_membership',
|
||||
meta,
|
||||
autoload=True)
|
||||
insert = user_project_membership_table.insert()
|
||||
for user_id, tenant_id in session.query(user_tenant_membership_table):
|
||||
insert.execute({'user_id': user_id, 'tenant_id': tenant_id})
|
||||
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
user_tenant_membership_table.drop()
|
||||
tenant_table.drop()
|
||||
|
||||
|
||||
def downgrade_with_copy(meta, migrate_engine):
|
||||
sql.Table('user', meta, autoload=True)
|
||||
tenant_table = sql.Table(
|
||||
'tenant',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.Column('description', sql.Text(), nullable=True),
|
||||
sql.Column('enabled', sql.types.Boolean))
|
||||
tenant_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
user_tenant_membership_table = sql.Table(
|
||||
'user_tenant_membership',
|
||||
meta,
|
||||
sql.Column(
|
||||
'user_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('user.id'),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'tenant_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('tenant.id'),
|
||||
primary_key=True))
|
||||
user_tenant_membership_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
|
||||
project_table = sql.Table('project', meta, autoload=True)
|
||||
insert = tenant_table.insert()
|
||||
for project in session.query(project_table):
|
||||
insert.values(project).execute()
|
||||
project_table.drop()
|
||||
|
||||
user_project_membership_table = sql.Table('user_project_membership',
|
||||
meta,
|
||||
autoload=True)
|
||||
insert = user_tenant_membership_table.insert()
|
||||
for membership in session.query(user_project_membership_table):
|
||||
insert.execute(membership)
|
||||
user_project_membership_table.drop()
|
||||
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
if migrate_engine.name == "sqlite":
|
||||
upgrade_with_copy(meta, migrate_engine)
|
||||
else:
|
||||
upgrade_with_rename(meta, migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
if migrate_engine.name == "sqlite":
|
||||
downgrade_with_copy(meta, migrate_engine)
|
||||
else:
|
||||
downgrade_with_rename(meta, migrate_engine)
|
||||
@@ -1,435 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
# Copyright 2013 IBM Corp.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Normalize for domain_id, i.e. ensure User and Project entities have the
|
||||
domain_id as a first class attribute.
|
||||
|
||||
Both User and Project (as well as Group) entities are owned by a
|
||||
domain, which is implemented as each having a domain_id foreign key
|
||||
in their sql representation that points back to the respective
|
||||
domain in the domain table. This domain_id attribute should also
|
||||
be required (i.e. not nullable)
|
||||
|
||||
Adding a non_nullable foreign key attribute to a table with existing
|
||||
data causes a few problems since not all DB engines support the
|
||||
ability to either control the triggering of integrity constraints
|
||||
or the ability to modify columns after they are created.
|
||||
|
||||
To get round the above inconsistencies, two versions of the
|
||||
upgrade/downgrade functions are supplied, one for those engines
|
||||
that support dropping columns, and one for those that don't. For
|
||||
the latter we are forced to do table copy AND control the triggering
|
||||
of integrity constraints.
|
||||
"""
|
||||
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from keystone import config
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def _disable_foreign_constraints(session, migrate_engine):
|
||||
if migrate_engine.name == 'mysql':
|
||||
session.execute('SET foreign_key_checks = 0;')
|
||||
|
||||
|
||||
def _enable_foreign_constraints(session, migrate_engine):
|
||||
if migrate_engine.name == 'mysql':
|
||||
session.execute('SET foreign_key_checks = 1;')
|
||||
|
||||
|
||||
def upgrade_user_table_with_copy(meta, migrate_engine, session):
|
||||
# We want to add the domain_id attribute to the user table. Since
|
||||
# it is non nullable and the table may have data, easiest way is
|
||||
# a table copy. Further, in order to keep foreign key constraints
|
||||
# pointing at the right table, we need to be able and do a table
|
||||
# DROP then CREATE, rather than ALTERing the name of the table.
|
||||
|
||||
# First make a copy of the user table
|
||||
temp_user_table = sql.Table(
|
||||
'temp_user',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.Column('password', sql.String(128)),
|
||||
sql.Column('enabled', sql.Boolean, default=True))
|
||||
temp_user_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
for user in session.query(user_table):
|
||||
session.execute('insert into temp_user (id, name, extra, '
|
||||
'password, enabled) '
|
||||
'values ( :id, :name, :extra, '
|
||||
':password, :enabled);',
|
||||
{'id': user.id,
|
||||
'name': user.name,
|
||||
'extra': user.extra,
|
||||
'password': user.password,
|
||||
'enabled': user.enabled})
|
||||
|
||||
# Now switch off constraints while we drop and then re-create the
|
||||
# user table, with the additional domain_id column
|
||||
_disable_foreign_constraints(session, migrate_engine)
|
||||
session.execute('drop table user;')
|
||||
# Need to create a new metadata stream since we are going to load a
|
||||
# different version of the user table
|
||||
meta2 = sql.MetaData()
|
||||
meta2.bind = migrate_engine
|
||||
sql.Table('domain', meta2, autoload=True)
|
||||
user_table = sql.Table(
|
||||
'user',
|
||||
meta2,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.Column("password", sql.String(128)),
|
||||
sql.Column("enabled", sql.Boolean, default=True),
|
||||
sql.Column('domain_id', sql.String(64), sql.ForeignKey('domain.id'),
|
||||
nullable=False),
|
||||
sql.UniqueConstraint('domain_id', 'name'))
|
||||
user_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
# Finally copy in the data from our temp table and then clean
|
||||
# up by deleting our temp table
|
||||
for user in session.query(temp_user_table):
|
||||
session.execute('insert into user (id, name, extra, '
|
||||
'password, enabled, domain_id) '
|
||||
'values ( :id, :name, :extra, '
|
||||
':password, :enabled, :domain_id);',
|
||||
{'id': user.id,
|
||||
'name': user.name,
|
||||
'extra': user.extra,
|
||||
'password': user.password,
|
||||
'enabled': user.enabled,
|
||||
'domain_id': CONF.identity.default_domain_id})
|
||||
_enable_foreign_constraints(session, migrate_engine)
|
||||
session.execute('drop table temp_user;')
|
||||
|
||||
|
||||
def upgrade_project_table_with_copy(meta, migrate_engine, session):
|
||||
# We want to add the domain_id attribute to the project table. Since
|
||||
# it is non nullable and the table may have data, easiest way is
|
||||
# a table copy. Further, in order to keep foreign key constraints
|
||||
# pointing at the right table, we need to be able and do a table
|
||||
# DROP then CREATE, rather than ALTERing the name of the table.
|
||||
|
||||
# Fist make a copy of the project table
|
||||
temp_project_table = sql.Table(
|
||||
'temp_project',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.Column('description', sql.Text()),
|
||||
sql.Column('enabled', sql.Boolean, default=True))
|
||||
temp_project_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
project_table = sql.Table('project', meta, autoload=True)
|
||||
for project in session.query(project_table):
|
||||
session.execute('insert into temp_project (id, name, extra, '
|
||||
'description, enabled) '
|
||||
'values ( :id, :name, :extra, '
|
||||
':description, :enabled);',
|
||||
{'id': project.id,
|
||||
'name': project.name,
|
||||
'extra': project.extra,
|
||||
'description': project.description,
|
||||
'enabled': project.enabled})
|
||||
|
||||
# Now switch off constraints while we drop and then re-create the
|
||||
# project table, with the additional domain_id column
|
||||
_disable_foreign_constraints(session, migrate_engine)
|
||||
session.execute('drop table project;')
|
||||
# Need to create a new metadata stream since we are going to load a
|
||||
# different version of the project table
|
||||
meta2 = sql.MetaData()
|
||||
meta2.bind = migrate_engine
|
||||
sql.Table('domain', meta2, autoload=True)
|
||||
project_table = sql.Table(
|
||||
'project',
|
||||
meta2,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.Column('description', sql.Text()),
|
||||
sql.Column('enabled', sql.Boolean, default=True),
|
||||
sql.Column('domain_id', sql.String(64), sql.ForeignKey('domain.id'),
|
||||
nullable=False),
|
||||
sql.UniqueConstraint('domain_id', 'name'))
|
||||
project_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
# Finally copy in the data from our temp table and then clean
|
||||
# up by deleting our temp table
|
||||
for project in session.query(temp_project_table):
|
||||
session.execute('insert into project (id, name, extra, '
|
||||
'description, enabled, domain_id) '
|
||||
'values ( :id, :name, :extra, '
|
||||
':description, :enabled, :domain_id);',
|
||||
{'id': project.id,
|
||||
'name': project.name,
|
||||
'extra': project.extra,
|
||||
'description': project.description,
|
||||
'enabled': project.enabled,
|
||||
'domain_id': CONF.identity.default_domain_id})
|
||||
_enable_foreign_constraints(session, migrate_engine)
|
||||
session.execute('drop table temp_project;')
|
||||
|
||||
|
||||
def downgrade_user_table_with_copy(meta, migrate_engine, session):
|
||||
# For engines that don't support dropping columns, we need to do this
|
||||
# as a table copy. Further, in order to keep foreign key constraints
|
||||
# pointing at the right table, we need to be able and do a table
|
||||
# DROP then CREATE, rather than ALTERing the name of the table.
|
||||
|
||||
# Fist make a copy of the user table
|
||||
temp_user_table = sql.Table(
|
||||
'temp_user',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('password', sql.String(128)),
|
||||
sql.Column('enabled', sql.Boolean, default=True),
|
||||
sql.Column('extra', sql.Text()))
|
||||
temp_user_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
for user in session.query(user_table):
|
||||
session.execute('insert into temp_user (id, name, '
|
||||
'password, enabled, extra) '
|
||||
'values ( :id, :name, '
|
||||
':password, :enabled, :extra);',
|
||||
{'id': user.id,
|
||||
'name': user.name,
|
||||
'password': user.password,
|
||||
'enabled': user.enabled,
|
||||
'extra': user.extra})
|
||||
|
||||
# Now switch off constraints while we drop and then re-create the
|
||||
# user table, less the columns we wanted to drop
|
||||
_disable_foreign_constraints(session, migrate_engine)
|
||||
session.execute('drop table user;')
|
||||
# Need to create a new metadata stream since we are going to load a
|
||||
# different version of the user table
|
||||
meta2 = sql.MetaData()
|
||||
meta2.bind = migrate_engine
|
||||
user_table = sql.Table(
|
||||
'user',
|
||||
meta2,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.Column('password', sql.String(128)),
|
||||
sql.Column('enabled', sql.Boolean, default=True))
|
||||
user_table.create(migrate_engine, checkfirst=True)
|
||||
_enable_foreign_constraints(session, migrate_engine)
|
||||
|
||||
# Finally copy in the data from our temp table and then clean
|
||||
# up by deleting our temp table
|
||||
for user in session.query(temp_user_table):
|
||||
session.execute('insert into user (id, name, extra, '
|
||||
'password, enabled) '
|
||||
'values ( :id, :name, :extra, '
|
||||
':password, :enabled);',
|
||||
{'id': user.id,
|
||||
'name': user.name,
|
||||
'extra': user.extra,
|
||||
'password': user.password,
|
||||
'enabled': user.enabled})
|
||||
session.execute('drop table temp_user;')
|
||||
|
||||
|
||||
def downgrade_project_table_with_copy(meta, migrate_engine, session):
|
||||
# For engines that don't support dropping columns, we need to do this
|
||||
# as a table copy. Further, in order to keep foreign key constraints
|
||||
# pointing at the right table, we need to be able and do a table
|
||||
# DROP then CREATE, rather than ALTERing the name of the table.
|
||||
|
||||
# Fist make a copy of the project table
|
||||
temp_project_table = sql.Table(
|
||||
'temp_project',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('description', sql.Text()),
|
||||
sql.Column('enabled', sql.Boolean, default=True),
|
||||
sql.Column('extra', sql.Text()))
|
||||
temp_project_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
project_table = sql.Table('project', meta, autoload=True)
|
||||
for project in session.query(project_table):
|
||||
session.execute('insert into temp_project (id, name, '
|
||||
'description, enabled, extra) '
|
||||
'values ( :id, :name, '
|
||||
':description, :enabled, :extra);',
|
||||
{'id': project.id,
|
||||
'name': project.name,
|
||||
'description': project.description,
|
||||
'enabled': project.enabled,
|
||||
'extra': project.extra})
|
||||
|
||||
# Now switch off constraints while we drop and then re-create the
|
||||
# project table, less the columns we wanted to drop
|
||||
_disable_foreign_constraints(session, migrate_engine)
|
||||
session.execute('drop table project;')
|
||||
# Need to create a new metadata stream since we are going to load a
|
||||
# different version of the project table
|
||||
meta2 = sql.MetaData()
|
||||
meta2.bind = migrate_engine
|
||||
project_table = sql.Table(
|
||||
'project',
|
||||
meta2,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('name', sql.String(64), unique=True, nullable=False),
|
||||
sql.Column('extra', sql.Text()),
|
||||
sql.Column('description', sql.Text()),
|
||||
sql.Column('enabled', sql.Boolean, default=True))
|
||||
project_table.create(migrate_engine, checkfirst=True)
|
||||
_enable_foreign_constraints(session, migrate_engine)
|
||||
|
||||
# Finally copy in the data from our temp table and then clean
|
||||
# up by deleting our temp table
|
||||
for project in session.query(temp_project_table):
|
||||
session.execute('insert into project (id, name, extra, '
|
||||
'description, enabled) '
|
||||
'values ( :id, :name, :extra, '
|
||||
':description, :enabled);',
|
||||
{'id': project.id,
|
||||
'name': project.name,
|
||||
'extra': project.extra,
|
||||
'description': project.description,
|
||||
'enabled': project.enabled})
|
||||
session.execute("drop table temp_project;")
|
||||
|
||||
|
||||
def upgrade_user_table_with_col_create(meta, migrate_engine, session):
|
||||
# Create the domain_id column. We want this to be not nullable
|
||||
# but also a foreign key. We can't create this right off the
|
||||
# bat since any existing rows would cause an Integrity Error.
|
||||
# We therefore create it nullable, fill the column with the
|
||||
# default data and then set it to non nullable.
|
||||
sql.Table('domain', meta, autoload=True)
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
user_table.create_column(
|
||||
sql.Column('domain_id', sql.String(64),
|
||||
sql.ForeignKey('domain.id'), nullable=True))
|
||||
for user in session.query(user_table).all():
|
||||
values = {'domain_id': CONF.identity.default_domain_id}
|
||||
update = user_table.update().\
|
||||
where(user_table.c.id == user.id).\
|
||||
values(values)
|
||||
migrate_engine.execute(update)
|
||||
# Need to commit this or setting nullable to False will fail
|
||||
session.commit()
|
||||
user_table.columns.domain_id.alter(nullable=False)
|
||||
|
||||
# Finally, change the uniqueness settings for the name attribute
|
||||
session.execute('ALTER TABLE "user" DROP CONSTRAINT user_name_key;')
|
||||
session.execute('ALTER TABLE "user" ADD CONSTRAINT user_dom_name_unique '
|
||||
'UNIQUE (domain_id, name);')
|
||||
|
||||
session.commit()
|
||||
|
||||
|
||||
def upgrade_project_table_with_col_create(meta, migrate_engine, session):
|
||||
# Create the domain_id column. We want this to be not nullable
|
||||
# but also a foreign key. We can't create this right off the
|
||||
# bat since any existing rows would cause an Integrity Error.
|
||||
# We therefore create it nullable, fill the column with the
|
||||
# default data and then set it to non nullable.
|
||||
sql.Table('domain', meta, autoload=True)
|
||||
project_table = sql.Table('project', meta, autoload=True)
|
||||
project_table.create_column(
|
||||
sql.Column('domain_id', sql.String(64),
|
||||
sql.ForeignKey('domain.id'), nullable=True))
|
||||
for project in session.query(project_table).all():
|
||||
values = {'domain_id': CONF.identity.default_domain_id}
|
||||
update = project_table.update().\
|
||||
where(project_table.c.id == project.id).\
|
||||
values(values)
|
||||
migrate_engine.execute(update)
|
||||
# Need to commit this or setting nullable to False will fail
|
||||
session.commit()
|
||||
project_table.columns.domain_id.alter(nullable=False)
|
||||
|
||||
# Finally, change the uniqueness settings for the name attribute
|
||||
session.execute('ALTER TABLE project DROP CONSTRAINT tenant_name_key;')
|
||||
session.execute('ALTER TABLE project ADD CONSTRAINT proj_dom_name_unique '
|
||||
'UNIQUE (domain_id, name);')
|
||||
|
||||
|
||||
def downgrade_user_table_with_col_drop(meta, migrate_engine, session):
|
||||
# Revert uniqueness settings for the name attribute
|
||||
session.execute('ALTER TABLE "user" DROP CONSTRAINT '
|
||||
'user_dom_name_unique;')
|
||||
# specify the constraint name so it can be referenced later
|
||||
session.execute('ALTER TABLE "user" ADD CONSTRAINT user_name_key '
|
||||
'UNIQUE (name);')
|
||||
session.commit()
|
||||
# And now go ahead an drop the domain_id column
|
||||
sql.Table('domain', meta, autoload=True)
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
column = sql.Column('domain_id', sql.String(64),
|
||||
sql.ForeignKey('domain.id'), nullable=False)
|
||||
column.drop(user_table)
|
||||
|
||||
|
||||
def downgrade_project_table_with_col_drop(meta, migrate_engine, session):
|
||||
# Revert uniqueness settings for the name attribute
|
||||
session.execute('ALTER TABLE project DROP CONSTRAINT '
|
||||
'proj_dom_name_unique;')
|
||||
session.execute('ALTER TABLE project ADD CONSTRAINT tenant_name_key '
|
||||
'UNIQUE (name);')
|
||||
session.commit()
|
||||
# And now go ahead an drop the domain_id column
|
||||
sql.Table('domain', meta, autoload=True)
|
||||
project_table = sql.Table('project', meta, autoload=True)
|
||||
column = sql.Column('domain_id', sql.String(64),
|
||||
sql.ForeignKey('domain.id'), nullable=False)
|
||||
column.drop(project_table)
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
if migrate_engine.name in ['sqlite', 'mysql']:
|
||||
upgrade_user_table_with_copy(meta, migrate_engine, session)
|
||||
upgrade_project_table_with_copy(meta, migrate_engine, session)
|
||||
else:
|
||||
upgrade_user_table_with_col_create(meta, migrate_engine, session)
|
||||
upgrade_project_table_with_col_create(meta, migrate_engine, session)
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
if migrate_engine.name in ['sqlite', 'mysql']:
|
||||
downgrade_user_table_with_copy(meta, migrate_engine, session)
|
||||
downgrade_project_table_with_copy(meta, migrate_engine, session)
|
||||
else:
|
||||
# MySQL should in theory be able to use this path, but seems to
|
||||
# have problems dropping columns which are foreign keys
|
||||
downgrade_user_table_with_col_drop(meta, migrate_engine, session)
|
||||
downgrade_project_table_with_col_drop(meta, migrate_engine, session)
|
||||
session.commit()
|
||||
session.close()
|
||||
@@ -1,113 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import json
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
from keystone import config
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
sql.Table('user', meta, autoload=True)
|
||||
sql.Table('project', meta, autoload=True)
|
||||
role_table = sql.Table('role', meta, autoload=True)
|
||||
|
||||
user_project_role_table = sql.Table(
|
||||
'user_project_metadata',
|
||||
meta,
|
||||
sql.Column('user_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('user.id'),
|
||||
primary_key=True),
|
||||
sql.Column('project_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('project.id'),
|
||||
primary_key=True),
|
||||
sql.Column('data', sql.Text()))
|
||||
user_project_role_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
conn = migrate_engine.connect()
|
||||
conn.execute(role_table.insert(),
|
||||
id=CONF.member_role_id,
|
||||
name=CONF.member_role_name,
|
||||
extra=json.dumps({'description':
|
||||
'Default role for project membership',
|
||||
'enabled': 'True'}))
|
||||
|
||||
user_project_membership_table = sql.Table('user_project_membership',
|
||||
meta, autoload=True)
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
for membership in session.query(user_project_membership_table):
|
||||
data = {'roles': [config.CONF.member_role_id]}
|
||||
ins = user_project_role_table.insert().values(
|
||||
user_id=membership.user_id,
|
||||
project_id=membership.tenant_id,
|
||||
data=json.dumps(data))
|
||||
conn.execute(ins)
|
||||
session.close()
|
||||
user_project_membership_table.drop()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
sql.Table('user', meta, autoload=True)
|
||||
sql.Table('project', meta, autoload=True)
|
||||
|
||||
user_project_membership_table = sql.Table(
|
||||
'user_project_membership',
|
||||
meta,
|
||||
sql.Column(
|
||||
'user_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('user.id'),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'tenant_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('project.id'),
|
||||
primary_key=True))
|
||||
user_project_membership_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
user_project_metadata_table = sql.Table(
|
||||
'user_project_metadata',
|
||||
meta,
|
||||
autoload=True)
|
||||
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
for membership in session.query(user_project_metadata_table):
|
||||
if 'roles' in membership:
|
||||
roles = membership['roles']
|
||||
if config.CONF.member_role_id in roles:
|
||||
user_project_membership_table.insert().values(
|
||||
user_id=membership.user_id,
|
||||
tenant_id=membership.project_id)
|
||||
session.close()
|
||||
role_table = sql.Table('role', meta, autoload=True)
|
||||
conn = migrate_engine.connect()
|
||||
user_project_membership_table = sql.Table(
|
||||
'user_project_membership', meta, autoload=True)
|
||||
|
||||
role_table = sql.Table('role', meta, autoload=True)
|
||||
conn.execute(role_table.delete().where(role_table.c.id ==
|
||||
config.CONF.member_role_id))
|
||||
user_project_metadata_table.drop()
|
||||
@@ -1,65 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
# Upgrade operations go here. Don't create your own engine; bind
|
||||
# migrate_engine to your metadata
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
sql.Table('user', meta, autoload=True)
|
||||
sql.Table('role', meta, autoload=True)
|
||||
sql.Table('project', meta, autoload=True)
|
||||
|
||||
trust_table = sql.Table(
|
||||
'trust',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True),
|
||||
sql.Column('trustor_user_id',
|
||||
sql.String(64),
|
||||
unique=False,
|
||||
nullable=False,),
|
||||
sql.Column('trustee_user_id',
|
||||
sql.String(64),
|
||||
unique=False,
|
||||
nullable=False),
|
||||
sql.Column('project_id', sql.String(64),
|
||||
unique=False,
|
||||
nullable=True),
|
||||
sql.Column("impersonation", sql.types.Boolean, nullable=False),
|
||||
sql.Column("deleted_at", sql.types.DateTime, nullable=True),
|
||||
sql.Column("expires_at", sql.types.DateTime, nullable=True),
|
||||
sql.Column('extra', sql.Text()))
|
||||
trust_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
trust_role_table = sql.Table(
|
||||
'trust_role',
|
||||
meta,
|
||||
sql.Column('trust_id', sql.String(64), primary_key=True,
|
||||
nullable=False),
|
||||
sql.Column('role_id', sql.String(64), primary_key=True,
|
||||
nullable=False))
|
||||
trust_role_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
# Operations to reverse the above upgrade go here.
|
||||
for table_name in ['trust_role', 'trust']:
|
||||
table = sql.Table(table_name, meta, autoload=True)
|
||||
table.drop()
|
||||
@@ -1,46 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
from keystone import config
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
role_table = sql.Table('role', meta, autoload=True)
|
||||
# name should be 255 characters to match fresh database
|
||||
role_table.c.name.alter(type=sql.String(length=255))
|
||||
|
||||
# blank 'extra' field should be "{}"
|
||||
none = None
|
||||
update = role_table.update().where(role_table.c.extra == none).values(
|
||||
{role_table.c.extra: "{}"})
|
||||
migrate_engine.execute(update)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
# this fixes bugs in migration 001 and 007 that result in discrepancies
|
||||
# between fresh databases and databases updated from 004 (folsom).
|
||||
# the changes fixing 007 will be rolled back in 007's rollback if
|
||||
# the user desires to return to a state before the existence of the extra
|
||||
# column.
|
||||
# the name length change reflects the current default and should not be
|
||||
# rolled back.
|
||||
pass
|
||||
@@ -1,109 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import json
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
from keystone import config
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
sql.Table('user', meta, autoload=True)
|
||||
sql.Table('role', meta, autoload=True)
|
||||
sql.Table('project', meta, autoload=True)
|
||||
new_metadata_table = sql.Table('user_project_metadata',
|
||||
meta,
|
||||
autoload=True)
|
||||
|
||||
old_metadata_table = sql.Table('metadata', meta, autoload=True)
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
|
||||
for metadata in session.query(old_metadata_table):
|
||||
data = json.loads(metadata.data)
|
||||
if config.CONF.member_role_id not in metadata.data:
|
||||
data['roles'].append(config.CONF.member_role_id)
|
||||
|
||||
r = session.query(new_metadata_table).filter_by(
|
||||
user_id=metadata.user_id,
|
||||
project_id=metadata.tenant_id).first()
|
||||
|
||||
if r is not None:
|
||||
# roles should be the union of the two role lists
|
||||
old_roles = data['roles']
|
||||
new_roles = json.loads(r.data)['roles']
|
||||
data['roles'] = list(set(old_roles) | set(new_roles))
|
||||
q = new_metadata_table.update().where(
|
||||
new_metadata_table.c.user_id == metadata.user_id).where(
|
||||
new_metadata_table.c.project_id ==
|
||||
metadata.tenant_id).values(data=json.dumps(data))
|
||||
else:
|
||||
q = new_metadata_table.insert().values(
|
||||
user_id=metadata.user_id,
|
||||
project_id=metadata.tenant_id,
|
||||
data=json.dumps(data))
|
||||
|
||||
session.execute(q)
|
||||
|
||||
session.commit()
|
||||
old_metadata_table.drop()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
sql.Table('user', meta, autoload=True)
|
||||
sql.Table('project', meta, autoload=True)
|
||||
|
||||
metadata_table = sql.Table(
|
||||
'metadata',
|
||||
meta,
|
||||
sql.Column(
|
||||
u'user_id',
|
||||
sql.String(64),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
u'tenant_id',
|
||||
sql.String(64),
|
||||
primary_key=True),
|
||||
sql.Column('data',
|
||||
sql.Text()))
|
||||
metadata_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
user_project_metadata_table = sql.Table(
|
||||
'user_project_metadata',
|
||||
meta,
|
||||
autoload=True)
|
||||
|
||||
metadata_table = sql.Table(
|
||||
'metadata',
|
||||
meta,
|
||||
autoload=True)
|
||||
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
|
||||
for metadata in session.query(user_project_metadata_table):
|
||||
if 'roles' in metadata:
|
||||
metadata_table.insert().values(
|
||||
user_id=metadata.user_id,
|
||||
tenant_id=metadata.project_id)
|
||||
|
||||
session.close()
|
||||
@@ -1,76 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy
|
||||
from sqlalchemy import exc
|
||||
|
||||
|
||||
def downgrade_token_table_with_column_drop(meta, migrate_engine):
|
||||
token_table = sqlalchemy.Table('token', meta, autoload=True)
|
||||
# delete old tokens, as the format has changed.
|
||||
# We don't guarantee that existing tokens will be
|
||||
# usable after a migration
|
||||
token_table.delete()
|
||||
token_table.drop_column(
|
||||
sqlalchemy.Column('trust_id',
|
||||
sqlalchemy.String(64),
|
||||
nullable=True))
|
||||
token_table.drop_column(
|
||||
sqlalchemy.Column('user_id',
|
||||
sqlalchemy.String(64)))
|
||||
|
||||
|
||||
def create_column_forgiving(migrate_engine, table, column):
|
||||
try:
|
||||
table.create_column(column)
|
||||
except exc.OperationalError as e:
|
||||
if (e.args[0].endswith('duplicate column name: %s' % column.name)
|
||||
and migrate_engine.name == "sqlite"):
|
||||
# sqlite does not drop columns, so if we have already
|
||||
# done a downgrade and are now upgrading, we will hit
|
||||
# this: the SQLite driver previously reported success
|
||||
# dropping the columns but it hasn't.
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
def upgrade_token_table(meta, migrate_engine):
|
||||
# delete old tokens, as the format has changed.
|
||||
# The existing tokens will not
|
||||
# support some of the list functions
|
||||
|
||||
token_table = sqlalchemy.Table('token', meta, autoload=True)
|
||||
token_table.delete()
|
||||
|
||||
create_column_forgiving(
|
||||
migrate_engine, token_table,
|
||||
sqlalchemy.Column('trust_id',
|
||||
sqlalchemy.String(64),
|
||||
nullable=True))
|
||||
create_column_forgiving(
|
||||
migrate_engine, token_table,
|
||||
sqlalchemy.Column('user_id', sqlalchemy.String(64)))
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sqlalchemy.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
upgrade_token_table(meta, migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sqlalchemy.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
downgrade_token_table_with_column_drop(meta, migrate_engine)
|
||||
@@ -1,68 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import json
|
||||
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy import orm
|
||||
|
||||
from keystone import config
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
endpoint_table = sql.Table('endpoint', meta, autoload=True)
|
||||
|
||||
session = orm.sessionmaker(bind=migrate_engine)()
|
||||
for endpoint in session.query(endpoint_table).all():
|
||||
try:
|
||||
extra = json.loads(endpoint.extra)
|
||||
legacy_endpoint_id = extra.pop('legacy_endpoint_id')
|
||||
except KeyError:
|
||||
# if there is no legacy_endpoint_id, there's nothing to do
|
||||
pass
|
||||
else:
|
||||
q = endpoint_table.update()
|
||||
q = q.where(endpoint_table.c.id == endpoint.id)
|
||||
q = q.values({
|
||||
endpoint_table.c.extra: json.dumps(extra),
|
||||
endpoint_table.c.legacy_endpoint_id: legacy_endpoint_id})
|
||||
migrate_engine.execute(q)
|
||||
session.close()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
endpoint_table = sql.Table('endpoint', meta, autoload=True)
|
||||
|
||||
session = orm.sessionmaker(bind=migrate_engine)()
|
||||
for endpoint in session.query(endpoint_table).all():
|
||||
if endpoint.legacy_endpoint_id is not None:
|
||||
extra = json.loads(endpoint.extra)
|
||||
extra['legacy_endpoint_id'] = endpoint.legacy_endpoint_id
|
||||
|
||||
q = endpoint_table.update()
|
||||
q = q.where(endpoint_table.c.id == endpoint.id)
|
||||
q = q.values({
|
||||
endpoint_table.c.extra: json.dumps(extra),
|
||||
endpoint_table.c.legacy_endpoint_id: None})
|
||||
migrate_engine.execute(q)
|
||||
session.close()
|
||||
@@ -1,47 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
from keystone.common.sql import migration_helpers
|
||||
|
||||
|
||||
def list_constraints(migrate_engine):
|
||||
meta = sqlalchemy.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
user_table = sqlalchemy.Table('user', meta, autoload=True)
|
||||
proj_table = sqlalchemy.Table('project', meta, autoload=True)
|
||||
cred_table = sqlalchemy.Table('credential', meta, autoload=True)
|
||||
|
||||
constraints = [{'table': cred_table,
|
||||
'fk_column': 'user_id',
|
||||
'ref_column': user_table.c.id},
|
||||
{'table': cred_table,
|
||||
'fk_column': 'project_id',
|
||||
'ref_column': proj_table.c.id}]
|
||||
return constraints
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
# SQLite does not support constraints, and querying the constraints
|
||||
# raises an exception
|
||||
if migrate_engine.name == 'sqlite':
|
||||
return
|
||||
migration_helpers.remove_constraints(list_constraints(migrate_engine))
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
if migrate_engine.name == 'sqlite':
|
||||
return
|
||||
migration_helpers.add_constraints(list_constraints(migrate_engine))
|
||||
@@ -1,31 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
idx = sql.Index('ix_token_expires', token.c.expires)
|
||||
idx.create(migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
idx = sql.Index('ix_token_expires', token.c.expires)
|
||||
idx.drop(migrate_engine)
|
||||
@@ -1,31 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
idx = sql.Index('ix_token_valid', token.c.valid)
|
||||
idx.create(migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
idx = sql.Index('ix_token_valid', token.c.valid)
|
||||
idx.drop(migrate_engine)
|
||||
@@ -1,60 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
from keystone.common.sql import migration_helpers
|
||||
|
||||
|
||||
def list_constraints(migrate_engine):
|
||||
meta = sqlalchemy.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
user_table = sqlalchemy.Table('user', meta, autoload=True)
|
||||
sqlalchemy.Table('project', meta, autoload=True)
|
||||
group_table = sqlalchemy.Table('group', meta, autoload=True)
|
||||
user_domain_metadata_table = sqlalchemy.Table('user_domain_metadata',
|
||||
meta, autoload=True)
|
||||
group_domain_metadata_table = sqlalchemy.Table('group_domain_metadata',
|
||||
meta, autoload=True)
|
||||
user_project_metadata_table = sqlalchemy.Table('user_project_metadata',
|
||||
meta, autoload=True)
|
||||
group_project_metadata_table = sqlalchemy.Table('group_project_metadata',
|
||||
meta, autoload=True)
|
||||
|
||||
constraints = [{'table': user_domain_metadata_table,
|
||||
'fk_column': 'user_id',
|
||||
'ref_column': user_table.c.id},
|
||||
{'table': group_domain_metadata_table,
|
||||
'fk_column': 'group_id',
|
||||
'ref_column': group_table.c.id},
|
||||
{'table': user_project_metadata_table,
|
||||
'fk_column': 'user_id',
|
||||
'ref_column': user_table.c.id},
|
||||
{'table': group_project_metadata_table,
|
||||
'fk_column': 'group_id',
|
||||
'ref_column': group_table.c.id},
|
||||
]
|
||||
return constraints
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
if migrate_engine.name == 'sqlite':
|
||||
return
|
||||
migration_helpers.remove_constraints(list_constraints(migrate_engine))
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
if migrate_engine.name == 'sqlite':
|
||||
return
|
||||
migration_helpers.add_constraints(list_constraints(migrate_engine))
|
||||
@@ -1,156 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy import MetaData
|
||||
|
||||
from keystone.common.sql import migration_helpers
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
# Upgrade operations go here. Don't create your own engine;
|
||||
# bind migrate_engine to your metadata
|
||||
|
||||
if migrate_engine.name != 'mysql':
|
||||
# InnoDB / MyISAM only applies to MySQL.
|
||||
return
|
||||
|
||||
# This is a list of all the tables that might have been created with MyISAM
|
||||
# rather than InnoDB.
|
||||
tables = [
|
||||
'credential',
|
||||
'domain',
|
||||
'ec2_credential',
|
||||
'endpoint',
|
||||
'group',
|
||||
'group_domain_metadata',
|
||||
'group_project_metadata',
|
||||
'policy',
|
||||
'project',
|
||||
'role',
|
||||
'service',
|
||||
'token',
|
||||
'trust',
|
||||
'trust_role',
|
||||
'user',
|
||||
'user_domain_metadata',
|
||||
'user_group_membership',
|
||||
'user_project_metadata',
|
||||
]
|
||||
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
domain_table = sql.Table('domain', meta, autoload=True)
|
||||
endpoint_table = sql.Table('endpoint', meta, autoload=True)
|
||||
group_table = sql.Table('group', meta, autoload=True)
|
||||
group_domain_metadata_table = sql.Table('group_domain_metadata', meta,
|
||||
autoload=True)
|
||||
group_project_metadata_table = sql.Table('group_project_metadata', meta,
|
||||
autoload=True)
|
||||
project_table = sql.Table('project', meta, autoload=True)
|
||||
service_table = sql.Table('service', meta, autoload=True)
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
user_domain_metadata_table = sql.Table('user_domain_metadata', meta,
|
||||
autoload=True)
|
||||
user_group_membership_table = sql.Table('user_group_membership', meta,
|
||||
autoload=True)
|
||||
|
||||
# Mapping of table name to the constraints on that table,
|
||||
# so we can create them.
|
||||
table_constraints = {
|
||||
'endpoint': [{'table': endpoint_table,
|
||||
'fk_column': 'service_id',
|
||||
'ref_column': service_table.c.id},
|
||||
],
|
||||
'group': [{'table': group_table,
|
||||
'fk_column': 'domain_id',
|
||||
'ref_column': domain_table.c.id},
|
||||
],
|
||||
'group_domain_metadata': [{'table': group_domain_metadata_table,
|
||||
'fk_column': 'domain_id',
|
||||
'ref_column': domain_table.c.id},
|
||||
],
|
||||
'group_project_metadata': [{'table': group_project_metadata_table,
|
||||
'fk_column': 'project_id',
|
||||
'ref_column': project_table.c.id},
|
||||
],
|
||||
'project': [{'table': project_table,
|
||||
'fk_column': 'domain_id',
|
||||
'ref_column': domain_table.c.id},
|
||||
],
|
||||
'user': [{'table': user_table,
|
||||
'fk_column': 'domain_id',
|
||||
'ref_column': domain_table.c.id},
|
||||
],
|
||||
'user_domain_metadata': [{'table': user_domain_metadata_table,
|
||||
'fk_column': 'domain_id',
|
||||
'ref_column': domain_table.c.id},
|
||||
],
|
||||
'user_group_membership': [{'table': user_group_membership_table,
|
||||
'fk_column': 'user_id',
|
||||
'ref_column': user_table.c.id},
|
||||
{'table': user_group_membership_table,
|
||||
'fk_column': 'group_id',
|
||||
'ref_column': group_table.c.id},
|
||||
],
|
||||
'user_project_metadata': [{'table': group_project_metadata_table,
|
||||
'fk_column': 'project_id',
|
||||
'ref_column': project_table.c.id},
|
||||
],
|
||||
}
|
||||
|
||||
# Maps a table name to the tables that reference it as a FK constraint
|
||||
# (See the map above).
|
||||
ref_tables_map = {
|
||||
'service': ['endpoint', ],
|
||||
'domain': ['group', 'group_domain_metadata', 'project', 'user',
|
||||
'user_domain_metadata', ],
|
||||
'project': ['group_project_metadata', 'user_project_metadata', ],
|
||||
'user': ['user_group_membership', ],
|
||||
'group': ['user_group_membership', ],
|
||||
}
|
||||
|
||||
# The names of tables that need to have their FKs added.
|
||||
fk_table_names = set()
|
||||
|
||||
d = migrate_engine.execute("SHOW TABLE STATUS WHERE Engine!='InnoDB';")
|
||||
for row in d.fetchall():
|
||||
table_name = row[0]
|
||||
|
||||
if table_name not in tables:
|
||||
# Skip this table since it's not a Keystone table.
|
||||
continue
|
||||
|
||||
migrate_engine.execute("ALTER TABLE `%s` Engine=InnoDB" % table_name)
|
||||
|
||||
# Will add the FKs to the table if any of
|
||||
# a) the table itself was converted
|
||||
# b) the tables that the table referenced were converted
|
||||
|
||||
if table_name in table_constraints:
|
||||
fk_table_names.add(table_name)
|
||||
|
||||
ref_tables = ref_tables_map.get(table_name, [])
|
||||
for other_table_name in ref_tables:
|
||||
fk_table_names.add(other_table_name)
|
||||
|
||||
# Now add all the FK constraints to those tables
|
||||
for table_name in fk_table_names:
|
||||
constraints = table_constraints.get(table_name)
|
||||
migration_helpers.add_constraints(constraints)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
pass
|
||||
@@ -1,188 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
# The group_project_metadata table was not updated in terms of its
|
||||
# FK to the tenant table when the tenant->project change was made at
|
||||
# the 015 migration for sqlite. This upgrade fixes that.
|
||||
# We need to create a fake tenant table so that we can first load
|
||||
# the group_project_metadata at all, then do a dance of copying tables
|
||||
# to get us to the correct schema.
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
if migrate_engine.name != 'sqlite':
|
||||
return
|
||||
|
||||
temp_tenant_table = sql.Table(
|
||||
'tenant',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True))
|
||||
temp_tenant_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
sql.Table('user', meta, autoload=True)
|
||||
old_group_metadata_table = sql.Table('group_project_metadata',
|
||||
meta, autoload=True)
|
||||
|
||||
# OK, we now have the table loaded, create a first
|
||||
# temporary table of a different name with the correct FK
|
||||
sql.Table('project', meta, autoload=True)
|
||||
temp_group_project_metadata_table = sql.Table(
|
||||
'temp_group_project_metadata',
|
||||
meta,
|
||||
sql.Column(
|
||||
'group_id',
|
||||
sql.String(64),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'project_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('project.id'),
|
||||
primary_key=True),
|
||||
sql.Column('data', sql.Text()))
|
||||
temp_group_project_metadata_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
# Populate the new temporary table, and then drop the old one
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
|
||||
for metadata in session.query(old_group_metadata_table):
|
||||
q = temp_group_project_metadata_table.insert().values(
|
||||
group_id=metadata.group_id,
|
||||
project_id=metadata.project_id,
|
||||
data=metadata.data)
|
||||
session.execute(q)
|
||||
session.commit()
|
||||
old_group_metadata_table.drop()
|
||||
temp_tenant_table.drop()
|
||||
|
||||
# Now do a final table copy to get the table of the right name.
|
||||
# Re-init the metadata so that sqlalchemy does not get confused with
|
||||
# multiple versions of the same named table.
|
||||
meta2 = sql.MetaData()
|
||||
meta2.bind = migrate_engine
|
||||
|
||||
sql.Table('project', meta2, autoload=True)
|
||||
new_group_project_metadata_table = sql.Table(
|
||||
'group_project_metadata',
|
||||
meta2,
|
||||
sql.Column(
|
||||
'group_id',
|
||||
sql.String(64),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'project_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('project.id'),
|
||||
primary_key=True),
|
||||
sql.Column('data', sql.Text()))
|
||||
new_group_project_metadata_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
for metadata in session.query(temp_group_project_metadata_table):
|
||||
q = new_group_project_metadata_table.insert().values(
|
||||
group_id=metadata.group_id,
|
||||
project_id=metadata.project_id,
|
||||
data=metadata.data)
|
||||
session.execute(q)
|
||||
session.commit()
|
||||
|
||||
temp_group_project_metadata_table.drop()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
# Put the group_project_metadata table back the way it was in its rather
|
||||
# broken state. We don't try and re-write history, since otherwise people
|
||||
# get out of step.
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
if migrate_engine.name != 'sqlite':
|
||||
return
|
||||
|
||||
sql.Table('user', meta, autoload=True)
|
||||
sql.Table('project', meta, autoload=True)
|
||||
group_metadata_table = sql.Table('group_project_metadata',
|
||||
meta, autoload=True)
|
||||
|
||||
# We want to create a temp group meta table with the FK
|
||||
# set to the wrong place.
|
||||
temp_tenant_table = sql.Table(
|
||||
'tenant',
|
||||
meta,
|
||||
sql.Column('id', sql.String(64), primary_key=True))
|
||||
temp_tenant_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
temp_group_project_metadata_table = sql.Table(
|
||||
'temp_group_project_metadata',
|
||||
meta,
|
||||
sql.Column(
|
||||
'group_id',
|
||||
sql.String(64),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'project_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('tenant.id'),
|
||||
primary_key=True),
|
||||
sql.Column('data', sql.Text()))
|
||||
temp_group_project_metadata_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
# Now populate the temp table and drop the real one
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
|
||||
for metadata in session.query(group_metadata_table):
|
||||
q = temp_group_project_metadata_table.insert().values(
|
||||
group_id=metadata.group_id,
|
||||
project_id=metadata.project_id,
|
||||
data=metadata.data)
|
||||
session.execute(q)
|
||||
|
||||
session.commit()
|
||||
group_metadata_table.drop()
|
||||
|
||||
# Now copy again into the correctly named table. Re-init the metadata
|
||||
# so that sqlalchemy does not get confused with multiple versions of the
|
||||
# same named table.
|
||||
meta2 = sql.MetaData()
|
||||
meta2.bind = migrate_engine
|
||||
|
||||
sql.Table('tenant', meta2, autoload=True)
|
||||
new_group_project_metadata_table = sql.Table(
|
||||
'group_project_metadata',
|
||||
meta2,
|
||||
sql.Column(
|
||||
'group_id',
|
||||
sql.String(64),
|
||||
primary_key=True),
|
||||
sql.Column(
|
||||
'project_id',
|
||||
sql.String(64),
|
||||
sql.ForeignKey('tenant.id'),
|
||||
primary_key=True),
|
||||
sql.Column('data', sql.Text()))
|
||||
new_group_project_metadata_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
for metadata in session.query(temp_group_project_metadata_table):
|
||||
q = new_group_project_metadata_table.insert().values(
|
||||
group_id=metadata.group_id,
|
||||
project_id=metadata.project_id,
|
||||
data=metadata.data)
|
||||
session.execute(q)
|
||||
|
||||
session.commit()
|
||||
|
||||
temp_group_project_metadata_table.drop()
|
||||
temp_tenant_table.drop()
|
||||
@@ -1,100 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import json
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def build_update(table_name, upgrade_table, row, values):
|
||||
if table_name == 'user_project_metadata':
|
||||
update = upgrade_table.update().where(
|
||||
upgrade_table.c.user_id == row.user_id).where(
|
||||
upgrade_table.c.project_id == row.project_id).values(values)
|
||||
elif table_name == 'group_project_metadata':
|
||||
update = upgrade_table.update().where(
|
||||
upgrade_table.c.group_id == row.group_id).where(
|
||||
upgrade_table.c.project_id == row.project_id).values(values)
|
||||
elif table_name == 'user_domain_metadata':
|
||||
update = upgrade_table.update().where(
|
||||
upgrade_table.c.user_id == row.user_id).where(
|
||||
upgrade_table.c.domain_id == row.domain_id).values(values)
|
||||
else:
|
||||
update = upgrade_table.update().where(
|
||||
upgrade_table.c.group_id == row.group_id).where(
|
||||
upgrade_table.c.domain_id == row.domain_id).values(values)
|
||||
return update
|
||||
|
||||
|
||||
def upgrade_grant_table(meta, migrate_engine, session, table_name):
|
||||
|
||||
# Convert the roles component of the metadata from a list
|
||||
# of ids to a list of dicts
|
||||
|
||||
def list_to_dict_list(metadata):
|
||||
json_metadata = json.loads(metadata)
|
||||
if 'roles' in json_metadata:
|
||||
json_metadata['roles'] = (
|
||||
[{'id': x} for x in json_metadata['roles']])
|
||||
return json.dumps(json_metadata)
|
||||
|
||||
upgrade_table = sql.Table(table_name, meta, autoload=True)
|
||||
for assignment in session.query(upgrade_table):
|
||||
values = {'data': list_to_dict_list(assignment.data)}
|
||||
update = build_update(table_name, upgrade_table, assignment, values)
|
||||
migrate_engine.execute(update)
|
||||
|
||||
|
||||
def downgrade_grant_table(meta, migrate_engine, session, table_name):
|
||||
|
||||
# Convert the roles component of the metadata from a list
|
||||
# of dicts to a simple list of ids. Any inherited roles are deleted
|
||||
# since they would have no meaning
|
||||
|
||||
def dict_list_to_list(metadata):
|
||||
json_metadata = json.loads(metadata)
|
||||
if 'roles' in json_metadata:
|
||||
json_metadata['roles'] = ([x['id'] for x in json_metadata['roles']
|
||||
if 'inherited_to' not in x])
|
||||
return json.dumps(json_metadata)
|
||||
|
||||
downgrade_table = sql.Table(table_name, meta, autoload=True)
|
||||
for assignment in session.query(downgrade_table):
|
||||
values = {'data': dict_list_to_list(assignment.data)}
|
||||
update = build_update(table_name, downgrade_table, assignment, values)
|
||||
migrate_engine.execute(update)
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
|
||||
for grant_table in ['user_project_metadata', 'user_domain_metadata',
|
||||
'group_project_metadata', 'group_domain_metadata']:
|
||||
upgrade_grant_table(meta, migrate_engine, session, grant_table)
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
|
||||
for grant_table in ['user_project_metadata', 'user_domain_metadata',
|
||||
'group_project_metadata', 'group_domain_metadata']:
|
||||
downgrade_grant_table(meta, migrate_engine, session, grant_table)
|
||||
session.commit()
|
||||
session.close()
|
||||
@@ -1,116 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
if migrate_engine.name == 'sqlite':
|
||||
drop_credential_table_foreign_key_constraints_for_sqlite(
|
||||
migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
if migrate_engine.name == 'sqlite':
|
||||
add_credential_table_foreign_key_constraints_for_sqlite(migrate_engine)
|
||||
|
||||
|
||||
def drop_credential_table_foreign_key_constraints_for_sqlite(migrate_engine):
|
||||
meta = sqlalchemy.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
# NOTE(nachiappan): SQLite does not support ALTER TABLE DROP constraint.
|
||||
# So we need to move the data to new credenital table
|
||||
# created without constraints, drop the old table and
|
||||
# rename the new table to credential.
|
||||
sqlalchemy.Table('user', meta, autoload=True)
|
||||
tenant_table = sqlalchemy.Table(
|
||||
'tenant',
|
||||
meta,
|
||||
sqlalchemy.Column('id', sqlalchemy.String(64), primary_key=True),
|
||||
sqlalchemy.Column(
|
||||
'name', sqlalchemy.String(64), unique=True, nullable=False),
|
||||
sqlalchemy.Column('extra', sqlalchemy.Text()))
|
||||
tenant_table.create(migrate_engine, checkfirst=True)
|
||||
cred_table = sqlalchemy.Table('credential', meta, autoload=True)
|
||||
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
new_credential_table = sqlalchemy.Table(
|
||||
'new_credential',
|
||||
meta,
|
||||
sqlalchemy.Column('id', sqlalchemy.String(64), primary_key=True),
|
||||
sqlalchemy.Column('user_id',
|
||||
sqlalchemy.String(64),
|
||||
nullable=False),
|
||||
sqlalchemy.Column('project_id',
|
||||
sqlalchemy.String(64)),
|
||||
sqlalchemy.Column('blob', sqlalchemy.Text(), nullable=False),
|
||||
sqlalchemy.Column('type', sqlalchemy.String(255), nullable=False),
|
||||
sqlalchemy.Column('extra', sqlalchemy.Text()))
|
||||
new_credential_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
insert = new_credential_table.insert()
|
||||
for credential in session.query(cred_table):
|
||||
insert.execute({'id': credential.id,
|
||||
'user_id': credential.user_id,
|
||||
'project_id': credential.project_id,
|
||||
'blob': credential.blob,
|
||||
'type': credential.type,
|
||||
'extra': credential.extra})
|
||||
cred_table.drop()
|
||||
tenant_table.drop()
|
||||
new_credential_table.rename('credential')
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
|
||||
def add_credential_table_foreign_key_constraints_for_sqlite(migrate_engine):
|
||||
meta = sqlalchemy.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
cred_table = sqlalchemy.Table('credential', meta, autoload=True)
|
||||
sqlalchemy.Table('user', meta, autoload=True)
|
||||
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
old_credential_table = sqlalchemy.Table(
|
||||
'old_credential',
|
||||
meta,
|
||||
sqlalchemy.Column('id', sqlalchemy.String(64), primary_key=True),
|
||||
sqlalchemy.Column('user_id',
|
||||
sqlalchemy.String(64),
|
||||
sqlalchemy.ForeignKey('user.id'),
|
||||
nullable=False),
|
||||
# NOTE(nachiappan): Not creating the foreign key constraint with
|
||||
# project table as version 15 conflicts with
|
||||
# version 7.
|
||||
sqlalchemy.Column('project_id',
|
||||
sqlalchemy.String(64)),
|
||||
sqlalchemy.Column('blob', sqlalchemy.Text(), nullable=False),
|
||||
sqlalchemy.Column('type', sqlalchemy.String(255), nullable=False),
|
||||
sqlalchemy.Column('extra', sqlalchemy.Text()))
|
||||
old_credential_table.create(migrate_engine, checkfirst=True)
|
||||
|
||||
insert = old_credential_table.insert()
|
||||
for credential in session.query(cred_table):
|
||||
insert.execute({'id': credential.id,
|
||||
'user_id': credential.user_id,
|
||||
'project_id': credential.project_id,
|
||||
'blob': credential.blob,
|
||||
'type': credential.type,
|
||||
'extra': credential.extra})
|
||||
cred_table.drop()
|
||||
old_credential_table.rename('credential')
|
||||
session.commit()
|
||||
session.close()
|
||||
@@ -1,38 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
# This migration is relevant only for mysql because for all other
|
||||
# migrate engines these indexes were successfully dropped.
|
||||
if migrate_engine.name != 'mysql':
|
||||
return
|
||||
meta = sqlalchemy.MetaData(bind=migrate_engine)
|
||||
table = sqlalchemy.Table('credential', meta, autoload=True)
|
||||
for index in table.indexes:
|
||||
index.drop()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
if migrate_engine.name != 'mysql':
|
||||
return
|
||||
meta = sqlalchemy.MetaData(bind=migrate_engine)
|
||||
table = sqlalchemy.Table('credential', meta, autoload=True)
|
||||
index = sqlalchemy.Index('user_id', table.c['user_id'])
|
||||
index.create()
|
||||
index = sqlalchemy.Index('credential_project_id_fkey',
|
||||
table.c['project_id'])
|
||||
index.create()
|
||||
@@ -1,45 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
user_table.c.name.alter(type=sql.String(255))
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
if migrate_engine.name != 'mysql':
|
||||
# NOTE(aloga): sqlite does not enforce length on the
|
||||
# VARCHAR types: http://www.sqlite.org/faq.html#q9
|
||||
# postgresql and DB2 do not truncate.
|
||||
maker = sessionmaker(bind=migrate_engine)
|
||||
session = maker()
|
||||
for user in session.query(user_table).all():
|
||||
values = {'name': user.name[:64]}
|
||||
update = (user_table.update().
|
||||
where(user_table.c.id == user.id).
|
||||
values(values))
|
||||
migrate_engine.execute(update)
|
||||
|
||||
session.commit()
|
||||
session.close()
|
||||
user_table.c.name.alter(type=sql.String(64))
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
from keystone.common import utils
|
||||
from keystone import exception
|
||||
from keystone.openstack.common.gettextutils import _
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
credential_table = sql.Table('credential',
|
||||
meta,
|
||||
autoload=True)
|
||||
|
||||
ec2_cred_table = sql.Table('ec2_credential',
|
||||
meta,
|
||||
autoload=True)
|
||||
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
insert = credential_table.insert()
|
||||
for ec2credential in session.query(ec2_cred_table):
|
||||
cred_exist = check_credential_exists(ec2credential,
|
||||
credential_table, session)
|
||||
|
||||
if not cred_exist:
|
||||
credential = utils.convert_ec2_to_v3_credential(ec2credential)
|
||||
insert.execute(credential)
|
||||
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
ec2_cred_table.drop()
|
||||
|
||||
|
||||
def check_credential_exists(ec2credential, credential_table, session):
|
||||
credential = session.query(credential_table).filter_by(
|
||||
id=utils.hash_access_key(ec2credential.access)).first()
|
||||
if credential is None:
|
||||
return False
|
||||
blob = utils.get_blob_from_credential(credential)
|
||||
# check if credential with same access key but different
|
||||
# secret key already exists in credential table.
|
||||
# If exists raise an exception
|
||||
if blob['secret'] != ec2credential.secret:
|
||||
msg = _('Credential %(access)s already exists with different secret'
|
||||
' in %(table)s table')
|
||||
message = msg % {'access': ec2credential.access,
|
||||
'table': credential_table.name}
|
||||
raise exception.Conflict(type='credential', details=message)
|
||||
# check if credential with same access and secret key but
|
||||
# associated with a different project exists. If exists raise
|
||||
# an exception
|
||||
elif credential.project_id is not None and (
|
||||
credential.project_id != ec2credential.tenant_id):
|
||||
msg = _('Credential %(access)s already exists with different project'
|
||||
' in %(table)s table')
|
||||
message = msg % {'access': ec2credential.access,
|
||||
'table': credential_table.name}
|
||||
raise exception.Conflict(type='credential', details=message)
|
||||
# if credential with same access and secret key and not associated
|
||||
# with any projects already exists in the credential table, then
|
||||
# return true.
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
session = sql.orm.sessionmaker(bind=migrate_engine)()
|
||||
|
||||
ec2_credential_table = sql.Table(
|
||||
'ec2_credential',
|
||||
meta,
|
||||
sql.Column('access', sql.String(64), primary_key=True),
|
||||
sql.Column('secret', sql.String(64)),
|
||||
sql.Column('user_id', sql.String(64)),
|
||||
sql.Column('tenant_id', sql.String(64)),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
ec2_credential_table.create(migrate_engine, checkfirst=True)
|
||||
credential_table = sql.Table('credential',
|
||||
meta,
|
||||
autoload=True)
|
||||
insert = ec2_credential_table.insert()
|
||||
for credential in session.query(credential_table).filter(
|
||||
sql.and_(credential_table.c.type == 'ec2',
|
||||
credential_table.c.project_id is not None)).all():
|
||||
ec2_credential = utils.convert_v3_to_ec2_credential(credential)
|
||||
insert.execute(ec2_credential)
|
||||
|
||||
session.commit()
|
||||
session.close()
|
||||
-102
@@ -1,102 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
import json
|
||||
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
|
||||
def migrate_default_project_from_extra_json(meta, migrate_engine):
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
|
||||
user_list = list(user_table.select().execute())
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
for user in user_list:
|
||||
try:
|
||||
data = json.loads(user.extra)
|
||||
default_project_id = data.pop('default_project_id', None)
|
||||
v2_tenant_id = data.pop('tenantId', None)
|
||||
alt_v2_tenant_id = data.pop('tenant_id', None)
|
||||
except (ValueError, TypeError):
|
||||
# NOTE(morganfainberg): Somehow we have non-json data here. This
|
||||
# is a broken user, but it was broken beforehand. Cleaning it up
|
||||
# is not in the scope of this migration.
|
||||
continue
|
||||
|
||||
values = {}
|
||||
if default_project_id is not None:
|
||||
values['default_project_id'] = default_project_id
|
||||
elif v2_tenant_id is not None:
|
||||
values['default_project_id'] = v2_tenant_id
|
||||
elif alt_v2_tenant_id is not None:
|
||||
values['default_project_id'] = alt_v2_tenant_id
|
||||
|
||||
if 'default_project_id' in values:
|
||||
values['extra'] = json.dumps(data)
|
||||
update = user_table.update().where(
|
||||
user_table.c.id == user['id']).values(values)
|
||||
migrate_engine.execute(update)
|
||||
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
|
||||
def migrate_default_project_to_extra_json(meta, migrate_engine):
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
|
||||
user_list = list(user_table.select().execute())
|
||||
session = sessionmaker(bind=migrate_engine)()
|
||||
for user in user_list:
|
||||
try:
|
||||
data = json.loads(user.extra)
|
||||
except (ValueError, TypeError):
|
||||
# NOTE(morganfainberg): Somehow we have non-json data here. This
|
||||
# is a broken user, but it was broken beforehand. Cleaning it up
|
||||
# is not in the scope of this migration.
|
||||
continue
|
||||
|
||||
# NOTE(morganfainberg): We don't really know what the original 'extra'
|
||||
# property was here. Populate all of the possible variants we may have
|
||||
# originally used.
|
||||
if user.default_project_id is not None:
|
||||
data['default_project_id'] = user.default_project_id
|
||||
data['tenantId'] = user.default_project_id
|
||||
data['tenant_id'] = user.default_project_id
|
||||
|
||||
values = {'extra': json.dumps(data)}
|
||||
update = user_table.update().where(
|
||||
user_table.c.id == user.id).values(values)
|
||||
migrate_engine.execute(update)
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
default_project_id = sql.Column('default_project_id', sql.String(64))
|
||||
user_table.create_column(default_project_id)
|
||||
migrate_default_project_from_extra_json(meta, migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
migrate_default_project_to_extra_json(meta, migrate_engine)
|
||||
user_table = sql.Table('user', meta, autoload=True)
|
||||
user_table.drop_column('default_project_id')
|
||||
@@ -1,31 +0,0 @@
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
idx = sql.Index('ix_token_expires_valid', token.c.expires, token.c.valid)
|
||||
idx.create(migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
idx = sql.Index('ix_token_expires_valid', token.c.expires, token.c.valid)
|
||||
idx.drop(migrate_engine)
|
||||
@@ -0,0 +1,288 @@
|
||||
# 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.
|
||||
|
||||
import migrate
|
||||
import sqlalchemy as sql
|
||||
from sqlalchemy import orm
|
||||
|
||||
from keystone.common import sql as ks_sql
|
||||
from keystone.common.sql import migration_helpers
|
||||
from keystone import config
|
||||
from keystone.openstack.common import log
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
if migrate_engine.name == 'mysql':
|
||||
# In Folsom we explicitly converted migrate_version to UTF8.
|
||||
sql_stmt = 'ALTER TABLE migrate_version CONVERT TO CHARACTER SET utf8;'
|
||||
# Set default DB charset to UTF8.
|
||||
sql_stmt += ('ALTER DATABASE %s DEFAULT CHARACTER SET utf8;' %
|
||||
migrate_engine.url.database)
|
||||
migrate_engine.execute(sql_stmt)
|
||||
|
||||
credential = sql.Table(
|
||||
'credential', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('user_id', sql.String(length=64), nullable=False),
|
||||
sql.Column('project_id', sql.String(length=64)),
|
||||
sql.Column('blob', ks_sql.JsonBlob, nullable=False),
|
||||
sql.Column('type', sql.String(length=255), nullable=False),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
domain = sql.Table(
|
||||
'domain', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('name', sql.String(length=64), nullable=False),
|
||||
sql.Column('enabled', sql.Boolean, default=True, nullable=False),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
endpoint = sql.Table(
|
||||
'endpoint', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('legacy_endpoint_id', sql.String(length=64)),
|
||||
sql.Column('interface', sql.String(length=8), nullable=False),
|
||||
sql.Column('region', sql.String(length=255)),
|
||||
sql.Column('service_id', sql.String(length=64), nullable=False),
|
||||
sql.Column('url', sql.Text, nullable=False),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
group = sql.Table(
|
||||
'group', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('domain_id', sql.String(length=64), nullable=False),
|
||||
sql.Column('name', sql.String(length=64), nullable=False),
|
||||
sql.Column('description', sql.Text),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
group_domain_metadata = sql.Table(
|
||||
'group_domain_metadata', meta,
|
||||
sql.Column('group_id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('domain_id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('data', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
group_project_metadata = sql.Table(
|
||||
'group_project_metadata', meta,
|
||||
sql.Column('group_id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('project_id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('data', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
policy = sql.Table(
|
||||
'policy', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('type', sql.String(length=255), nullable=False),
|
||||
sql.Column('blob', ks_sql.JsonBlob, nullable=False),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
project = sql.Table(
|
||||
'project', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('name', sql.String(length=64), nullable=False),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
sql.Column('description', sql.Text),
|
||||
sql.Column('enabled', sql.Boolean),
|
||||
sql.Column('domain_id', sql.String(length=64), nullable=False),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
role = sql.Table(
|
||||
'role', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('name', sql.String(length=255), nullable=False),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
service = sql.Table(
|
||||
'service', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('type', sql.String(length=255)),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
token = sql.Table(
|
||||
'token', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('expires', sql.DateTime, default=None),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
sql.Column('valid', sql.Boolean, default=True, nullable=False),
|
||||
sql.Column('trust_id', sql.String(length=64)),
|
||||
sql.Column('user_id', sql.String(length=64)),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
trust = sql.Table(
|
||||
'trust', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('trustor_user_id', sql.String(length=64), nullable=False),
|
||||
sql.Column('trustee_user_id', sql.String(length=64), nullable=False),
|
||||
sql.Column('project_id', sql.String(length=64)),
|
||||
sql.Column('impersonation', sql.Boolean, nullable=False),
|
||||
sql.Column('deleted_at', sql.DateTime),
|
||||
sql.Column('expires_at', sql.DateTime),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
trust_role = sql.Table(
|
||||
'trust_role', meta,
|
||||
sql.Column('trust_id', sql.String(length=64), primary_key=True,
|
||||
nullable=False),
|
||||
sql.Column('role_id', sql.String(length=64), primary_key=True,
|
||||
nullable=False),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
user = sql.Table(
|
||||
'user', meta,
|
||||
sql.Column('id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('name', sql.String(length=255), nullable=False),
|
||||
sql.Column('extra', ks_sql.JsonBlob.impl),
|
||||
sql.Column('password', sql.String(length=128)),
|
||||
sql.Column('enabled', sql.Boolean),
|
||||
sql.Column('domain_id', sql.String(length=64), nullable=False),
|
||||
sql.Column('default_project_id', sql.String(length=64)),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
user_domain_metadata = sql.Table(
|
||||
'user_domain_metadata', meta,
|
||||
sql.Column('user_id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('domain_id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('data', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
user_group_membership = sql.Table(
|
||||
'user_group_membership', meta,
|
||||
sql.Column('user_id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('group_id', sql.String(length=64), primary_key=True),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
user_project_metadata = sql.Table(
|
||||
'user_project_metadata', meta,
|
||||
sql.Column('user_id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('project_id', sql.String(length=64), primary_key=True),
|
||||
sql.Column('data', ks_sql.JsonBlob.impl),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
# create all tables
|
||||
tables = [credential, domain, endpoint, group, group_domain_metadata,
|
||||
group_project_metadata, policy, project, role, service,
|
||||
token, trust, trust_role, user, user_domain_metadata,
|
||||
user_group_membership, user_project_metadata]
|
||||
|
||||
for table in tables:
|
||||
try:
|
||||
table.create()
|
||||
except Exception:
|
||||
LOG.exception('Exception while creating table: %r', table)
|
||||
raise
|
||||
|
||||
# Unique Constraints
|
||||
migrate.UniqueConstraint(user.c.domain_id,
|
||||
user.c.name,
|
||||
name='ixu_user_name_domain_id').create()
|
||||
migrate.UniqueConstraint(group.c.domain_id,
|
||||
group.c.name,
|
||||
name='ixu_group_name_domain_id').create()
|
||||
migrate.UniqueConstraint(role.c.name,
|
||||
name='ixu_role_name').create()
|
||||
migrate.UniqueConstraint(project.c.domain_id,
|
||||
project.c.name,
|
||||
name='ixu_project_name_domain_id').create()
|
||||
migrate.UniqueConstraint(domain.c.name,
|
||||
name='ixu_domain_name').create()
|
||||
|
||||
# Indexes
|
||||
sql.Index('ix_token_expires', token.c.expires).create()
|
||||
sql.Index('ix_token_expires_valid', token.c.expires,
|
||||
token.c.valid).create()
|
||||
|
||||
fkeys = [
|
||||
{'columns': [user_project_metadata.c.project_id],
|
||||
'references': [project.c.id],
|
||||
'name': 'fk_user_project_metadata_project_id'},
|
||||
|
||||
{'columns': [user_domain_metadata.c.domain_id],
|
||||
'references': [domain.c.id],
|
||||
'name': 'fk_user_domain_metadata_domain_id'},
|
||||
|
||||
{'columns': [group_project_metadata.c.project_id],
|
||||
'references': [project.c.id],
|
||||
'name': 'fk_group_project_metadata_project_id'},
|
||||
|
||||
{'columns': [group_domain_metadata.c.domain_id],
|
||||
'references': [domain.c.id],
|
||||
'name': 'fk_group_domain_metadata_domain_id'},
|
||||
|
||||
{'columns': [endpoint.c.service_id],
|
||||
'references': [service.c.id]},
|
||||
|
||||
{'columns': [user_group_membership.c.group_id],
|
||||
'references': [group.c.id],
|
||||
'name': 'fk_user_group_membership_group_id'},
|
||||
|
||||
{'columns': [user_group_membership.c.user_id],
|
||||
'references':[user.c.id],
|
||||
'name': 'fk_user_group_membership_user_id'},
|
||||
|
||||
{'columns': [user.c.domain_id],
|
||||
'references': [domain.c.id],
|
||||
'name': 'fk_user_domain_id'},
|
||||
|
||||
{'columns': [group.c.domain_id],
|
||||
'references': [domain.c.id],
|
||||
'name': 'fk_group_domain_id'},
|
||||
|
||||
{'columns': [project.c.domain_id],
|
||||
'references': [domain.c.id],
|
||||
'name': 'fk_project_domain_id'}
|
||||
]
|
||||
|
||||
for fkey in fkeys:
|
||||
migrate.ForeignKeyConstraint(columns=fkey['columns'],
|
||||
refcolumns=fkey['references'],
|
||||
name=fkey.get('name')).create()
|
||||
|
||||
# Create the default domain.
|
||||
session = orm.sessionmaker(bind=migrate_engine)()
|
||||
domain.insert(migration_helpers.get_default_domain()).execute()
|
||||
session.commit()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
raise NotImplementedError('Downgrade to pre-Havana release db schema is '
|
||||
'unsupported.')
|
||||
@@ -1,31 +0,0 @@
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sql
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
idx = sql.Index('ix_token_valid', token.c.valid)
|
||||
idx.drop(migrate_engine)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = sql.MetaData()
|
||||
meta.bind = migrate_engine
|
||||
token = sql.Table('token', meta, autoload=True)
|
||||
idx = sql.Index('ix_token_valid', token.c.valid)
|
||||
idx.create(migrate_engine)
|
||||
@@ -22,11 +22,29 @@ from migrate import exceptions
|
||||
import sqlalchemy
|
||||
|
||||
from keystone.common import sql
|
||||
from keystone import config
|
||||
from keystone import contrib
|
||||
from keystone import exception
|
||||
from keystone.openstack.common.db.sqlalchemy import migration
|
||||
from keystone.openstack.common.gettextutils import _
|
||||
from keystone.openstack.common import importutils
|
||||
from keystone.openstack.common import jsonutils
|
||||
|
||||
|
||||
DB_INIT_VERSION = 35
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def get_default_domain():
|
||||
# Return the reference used for the default domain structure during
|
||||
# sql migrations.
|
||||
return {
|
||||
'id': CONF.identity.default_domain_id,
|
||||
'name': 'Default',
|
||||
'enabled': True,
|
||||
'extra': jsonutils.dumps({'description': 'Owns users and tenants '
|
||||
'(i.e. projects) available '
|
||||
'on Identity API v2.'})}
|
||||
|
||||
|
||||
# Different RDBMSs use different schemes for naming the Foreign Key
|
||||
@@ -117,7 +135,9 @@ def find_migrate_repo(package=None, repo_name='migrate_repo'):
|
||||
def sync_database_to_version(extension=None, version=None):
|
||||
if not extension:
|
||||
abs_path = find_migrate_repo()
|
||||
init_version = DB_INIT_VERSION
|
||||
else:
|
||||
init_version = 0
|
||||
try:
|
||||
package_name = '.'.join((contrib.__name__, extension))
|
||||
package = importutils.import_module(package_name)
|
||||
@@ -136,7 +156,8 @@ def sync_database_to_version(extension=None, version=None):
|
||||
except exception.MigrationNotProvided as e:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
migration.db_sync(sql.get_engine(), abs_path, version=version)
|
||||
migration.db_sync(sql.get_engine(), abs_path, version=version,
|
||||
init_version=init_version)
|
||||
|
||||
|
||||
def get_db_version(extension=None):
|
||||
|
||||
+146
-1492
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user