from oslo.db.sqlalchemy import session as db_session
from oslo.utils import timeutils
import osprofiler.sqlalchemy
+import six
import sqlalchemy
from sqlalchemy import or_
from sqlalchemy.orm import joinedload, joinedload_all
if 'volume_type_id' not in values:
values['volume_type_id'] = volume_type_id
+ if 'encryption_id' not in values:
+ values['encryption_id'] = six.text_type(uuid.uuid4())
+
encryption.update(values)
session.add(encryption)
--- /dev/null
+# 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 uuid
+
+from migrate import PrimaryKeyConstraint, ForeignKeyConstraint
+from sqlalchemy import Column
+from sqlalchemy import MetaData, String, Table
+
+
+def upgrade(migrate_engine):
+ """Add UUID primary key column to encryption."""
+ meta = MetaData()
+ meta.bind = migrate_engine
+
+ encryptions = Table('encryption', meta, autoload=True)
+
+ encryption_id = Column('encryption_id', String(36))
+ encryptions.create_column(encryption_id)
+
+ encryption_items = list(encryptions.select().execute())
+
+ for item in encryption_items:
+ encryptions.update().\
+ where(encryptions.c.volume_type_id == item['volume_type_id']).\
+ values(encryption_id=str(uuid.uuid4())).execute()
+
+ # NOTE (e0ne): need to drop FK first for MySQL
+ if migrate_engine.name == 'mysql':
+ ref_table = Table('volume_types', meta, autoload=True)
+ params = {'columns': [encryptions.c['volume_type_id']],
+ 'refcolumns': [ref_table.c['id']],
+ 'name': 'encryption_ibfk_1'}
+ volume_type_fk = ForeignKeyConstraint(**params)
+ volume_type_fk.drop()
+
+ try:
+ volume_type_pk = PrimaryKeyConstraint('volume_type_id',
+ table=encryptions)
+ volume_type_pk.drop()
+ except Exception:
+ # NOTE (e0ne): SQLite doesn't support 'drop constraint' statament
+ if migrate_engine.url.get_dialect().name.startswith('sqlite'):
+ pass
+ else:
+ raise
+
+ pkey = PrimaryKeyConstraint(encryptions.columns.encryption_id)
+ pkey.create()
+
+
+def downgrade(migrate_engine):
+ meta = MetaData()
+ meta.bind = migrate_engine
+
+ encryptions = Table('encryption', meta, autoload=True)
+ encryption_id_pk = PrimaryKeyConstraint(encryptions.columns.encryption_id)
+
+ encryption_id_pk.drop()
+ encryptions.drop_column(encryptions.columns.encryption_id)
+
+ volume_type_pk = PrimaryKeyConstraint(encryptions.columns.volume_type_id)
+ volume_type_pk.create()
+
+ ref_table = Table('volume_types', meta, autoload=True)
+ params = {'columns': [encryptions.c['volume_type_id']],
+ 'refcolumns': [ref_table.c['id']],
+ 'name': 'encryption_ibfk_1'}
+ volume_type_fk = ForeignKeyConstraint(**params)
+ volume_type_fk.create()
--- /dev/null
+CREATE TABLE encryption_v32 (
+ created_at DATETIME,
+ updated_at DATETIME,
+ deleted_at DATETIME,
+ deleted BOOLEAN,
+ cipher VARCHAR(255),
+ control_location VARCHAR(255),
+ key_size INTEGER,
+ provider VARCHAR(255),
+ volume_type_id VARCHAR(36),
+ PRIMARY KEY (volume_type_id),
+ FOREIGN KEY(volume_type_id) REFERENCES volume_types(id)
+);
+
+INSERT INTO encryption_v32
+ SELECT created_at,
+ updated_at,
+ deleted_at,
+ deleted,
+ cipher,
+ control_location,
+ key_size,
+ provider,
+ volume_type_id
+ FROM encryption;
+
+DROP TABLE encryption;
+ALTER TABLE encryption_v32 RENAME TO encryption;
"""
__tablename__ = 'encryption'
+ encryption_id = Column(String(36), primary_key=True)
cipher = Column(String(255))
key_size = Column(Integer)
provider = Column(String(255))
control_location = Column(String(255))
- volume_type_id = Column(String(36),
- ForeignKey('volume_types.id'),
- primary_key=True)
+ volume_type_id = Column(String(36), ForeignKey('volume_types.id'))
volume_type = relationship(
VolumeTypes,
backref="encryption",
'deleted_at',
'created_at',
'updated_at',
+ 'encryption_id',
]
def setUp(self):
volume_types = db_utils.get_table(engine, 'volume_types')
self.assertNotIn('is_public', volume_types.c)
+ def _check_033(self, engine, data):
+ """Test adding encryption_id column to encryption table."""
+ encryptions = db_utils.get_table(engine, 'encryption')
+ self.assertIsInstance(encryptions.c.encryption_id.type,
+ sqlalchemy.types.VARCHAR)
+
+ def _post_downgrade_033(self, engine):
+ metadata = sqlalchemy.schema.MetaData()
+ metadata.bind = engine
+
+ encryptions = db_utils.get_table(engine, 'encryption')
+ self.assertNotIn('encryption_id', encryptions.c)
+
def test_walk_versions(self):
self.walk_versions(True, False)
# And add encryption for good measure
enc_keyvals1 = {'cipher': 'c1', 'key_size': 256, 'provider': 'p1',
- 'control_location': 'front-end'}
+ 'control_location': 'front-end',
+ 'encryption_id': 'uuid1'}
enc_keyvals2 = {'cipher': 'c1', 'key_size': 128, 'provider': 'p1',
- 'control_location': 'front-end'}
+ 'control_location': 'front-end',
+ 'encryption_id': 'uuid2'}
db.volume_type_encryption_create(self.ctxt, type_ref1['id'],
enc_keyvals1)
db.volume_type_encryption_create(self.ctxt, type_ref2['id'],
'control_location': (None, 'front-end'),
'deleted': (None, False),
'key_size': (None, 256),
- 'provider': (None, 'p1')})
+ 'provider': (None, 'p1'),
+ 'encryption_id': (None, 'uuid1')})
+
+ def test_encryption_create(self):
+ volume_type = volume_types.create(self.ctxt, "type1")
+ volume_type_id = volume_type.get('id')
+ encryption = {
+ 'control_location': 'front-end',
+ 'provider': 'fake_provider',
+ }
+ db_api.volume_type_encryption_create(self.ctxt, volume_type_id,
+ encryption)
+ self.assertTrue(volume_types.is_encrypted(self.ctxt, volume_type_id))
def test_get_volume_type_encryption(self):
volume_type = volume_types.create(self.ctxt, "type1")