Rename application credential restriction column
In the application credential spec[1] we decided to add on a parameter that would control whether an application credential could be used to create other application credentials. This parameter is also used to control whether it can be used to delete other application credentials and whether it can create and delete trusts. Therefore the name `allow_application_credential_creation` is misleading. Moreover, giving a property of the resource a name that is an imperative verb is not great. It makes more sense for a property to be a noun, an adjective, or a passive verb. This change renames the `allow_application_credential_creation`` column to ``unrestricted``. This maintains the same boolean context, i.e. a "true" value for the old name maintains the same meaning as a "true" value for the new name. At this point, the application credential API has not yet been exposed, so there should be no data in this table and no need for complicated migration triggers. In general, we only need to do a column alter to rename it. Sqlite is special because it does not support column alters, so in order to accomodate our tests the migration involves copying the whole table, minus the old column, and recreating it with the new column. Change-Id: Id26a2790acae25f80bd28a8cb121c80cb5064645
This commit is contained in:
parent
d94d9c566f
commit
5fe9e3761d
|
@ -27,7 +27,7 @@ class ApplicationCredentialModel(sql.ModelBase, sql.ModelDictMixin):
|
|||
__tablename__ = 'application_credential'
|
||||
attributes = ['internal_id', 'id', 'name', 'secret_hash', 'description',
|
||||
'user_id', 'project_id', 'system', 'expires_at',
|
||||
'allow_application_credential_creation']
|
||||
'unrestricted']
|
||||
internal_id = sql.Column(sql.Integer, primary_key=True, nullable=False)
|
||||
id = sql.Column(sql.String(64), nullable=False)
|
||||
name = sql.Column(sql.String(255), nullable=False)
|
||||
|
@ -37,7 +37,7 @@ class ApplicationCredentialModel(sql.ModelBase, sql.ModelDictMixin):
|
|||
project_id = sql.Column(sql.String(64), nullable=True)
|
||||
system = sql.Column(sql.String(64), nullable=True)
|
||||
expires_at = sql.Column(sql.DateTimeInt())
|
||||
allow_application_credential_creation = sql.Column(sql.Boolean)
|
||||
unrestricted = sql.Column(sql.Boolean)
|
||||
__table_args__ = (sql.UniqueConstraint('name', 'user_id',
|
||||
name='duplicate_app_cred_constraint'),)
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# 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
|
||||
|
||||
application_credential_table = sql.Table(
|
||||
'application_credential', meta, autoload=True
|
||||
)
|
||||
if migrate_engine.name == 'sqlite':
|
||||
old_table = sql.Table('application_credential', meta, autoload=True)
|
||||
new_table = sql.Table('application_credential_temp', meta,
|
||||
autoload=True)
|
||||
old_table.drop()
|
||||
new_table.rename('application_credential')
|
||||
else:
|
||||
table = application_credential_table
|
||||
column = table.c.allow_application_credential_creation
|
||||
column.alter(name='unrestricted')
|
|
@ -0,0 +1,15 @@
|
|||
# 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.
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
pass
|
|
@ -0,0 +1,40 @@
|
|||
# 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
|
||||
|
||||
# MySQL and PostgreSQL can handle a column rename.
|
||||
# Only Sqlite is special. Since Sqlite can't support an online upgrade
|
||||
# anyway, just brute-force the migration by copying the table.
|
||||
if migrate_engine.name == 'sqlite':
|
||||
old_table = sql.Table(
|
||||
'application_credential', meta, autoload=True
|
||||
)
|
||||
|
||||
args = []
|
||||
for column in old_table.columns:
|
||||
if column.name != 'allow_application_credential_creation':
|
||||
args.append(column.copy())
|
||||
unrestricted = sql.Column('unrestricted', sql.Boolean)
|
||||
args.append(unrestricted)
|
||||
constraint = sql.UniqueConstraint('user_id', 'name',
|
||||
name='duplicate_app_cred_constraint')
|
||||
args.append(constraint)
|
||||
new_table = sql.Table('application_credential_temp',
|
||||
old_table.metadata, *args)
|
||||
new_table.create(migrate_engine, checkfirst=True)
|
|
@ -47,7 +47,7 @@ class ApplicationCredentialTests(object):
|
|||
{'id': self.role__member_['id']},
|
||||
],
|
||||
'secret': uuid.uuid4().hex,
|
||||
'allow_application_credential_creation': False
|
||||
'unrestricted': False
|
||||
}
|
||||
return app_cred_data
|
||||
|
||||
|
@ -86,7 +86,7 @@ class ApplicationCredentialTests(object):
|
|||
def test_application_credential_allow_recursion(self):
|
||||
app_cred = self._new_app_cred_data(self.user_foo['id'],
|
||||
project_id=self.tenant_bar['id'])
|
||||
app_cred['allow_application_credential_creation'] = True
|
||||
app_cred['unrestricted'] = True
|
||||
resp = self.app_cred_api.create_application_credential(app_cred)
|
||||
resp.pop('roles')
|
||||
app_cred.pop('roles')
|
||||
|
|
|
@ -2866,6 +2866,52 @@ class FullMigration(SqlMigrateBase, unit.TestCase):
|
|||
}
|
||||
application_credential_table.insert().values(app_cred).execute()
|
||||
|
||||
def test_migration_036_rename_application_credentials_column(self):
|
||||
self.expand(35)
|
||||
self.migrate(35)
|
||||
self.contract(35)
|
||||
|
||||
application_credential_table_name = 'application_credential'
|
||||
application_credential_role_table_name = 'application_credential_role'
|
||||
|
||||
self.expand(36)
|
||||
self.migrate(36)
|
||||
self.contract(36)
|
||||
|
||||
self.assertTableColumns(
|
||||
application_credential_table_name,
|
||||
['internal_id', 'id', 'name', 'secret_hash',
|
||||
'description', 'user_id', 'project_id', 'system', 'expires_at',
|
||||
'unrestricted']
|
||||
)
|
||||
|
||||
application_credential_table = sqlalchemy.Table(
|
||||
application_credential_table_name, self.metadata, autoload=True
|
||||
)
|
||||
app_cred_role_table = sqlalchemy.Table(
|
||||
application_credential_role_table_name,
|
||||
self.metadata, autoload=True
|
||||
)
|
||||
|
||||
# Test that the new column works
|
||||
app_cred = {
|
||||
'internal_id': 1,
|
||||
'id': uuid.uuid4().hex,
|
||||
'name': uuid.uuid4().hex,
|
||||
'secret_hash': uuid.uuid4().hex,
|
||||
'description': uuid.uuid4().hex,
|
||||
'user_id': uuid.uuid4().hex,
|
||||
'system': uuid.uuid4().hex,
|
||||
'expires_at': None,
|
||||
'unrestricted': False
|
||||
}
|
||||
application_credential_table.insert().values(app_cred).execute()
|
||||
role_rel = {
|
||||
'application_credential_id': app_cred['internal_id'],
|
||||
'role_id': uuid.uuid4().hex
|
||||
}
|
||||
app_cred_role_table.insert().values(role_rel).execute()
|
||||
|
||||
|
||||
class MySQLOpportunisticFullMigration(FullMigration):
|
||||
FIXTURE = test_base.MySQLOpportunisticFixture
|
||||
|
|
Loading…
Reference in New Issue