Skip to content

Commit

Permalink
Merge pull request #886 from lsst-sqre/tickets/DM-41186
Browse files Browse the repository at this point in the history
DM-41186: Prepare 9.5.0 release
  • Loading branch information
rra committed Oct 25, 2023
2 parents 96428d3 + edab2af commit 011d93f
Show file tree
Hide file tree
Showing 12 changed files with 1,558 additions and 1,463 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ repos:
rev: 1.16.0
hooks:
- id: blacken-docs
additional_dependencies: [black==23.9.1]
additional_dependencies: [black==23.10.0]
args: [-l, '79', -t, py311]

- repo: https://github.com/pre-commit/mirrors-eslint
Expand All @@ -33,7 +33,7 @@ repos:
additional_dependencies:
- '@babel/eslint-parser@7.22.15'
- '@babel/preset-react@7.22.15'
- eslint@8.49.0
- eslint@8.52.0
- eslint-config-airbnb@19.0.4
- eslint-config-prettier@9.0.0
- eslint-config-wesbos@3.2.3
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ Find changes for the upcoming release in the project's [changelog.d directory](h

<!-- scriv-insert-here -->

<a id='changelog-9.5.0'></a>
## 9.5.0 (2023-10-25)

### New features

- Add new `/auth/cadc/userinfo` route, which accepts a Gafaelfawr token and returns user metadata in the format expected by the CADC authentication code. This route is expected to be temporary and will be moved into the main token API once we decide how to handle uniqueness of the `sub` claim. It is therefore not currently documented outside of the autogenerated API documentation.
- Gafaelfawr now imposes a maximum run time and retention duration for its periodic maintenance jobs. These can be adjusted with the new `config.maintenance.deadlineSeconds` and `config.maintenance.cleanupSeconds` Helm settings.
- All Gafaelfawr pods now set Kubernetes resource requests and limits. The requests match the consumption of a lightly-loaded deployment using OpenID Connect and LDAP, and the limits should be generous. These can be adjusted using Helm chart values.

### Bug fixes

- Log exceptions encountered while parsing OpenID Connect responses from upstream providers, not just the deduced error message. Include the body of the response from the token endpoint if it could not be parsed as JSON.

### Other changes

- Include curl in the Gafaelfawr container for manual debugging of web request problems.

<a id='changelog-9.4.0'></a>
## 9.4.0 (2023-10-03)

Expand Down
3 changes: 0 additions & 3 deletions changelog.d/20231006_082903_rra_DM_41075.md

This file was deleted.

3 changes: 0 additions & 3 deletions changelog.d/20231006_083302_rra_DM_41075.md

This file was deleted.

4 changes: 0 additions & 4 deletions changelog.d/20231006_141539_rra_DM_41090.md

This file was deleted.

3 changes: 0 additions & 3 deletions changelog.d/20231013_131313_rra_DM_41186.md

This file was deleted.

1,094 changes: 547 additions & 547 deletions requirements/dev.txt

Large diffs are not rendered by default.

1,080 changes: 571 additions & 509 deletions requirements/main.txt

Large diffs are not rendered by default.

43 changes: 28 additions & 15 deletions src/gafaelfawr/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from __future__ import annotations

import os
from collections.abc import AsyncIterator, Coroutine
from contextlib import asynccontextmanager
from importlib.metadata import version
from pathlib import Path

Expand Down Expand Up @@ -31,7 +33,11 @@
__all__ = ["create_app"]


def create_app(*, load_config: bool = True) -> FastAPI:
def create_app(
*,
load_config: bool = True,
extra_startup: Coroutine[None, None, None] | None = None,
) -> FastAPI:
"""Create the FastAPI application.
This is in a function rather than using a global variable (as is more
Expand All @@ -46,7 +52,27 @@ def create_app(*, load_config: bool = True) -> FastAPI:
set of proxy IP addresses. This is used primarily for OpenAPI
schema generation, where constructing the app is required but the
configuration won't matter.
extra_startup
If provided, an additional coroutine to run as part of the startup
section of the lifespan context manager, used by the test suite.
"""

@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
config = config_dependency.config()
await context_dependency.initialize(config)
await db_session_dependency.initialize(
config.database_url, config.database_password
)
if extra_startup:
await extra_startup

yield

await http_client_dependency.aclose()
await db_session_dependency.aclose()
await context_dependency.aclose()

app = FastAPI(
title="Gafaelfawr",
description=(
Expand Down Expand Up @@ -83,6 +109,7 @@ def create_app(*, load_config: bool = True) -> FastAPI:
openapi_url="/auth/openapi.json",
docs_url="/auth/docs",
redoc_url="/auth/redoc",
lifespan=lifespan,
)

# Add all of the routes.
Expand Down Expand Up @@ -143,20 +170,6 @@ def create_app(*, load_config: bool = True) -> FastAPI:
# Handle exceptions descended from ClientRequestError.
app.exception_handler(ClientRequestError)(client_request_error_handler)

@app.on_event("startup")
async def startup_event() -> None:
config = config_dependency.config()
await context_dependency.initialize(config)
await db_session_dependency.initialize(
config.database_url, config.database_password
)

@app.on_event("shutdown")
async def shutdown_event() -> None:
await http_client_dependency.aclose()
await db_session_dependency.aclose()
await context_dependency.aclose()

# This is a temporary workaround for a bug in FastAPI handling Pydantic
# validation errors when a list query parameter is not specified. See
# https://github.com/tiangolo/fastapi/issues/9920
Expand Down
3 changes: 3 additions & 0 deletions tests/support/firestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ class MockTransaction(MagicMock):

def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(spec=firestore.AsyncTransaction, **kwargs)

# Used internally by Firestore and thus must be set in the mock.
self._id = None
self._max_attempts = 1
self._read_only = False

def create(self, ref: MockDocumentRef, data: dict[str, Any]) -> None:
assert ref.document is None
Expand Down
6 changes: 2 additions & 4 deletions tests/support/selenium.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,12 @@ def selenium_create_app() -> FastAPI:
be called by uvicorn in the separate process spawned by run_app. If it is
run in the main pytest process, it will break other tests.
"""
app = create_app()
token_path = Path(os.environ["GAFAELFAWR_TEST_TOKEN_PATH"])

@app.on_event("startup")
async def selenium_startup_event() -> None:
async def selenium_startup() -> None:
await _selenium_startup(token_path)

return app
return create_app(extra_startup=selenium_startup())


@asynccontextmanager
Expand Down

0 comments on commit 011d93f

Please sign in to comment.