¡@

Home 

OpenStack Study: 039_grant_to_assignment.py

OpenStack Index

**** CubicPower OpenStack Study ****

def migrate_grant_table(meta, migrate_engine, session, table_name):

    def extract_actor_and_target(table_name, composite_grant):

        if table_name == USER_PROJECT_TABLE:

            return {'type': assignment_sql.AssignmentType.USER_PROJECT,

                    'actor_id': composite_grant.user_id,

                    'target_id': composite_grant.project_id}

        elif table_name == GROUP_PROJECT_TABLE:

            return {'type': assignment_sql.AssignmentType.GROUP_PROJECT,

                    'actor_id': composite_grant.group_id,

                    'target_id': composite_grant.project_id}

        elif table_name == USER_DOMAIN_TABLE:

            return {'type': assignment_sql.AssignmentType.USER_DOMAIN,

                    'actor_id': composite_grant.user_id,

                    'target_id': composite_grant.domain_id}

        else:

            return {'type': assignment_sql.AssignmentType.GROUP_DOMAIN,

                    'actor_id': composite_grant.group_id,

                    'target_id': composite_grant.domain_id}

    def grant_to_grant_dict_list(table_name, composite_grant):

        """Make each role in the list of this entry a separate assignment."""

        json_metadata = json.loads(composite_grant.data)

        role_dict_list = []

        if 'roles' in json_metadata:

            for x in json_metadata['roles']:

                if x.get('id') is None:

                    # Looks like an invalid role, drop it

                    break

                grant = extract_actor_and_target(table_name, composite_grant)

                grant['role_id'] = x.get('id')

                grant['inherited'] = False

                if x.get('inherited_to') == 'projects':

                    grant['inherited'] = True

                role_dict_list.append(grant)

        return role_dict_list

    upgrade_table = sql.Table(table_name, meta, autoload=True)

    assignment_table = sql.Table(ASSIGNMENT_TABLE, meta, autoload=True)

    # For each grant in this table, expand it out to be an assignment entry for

    # each role in the metadata

    for grant in session.query(upgrade_table).all():

        for grant_role in grant_to_grant_dict_list(table_name, grant):

            new_entry = assignment_table.insert().values(

                type=grant_role['type'],

                actor_id=grant_role['actor_id'],

                target_id=grant_role['target_id'],

                role_id=grant_role['role_id'],

                inherited=grant_role['inherited'])

            migrate_engine.execute(new_entry)

    # Delete all the rows

    migrate_engine.execute(upgrade_table.delete())

**** CubicPower OpenStack Study ****

