예제 #1
0
def add_region_product(keycloak: KeycloakClient, region_id, body, user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        if not keycloak.user_check_group(user, region.owner_group):
            raise Forbidden("You don't have write access to this region.")

    product = model.Product.query.get(body['id'])
    if not product:
        return problem(404, 'Not Found',
                       f'Product {body["id"]} does not exist')

    q = model.RegionProduct.query.filter(
        sqlalchemy.and_(
            model.RegionProduct.region_id == region.id,
            model.RegionProduct.product_id == product.id,
        ))
    if q.count() == 0:
        relation = model.RegionProduct(
            region_id=region.id,
            product_id=product.id,
            enabled=body.get('enabled', True),
        )
        db.session.add(relation)
        db.session.commit()
        logger.info(
            f'Added Product {product.name} (id {product.id}) to Region {region.name} '
            f'(id {region.id}) by user {user}')
    elif 'enabled' in body:
        for relation in q.all():
            relation.enabled = body['enabled']
        db.session.commit()
예제 #2
0
def list_region_products(keycloak: KeycloakClient, region_id, user, filter_):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if region.users_group is not None:
        if not keycloak.user_check_role(user, ADMIN_ROLE):
            if not keycloak.user_check_group_any(
                    user, [region.users_group, region.owner_group]):
                raise Forbidden("You don't have access to this region.")

    products_relation = region.products_relation

    if 'name' in filter_:
        products_relation = products_relation.filter(
            model.Region.name.ilike(filter_['enabled']), )

    if 'enabled' in filter_:
        products_relation = products_relation.filter(
            model.Product.enabled == filter_['enabled'], )

    return [{
        'id': r.product_id,
        'region_id': r.region.id,
        'product_id': r.product.id,
        'product': r.product.to_dict(),
        'enabled': r.enabled,
    } | {
        '_href': _region_href(r.region) | _product_href(r.product)
    } for r in products_relation]
예제 #3
0
def delete_region(keycloak: KeycloakClient, region_id, user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        if not keycloak.user_check_group(user, region.owner_group):
            raise Forbidden("You don't have write access to this region.")

    q = model.RegionProduct.query.filter(
        model.RegionProduct.region_id == region.id, )
    if q.count() > 0:
        for relation in q.all():
            db.session.delete(relation)
        db.session.flush()

    db.session.delete(region)

    try:
        owner_group = keycloak.group_get(region.owner_group)
        keycloak.group_delete(owner_group['id'])
        logger.info(f'Deleted owners group {owner_group["id"]}')

    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error',
                       f'Failed to delete owner group in Keycloak, {e}')

    db.session.commit()
    logger.info(
        f'Region {region.name} (id {region.id}) deleted by user {user}')
예제 #4
0
def update_region(keycloak: KeycloakClient, vault: Vault, region_id, body,
                  user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        if not keycloak.user_check_group(user, region.owner_group):
            raise Forbidden("You don't have write access to this region.")

    try:
        if body.get('users_group'):
            keycloak.group_get(body['users_group'])
    except KeycloakGetError as e:
        logger.exception(e)
        return problem(
            400, 'Users group does not exist',
            f'Users group {body["users_group"]} does not exist in Keycloak, '
            'you have to create group first or use existing group.')

    if 'quota' in body:
        if body['quota']:
            if region.quota is None:
                region.quota = model.Quota(**body['quota'])
            else:
                for k, v in body['quota'].items():
                    setattr(region.quota, k, v)
        else:
            region.quota = None
        del body['quota']

    openstack_credentials = dpath.get(body,
                                      'openstack/credentials',
                                      default=region.openstack_credentials)
    if not isinstance(openstack_credentials, str):
        vault.write(region.openstack_credentials, openstack_credentials)
        dpath.delete(body, 'openstack/credentials')

    satellite_credentials = dpath.get(body,
                                      'satellite/credentials',
                                      default=region.satellite_credentials)
    if not isinstance(satellite_credentials, str):
        vault.write(region.satellite_credentials, satellite_credentials)
        dpath.delete(body, 'satellite/credentials')

    dns_server_key = dpath.get(body,
                               'dns_server/key',
                               default=region.dns_server_key)
    if not isinstance(dns_server_key, str):
        vault.write(region.dns_server_key, dns_server_key)
        dpath.delete(body, 'dns_server/key')

    region.update_from_dict(body)

    db.session.commit()
    logger.info(
        f'Region {region.name} (id {region.id}) updated by user {user}')

    return region.to_dict() | {'_href': _region_href(region)}
예제 #5
0
def get_region(keycloak: KeycloakClient, region_id, user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if region.users_group is not None:
        if not keycloak.user_check_role(user, ADMIN_ROLE):
            if not keycloak.user_check_group_any(
                    user, [region.users_group, region.owner_group]):
                raise Forbidden("You don't have access to this region.")

    return region.to_dict() | {'_href': _region_href(region)}
예제 #6
0
def list_product_regions(keycloak: KeycloakClient,
                         product_id,
                         user,
                         filter_,
                         page=0,
                         limit=DEFAULT_PAGE_LIMIT):
    product = model.Product.query.get(product_id)
    if not product:
        return problem(404, 'Not Found',
                       f'Product {product_id} does not exist')

    regions_relation = product.regions_relation

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        user_groups = [group['id'] for group in keycloak.user_group_list(user)]
        regions_relation = regions_relation.filter(
            sqlalchemy.or_(
                model.Region.users_group.is_(None),
                model.Region.users_group.in_(user_groups),
                model.Region.owner_group.in_(user_groups),
            ))

    if 'name' in filter_:
        regions_relation = regions_relation.filter(
            model.Region.name.ilike(filter_['name']), )

    if 'location' in filter_:
        regions_relation = regions_relation.filter(
            model.Region.location.ilike(filter_['location']), )

    if 'enabled' in filter_:
        regions_relation = regions_relation.filter(
            sqlalchemy.and_(
                model.RegionProduct.enabled == filter_['enabled'],
                model.Region.enabled == filter_['enabled'],
            ))

    if 'reservations_enabled' in filter_:
        regions_relation = regions_relation.filter(
            model.Region.reservations_enabled ==
            filter_['reservations_enabled'], )

    return [{
        'id': r.region_id,
        'region': r.region.to_dict(),
        'enabled': r.enabled
    } for r in regions_relation]
예제 #7
0
def list_regions(keycloak: KeycloakClient,
                 user,
                 filter_,
                 sort=None,
                 page=0,
                 limit=DEFAULT_PAGE_LIMIT):
    if keycloak.user_check_role(user, ADMIN_ROLE):
        regions = model.Region.query
    else:
        user_groups = [group['id'] for group in keycloak.user_group_list(user)]
        regions = model.Region.query.filter(
            sqlalchemy.or_(
                model.Region.users_group.is_(None),
                model.Region.users_group.in_(user_groups),
                model.Region.owner_group.in_(user_groups),
            ))

    if 'name' in filter_:
        regions = regions.filter(model.Region.name.ilike(filter_['name']))

    if 'location' in filter_:
        regions = regions.filter(
            model.Region.location.ilike(filter_['location']))

    if 'enabled' in filter_:
        regions = regions.filter(model.Region.enabled == filter_['enabled'])

    if 'reservations_enabled' in filter_:
        regions = regions.filter(model.Region.reservations_enabled ==
                                 filter_['reservations_enabled'])

    if sort:
        regions = db_sort(regions, sort)

    return {
        'data': [
            region.to_dict() | {
                '_href': _region_href(region)
            } for region in regions.limit(limit).offset(page * limit)
        ],
        'total':
        regions.count(),
    }
예제 #8
0
def delete_region_product(keycloak: KeycloakClient, region_id, user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        if not keycloak.user_check_group(user, region.owner_group):
            raise Forbidden("You don't have write access to this region.")

    product = model.Product.query.get(request.json['id'])
    if not product:
        return problem(404, 'Not Found',
                       f'Product {request.json["id"]} does not exist')

    q = model.RegionProduct.query.filter(
        sqlalchemy.and_(
            model.RegionProduct.region_id == region.id,
            model.RegionProduct.product_id == product.id,
        ))
    if q.count() > 0:
        for relation in q.all():
            db.session.delete(relation)
        db.session.commit()