Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Swagger UI for indexer is a stub (#5051, #5228) #5160

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
# to `docker run` and bind-mount an /etc/passwd that maps that to `developer`.
# We also need write permissions for the group
chmod -R g+w . && sudo chgrp -R 1000 . && make format && sudo chgrp -R $(id -g) .
make openapi
make -C lambdas openapi
make check_clean
make pep8
AZUL_DEBUG=0 GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} make test
Expand Down
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ test:
script:
- make format # Any ill-formatted sources, ...
- test "$azul_is_sandbox" = 1 && make requirements_update # ... stale transitive dependencies ...
- make openapi # ... or changes to the canned OpenAPI definition document ...
- make -C lambdas openapi # ... or changes to the canned OpenAPI definition document ...
- make check_clean # would dirty up the working copy and fail the build.
- make pep8
- AZUL_DEBUG=0 make test
Expand Down
4 changes: 0 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,3 @@ integration_test: check_python check_branch $(project_root)/lambdas/service/.cha
.PHONY: check_clean
check_clean: check_env
git diff --exit-code && git diff --cached --exit-code

.PHONY: openapi
openapi:
python $(project_root)/scripts/generate_openapi_document.py
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2384,7 +2384,7 @@ Changes to the OpenAPI definition are tracked in the source tree. When making
changes that affect the definition, run:

```
make openapi
make -C lambdas openapi
```

and commit any modifications to the `openapi.json` file. Failure to do so will
Expand Down
6 changes: 5 additions & 1 deletion lambdas/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ service: check_env

.PHONY: clean
clean: check_env
for d in indexer service layer; do $(MAKE) -C $$d clean; done
for d in indexer service layer; do $(MAKE) -C $$d clean || ! break; done

.PHONY: openapi
openapi: check_env
for d in indexer service; do $(MAKE) -C $$d openapi || ! break; done
102 changes: 91 additions & 11 deletions lambdas/indexer/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
SignatureHelper,
)
from azul.indexer.index_controller import (
Action,
IndexController,
)
from azul.indexer.log_forwarding_controller import (
Expand All @@ -38,6 +39,14 @@
)
from azul.openapi import (
format_description,
params,
schema,
)
from azul.openapi.responses import (
json_content,
)
from azul.openapi.spec import (
CommonEndpointSpecs,
)

log = logging.getLogger(__name__)
Expand All @@ -46,10 +55,8 @@
'openapi': '3.0.1',
'info': {
'title': config.indexer_name,
# FIXME: Swagger UI for indexer is a stub
# https://github.com/DataBiosphere/azul/issues/5051
'description': format_description('''
This is the indexer component for Azul.
This is the internal API for Azul's indexer component.
'''),
'version': '1.0'
}
Expand Down Expand Up @@ -103,14 +110,17 @@ def static_resource(file):
return app.swagger_resource(file)


@app.route('/openapi', methods=['GET'], cors=True)
common_specs = CommonEndpointSpecs(app_name='indexer')


@app.route('/openapi', methods=['GET'], cors=True, **common_specs.openapi)
def openapi():
return Response(status_code=200,
headers={'content-type': 'application/json'},
body=app.spec())


@app.route('/version', methods=['GET'], cors=True)
@app.route('/version', methods=['GET'], cors=True, **common_specs.version)
def version():
from azul.changelog import (
compact_changes,
Expand All @@ -121,27 +131,39 @@ def version():
}


@app.route('/health', methods=['GET'], cors=True)
@app.route('/health', methods=['GET'], cors=True, **common_specs.full_health)
def health():
return app.health_controller.health()


@app.route('/health/basic', methods=['GET'], cors=True)
@app.route('/health/basic',
methods=['GET'],
cors=True,
**common_specs.basic_health)
def basic_health():
return app.health_controller.basic_health()


@app.route('/health/cached', methods=['GET'], cors=True)
@app.route('/health/cached',
methods=['GET'],
cors=True,
**common_specs.cached_health)
def cached_health():
return app.health_controller.cached_health()


@app.route('/health/fast', methods=['GET'], cors=True)
@app.route('/health/fast',
methods=['GET'],
cors=True,
**common_specs.fast_health)
def fast_health():
return app.health_controller.fast_health()


@app.route('/health/{keys}', methods=['GET'], cors=True)
@app.route('/health/{keys}',
methods=['GET'],
cors=True,
**common_specs.custom_health)
def health_by_key(keys: Optional[str] = None):
return app.health_controller.custom_health(keys)

Expand All @@ -151,7 +173,65 @@ def update_health_cache(_event: chalice.app.CloudWatchEvent):
app.health_controller.update_cache()


@app.route('/{catalog}/{action}', methods=['POST'])
@app.route('/{catalog}/{action}', methods=['POST'], method_spec={
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should mention the HMAC header and briefly explain how to compute it.

'tags': ['Indexing'],
'summary': 'Notify the indexer to perform an action on a bundle',
'description': format_description('''
Queue a bundle for addition to or deletion from the index.

The request must be authenticated using HMAC via the ``signature``
header. Each Azul deployment has its own unique HMAC key. The HMAC
components are the request method, request path, and the SHA256 digest
of the request body.

A valid HMAC header proves that the client is in possession of the
secret HMAC key and that the request wasn't tampered with while
travelling between client and service, even though the latter is not
strictly necessary considering that TLS is used to encrypt the entire
exchange. Internal clients can obtain the secret key from the
environment they are running in, and that they share with the service.
External clients must have been given the secret key. The now-defunct
DSS was such an external client. The Azul indexer provided the HMAC
secret to DSS when it registered with DSS to be notified about bundle
additions/deletions. These days only internal clients use this endpoint.
'''),
'requestBody': {
'description': 'Contents of the notification',
'required': True,
**json_content(schema.object(
bundle_fqid=schema.object(
uuid=str,
version=str,
source=schema.object(
id=str,
spec=str
)
)
))
},
'parameters': [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought there was a way to declare headers in Swagger. If that is correct it should be used to document the HMAC header.

params.path('catalog',
schema.enum(*config.catalogs),
description='The name of the catalog to notify.'),
params.path('action',
schema.enum(Action.add.name, Action.delete.name),
description='Which action to perform.'),
params.header('signature',
str,
description='HMAC authentication signature.')
],
'responses': {
'200': {
'description': 'Notification was successfully queued for processing'
},
'400': {
'description': 'Request was rejected due to malformed parameters'
},
'401': {
'description': 'Request lacked a valid HMAC header'
}
}
})
def post_notification(catalog: CatalogName, action: str):
"""
Receive a notification event and queue it for indexing or deletion.
Expand Down
Loading