# vim: tabstop=4 shiftwidth=4 softtabstop=4
# 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 re
import sqlalchemy
from sqlalchemy import exc
from keystone.common import logging
from keystone import config
from keystone.contrib.ec2.backends import sql as ec2_sql
from keystone.identity.backends import sql as identity_sql
LOG = logging.getLogger(__name__)
CONF = config.CONF
DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id
def export_db(db):
table_names = db.table_names()
migration_data = {}
for table_name in table_names:
query = db.execute("select * from %s" % table_name)
table_data = []
for row in query.fetchall():
entry = {}
for k in row.keys():
entry[k] = row[k]
table_data.append(entry)
migration_data[table_name] = table_data
return migration_data
def _translate_replacements(s):
if '%' not in str(s):
return s
return re.sub(r'%([\w_]+)%', r'$(\1)s', s)
class LegacyMigration(object):
def __init__(self, db_string):
self.db = sqlalchemy.create_engine(db_string)
self.identity_driver = identity_sql.Identity()
self.identity_driver.db_sync()
self.ec2_driver = ec2_sql.Ec2()
self._data = {}
self._user_map = {}
self._project_map = {}
self._role_map = {}
def migrate_all(self):
self._export_legacy_db()
self._migrate_projects()
self._migrate_users()
self._migrate_roles()
self._migrate_user_roles()
self._migrate_tokens()
self._migrate_ec2()
def dump_catalog(self):
"""Generate the contents of a catalog templates file."""
self._export_legacy_db()
services_by_id = dict((x['id'], x) for x in self._data['services'])
template = 'catalog.%(region)s.%(service_type)s.%(key)s = %(value)s'
o = []
for row in self._data['endpoint_templates']:
service = services_by_id[row['service_id']]
d = {'service_type': service['type'],
'region': row['region']}
for x in ['internal_url', 'public_url', 'admin_url', 'enabled']:
d['key'] = x.replace('_url', 'URL')
d['value'] = _translate_replacements(row[x])
o.append(template % d)
d['key'] = 'name'
d['value'] = service['desc']
o.append(template % d)
return o
def _export_legacy_db(self):
self._data = export_db(self.db)
def _migrate_projects(self):
for x in self._data['tenants']:
# map
new_dict = {'description': x.get('desc', ''),
'id': x.get('uid', x.get('id')),
'enabled': x.get('enabled', True),
'domain_id': x.get('domain_id', DEFAULT_DOMAIN_ID)}
new_dict['name'] = x.get('name', new_dict.get('id'))
# track internal ids
self._project_map[x.get('id')] = new_dict['id']
# create
#print 'create_project(%s, %s)' % (new_dict['id'], new_dict)
self.identity_driver.create_project(new_dict['id'], new_dict)
def _migrate_users(self):
for x in self._data['users']:
# map
new_dict = {'email': x.get('email', ''),
'password': x.get('password', None),
'id': x.get('uid', x.get('id')),
'enabled': x.get('enabled', True),
'domain_id': x.get('domain_id', DEFAULT_DOMAIN_ID)}
127 if x.get('tenant_id'):
new_dict['tenant_id'] = self._project_map.get(x['tenant_id'])
new_dict['name'] = x.get('name', new_dict.get('id'))
# track internal ids
self._user_map[x.get('id')] = new_dict['id']
# create
#print 'create_user(%s, %s)' % (new_dict['id'], new_dict)
self.identity_driver.create_user(new_dict['id'], new_dict)
135 if new_dict.get('tenant_id'):
self.identity_driver.add_user_to_project(
new_dict['tenant_id'],
new_dict['id'])
def _migrate_roles(self):
for x in self._data['roles']:
# map
new_dict = {'id': x['id'],
'name': x.get('name', x['id'])}
# track internal ids
self._role_map[x.get('id')] = new_dict['id']
# create
self.identity_driver.create_role(new_dict['id'], new_dict)
def _migrate_user_roles(self):
for x in self._data['user_roles']:
# map
155 if (not x.get('user_id')
or not x.get('tenant_id')
or not x.get('role_id')):
continue
user_id = self._user_map[x['user_id']]
tenant_id = self._project_map[x['tenant_id']]
role_id = self._role_map[x['role_id']]
try:
self.identity_driver.add_user_to_project(tenant_id, user_id)
except Exception:
pass
self.identity_driver.add_role_to_user_and_project(
user_id, tenant_id, role_id)
def _migrate_tokens(self):
pass
def _migrate_ec2(self):
for x in self._data['credentials']:
new_dict = {'user_id': x['user_id'],
'tenant_id': x['tenant_id'],
'access': x['key'],
'secret': x['secret']}
try:
self.ec2_driver.create_credential(None, new_dict)
except exc.IntegrityError:
LOG.exception(_('Cannot migrate EC2 credential: %s') % x)
|