def downgrade_assignment_table(meta, migrate_engine):

    def add_to_dict_list(metadata, assignment_row):

        """Update a metadata dict list with the role.

        For the assignment row supplied, we need to append the role_id into

        the metadata list of dicts.  If the row is inherited, then we mark

        it so in the dict we append.

        """

        new_entry = {'id': assignment_row.role_id}

        if assignment_row.inherited and (

                assignment_row.type ==

                assignment_sql.AssignmentType.USER_DOMAIN or

                assignment_row.type ==

                assignment_sql.AssignmentType.GROUP_DOMAIN):

            new_entry['inherited_to'] = 'projects'

        if metadata is not None:

            json_metadata = json.loads(metadata)

        else:

            json_metadata = {}

        if json_metadata.get('roles') is None:

            json_metadata['roles'] = []

        json_metadata['roles'].append(new_entry)

        return json.dumps(json_metadata)

    def build_user_project_entry(meta, session, row):

        update_table = sql.Table(USER_PROJECT_TABLE, meta, autoload=True)

        q = session.query(update_table)

        q = q.filter_by(user_id=row.actor_id)

        q = q.filter_by(project_id=row.target_id)

        ref = q.first()

        if ref is not None:

            values = {'data': add_to_dict_list(ref.data, row)}

            update = update_table.update().where(

                update_table.c.user_id == ref.user_id).where(

                    update_table.c.project_id == ref.project_id).values(values)

        else:

            values = {'user_id': row.actor_id,

                      'project_id': row.target_id,

                      'data': add_to_dict_list(None, row)}

            update = update_table.insert().values(values)

        return update

    def build_group_project_entry(meta, session, row):

        update_table = sql.Table(GROUP_PROJECT_TABLE, meta, autoload=True)

        q = session.query(update_table)

        q = q.filter_by(group_id=row.actor_id)

        q = q.filter_by(project_id=row.target_id)

        ref = q.first()

        if ref is not None:

            values = {'data': add_to_dict_list(ref.data, row)}

            update = update_table.update().where(

                update_table.c.group_id == ref.group_id).where(

                    update_table.c.project_id == ref.project_id).values(values)

        else:

            values = {'group_id': row.actor_id,

                      'project_id': row.target_id,

                      'data': add_to_dict_list(None, row)}

            update = update_table.insert().values(values)

        return update

    def build_user_domain_entry(meta, session, row):

        update_table = sql.Table(USER_DOMAIN_TABLE, meta, autoload=True)

        q = session.query(update_table)

        q = q.filter_by(user_id=row.actor_id)

        q = q.filter_by(domain_id=row.target_id)

        ref = q.first()

        if ref is not None:

            values = {'data': add_to_dict_list(ref.data, row)}

            update = update_table.update().where(

                update_table.c.user_id == ref.user_id).where(

                    update_table.c.domain_id == ref.domain_id).values(values)

        else:

            values = {'user_id': row.actor_id,

                      'domain_id': row.target_id,

                      'data': add_to_dict_list(None, row)}

            update = update_table.insert().values(values)

        return update

    def build_group_domain_entry(meta, session, row):

        update_table = sql.Table(GROUP_DOMAIN_TABLE, meta, autoload=True)

        q = session.query(update_table)

        q = q.filter_by(group_id=row.actor_id)

        q = q.filter_by(domain_id=row.target_id)

        ref = q.first()

        if ref is not None:

            values = {'data': add_to_dict_list(ref.data, row)}

            update = update_table.update().where(

                update_table.c.group_id == ref.group_id).where(

                    update_table.c.domain_id == ref.domain_id).values(values)

        else:

            values = {'group_id': row.actor_id,

                      'domain_id': row.target_id,

                      'data': add_to_dict_list(None, row)}

            update = update_table.insert().values(values)

        return update

    def build_update(meta, session, row):

        """Build an update or an insert to the correct metadata table."""

        if row.type == assignment_sql.AssignmentType.USER_PROJECT:

            return build_user_project_entry(meta, session, row)

        elif row.type == assignment_sql.AssignmentType.GROUP_PROJECT:

            return build_group_project_entry(meta, session, row)

        elif row.type == assignment_sql.AssignmentType.USER_DOMAIN:

            return build_user_domain_entry(meta, session, row)

        elif row.type == assignment_sql.AssignmentType.GROUP_DOMAIN:

            return build_group_domain_entry(meta, session, row)

        # If the row type doesn't match any that we understand we drop

        # the data.

    session = sql.orm.sessionmaker(bind=migrate_engine)()

    downgrade_table = sql.Table(ASSIGNMENT_TABLE, meta, autoload=True)

    for assignment in session.query(downgrade_table).all():

        update = build_update(meta, session, assignment)

        if update is not None:

            migrate_engine.execute(update)

            session.commit()

    # Delete all the rows

    migrate_engine.execute(downgrade_table.delete())

    session.commit()

    session.close()

**** CubicPower OpenStack Study ****

def upgrade(migrate_engine):

    meta = sql.MetaData()

    meta.bind = migrate_engine

    session = sql.orm.sessionmaker(bind=migrate_engine)()

    for table_name in GRANT_TABLES:

        migrate_grant_table(meta, migrate_engine, session, table_name)

    session.commit()

    session.close()

**** CubicPower OpenStack Study ****

def downgrade(migrate_engine):

    meta = sql.MetaData()

    meta.bind = migrate_engine

    downgrade_assignment_table(meta, migrate_engine)