Merge "Collapse SQL Migrations"
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