Skip to content

Commit

Permalink
Adding filtering builds based on from_index
Browse files Browse the repository at this point in the history
CLOUDDST-18396
  • Loading branch information
lipoja committed May 3, 2023
1 parent 3a6bfeb commit cd0cf99
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 24 deletions.
67 changes: 43 additions & 24 deletions iib/web/api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ def get_builds() -> flask.Response:
request_type = flask.request.args.get('request_type')
user = flask.request.args.get('user')
index_image = flask.request.args.get('index_image')

from_index = flask.request.args.get('from_index')
query_params = {}

# Create an alias class to load the polymorphic classes
Expand Down Expand Up @@ -397,35 +397,57 @@ def get_builds() -> flask.Response:
query_params['user'] = user
query = query.join(Request.user).filter(User.username == user)

if index_image:
if index_image or from_index:
# https://sqlalche.me/e/20/xaj2 - Create aliases for self-join (Sqlalchemy 2.0)
request_create_empty_index_alias = aliased(RequestCreateEmptyIndex, flat=True)
request_add_alias = aliased(RequestAdd, flat=True)
request_rm_alias = aliased(RequestRm, flat=True)
request_merge_index_image_alias = aliased(RequestMergeIndexImage, flat=True)
request_fbc_operations_alias = aliased(RequestFbcOperations, flat=True)

query_params['index_image'] = index_image
# Get the image id of the image to be searched
image_result = Image.query.filter_by(pull_specification=index_image).first()
if image_result:
# join with the Request* tables to get the response as image_ids are stored there
query = (
query.outerjoin(
request_create_empty_index_alias,
Request.id == request_create_empty_index_alias.id,
)
.outerjoin(request_add_alias, Request.id == request_add_alias.id)
.outerjoin(
request_merge_index_image_alias,
Request.id == request_merge_index_image_alias.id,
)
.outerjoin(request_rm_alias, Request.id == request_rm_alias.id)
.outerjoin(
request_fbc_operations_alias, Request.id == request_fbc_operations_alias.id
# join with the Request* tables to get the response as image_ids are stored there
query = (
query.outerjoin(
request_create_empty_index_alias,
Request.id == request_create_empty_index_alias.id,
)
.outerjoin(request_add_alias, Request.id == request_add_alias.id)
.outerjoin(request_rm_alias, Request.id == request_rm_alias.id)
.outerjoin(request_fbc_operations_alias, Request.id == request_fbc_operations_alias.id)
)

if from_index:
query_params['from_index'] = from_index
# Get the image id of the image to be searched
from_index_result = Image.query.filter_by(pull_specification=from_index).first()
if not from_index_result:
# if from_index is not found in image table, then raise an error
raise ValidationError(f'from_index {from_index} is not a valid index image')

query = query.filter(
or_(
request_create_empty_index_alias.from_index_id == from_index_result.id,
request_add_alias.from_index_id == from_index_result.id,
request_rm_alias.from_index_id == from_index_result.id,
request_fbc_operations_alias.from_index_id == from_index_result.id,
)
)

if index_image:
# Get the image id of the image to be searched for
image_result = Image.query.filter_by(pull_specification=index_image).first()
if not image_result:
# if index_image is not found in image table, then raise an error
raise ValidationError(f'{index_image} is not a valid index image')

request_merge_index_image_alias = aliased(RequestMergeIndexImage, flat=True)
query_params['index_image'] = index_image

# join with the Request* tables to get the response as image_ids are stored there
query = query.outerjoin(
request_merge_index_image_alias,
Request.id == request_merge_index_image_alias.id,
)

query = query.filter(
or_(
request_create_empty_index_alias.index_image_id == image_result.id,
Expand All @@ -435,9 +457,6 @@ def get_builds() -> flask.Response:
request_fbc_operations_alias.index_image_id == image_result.id,
)
)
# if index_image is not found in image table, then raise an error
else:
raise ValidationError(f'{index_image} is not a valid index image')

pagination_query = query.order_by(Request.id.desc()).paginate(max_per_page=max_per_page)
requests = pagination_query.items
Expand Down
38 changes: 38 additions & 0 deletions tests/test_web/test_api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,44 @@ def test_index_image_filter(
assert rv.json == {'error': ('quay.io/namespace/index@sha256:abc is not a valid index image')}


def _request_add_state_and_from_index(minimal_request, image_pull_spec):
minimal_request.add_state('in_progress', 'Starting things up!')
minimal_request.from_index = Image.get_or_create(image_pull_spec)
minimal_request.add_state('complete', 'The request is complete')


def test_from_index_filter(
app, client, db, minimal_request_add, minimal_request_rm, minimal_request_fbc_operations
):
_request_add_state_and_from_index(
minimal_request_add, 'quay.io/namespace/index@sha256:from_index'
)
_request_add_state_and_from_index(
minimal_request_rm, 'quay.io/namespace/from_index@sha256:123456'
)
_request_add_state_and_from_index(
minimal_request_fbc_operations,
'quay.io/namespace/from_index@sha256:fbcop',
)
db.session.commit()

rv_json = client.get('/api/v1/builds?from_index=quay.io/namespace/index@sha256:from_index').json
assert rv_json['meta']['total'] == 1

rv_json = client.get(
'/api/v1/builds?from_index=quay.io/namespace/from_index@sha256:123456'
).json
assert rv_json['meta']['total'] == 1

rv_json = client.get('/api/v1/builds?from_index=quay.io/namespace/from_index@sha256:fbcop').json
assert rv_json['meta']['total'] == 1

rv = client.get('/api/v1/builds?from_index=quay.io/namespace/index@sha256:abc')
assert rv.json == {
'error': 'from_index quay.io/namespace/index@sha256:abc is not a valid index image'
}


def test_get_builds_invalid_state(app, client, db):
rv = client.get('/api/v1/builds?state=is_it_lunch_yet%3F')
assert rv.status_code == 400
Expand Down

0 comments on commit cd0cf99

Please sign in to comment.