Skip to content

Commit

Permalink
feat(metrics): use basic auth instead of api token
Browse files Browse the repository at this point in the history
  • Loading branch information
rwxd committed Feb 9, 2024
1 parent 96ebc5b commit 5d2fa25
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 13 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,18 @@ metrics_require_auth: false # default is true

When the `metrics_proxy` option is set to `true`, the environment has access to the `/metrics` endpoint of the proxy.

That is needed, when the `metrics_require_auth` option is set to `true` (default).

```yaml
...
environments:
- name: "Test1"
metrics_proxy: true
```

When `metrics_require_auth` is enabled, basic auth needs to be used.

* username: name of the environment
* password: token

#### Metrics

The [prometheus-fastapi-instrumentator](https://github.com/trallnag/prometheus-fastapi-instrumentator) is used for the default metrics.
Expand Down
21 changes: 16 additions & 5 deletions powerdns_api_proxy/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import os
from functools import lru_cache
from pathlib import Path
from typing import Optional
from typing import Annotated, Optional

from fastapi import Header, HTTPException
from fastapi import Depends, Header, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from yaml import safe_load

from powerdns_api_proxy.logging import logger
Expand Down Expand Up @@ -58,15 +59,25 @@ def dependency_check_token_defined(
check_token_defined(load_config(), X_API_Key)


security = HTTPBasic()


def dependency_metrics_proxy_enabled(
X_API_Key: str = Header(description='API Key for the proxy.'),
credentials: Annotated[HTTPBasicCredentials, Depends(security)] = Header(
description='API Key for the proxy.'
),
):
username = credentials.username
password = credentials.password

try:
environment = get_environment_for_token(load_config(), X_API_Key)
environment = get_environment_for_token(load_config(), password)
if not environment.name == username:
raise NotAuthorizedException()
if not environment.metrics_proxy:
raise MetricsNotAllowedException()
except ValueError:
raise MetricsNotAllowedException()
raise NotAuthorizedException()


def get_environment_for_token(
Expand Down
2 changes: 1 addition & 1 deletion powerdns_api_proxy/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def __init__(self):
class NotAuthorizedException(HTTPException):
def __init__(self):
self.status_code = 401
self.detail = 'Not authorized'
self.detail = 'Unauthorized'


class SearchNotAllowedException(HTTPException):
Expand Down
6 changes: 1 addition & 5 deletions powerdns_api_proxy/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,7 @@ async def _startup(app: FastAPI):
if config.metrics_require_auth:
logger.info('Enabling metrics authentication')
instrumentator.expose(
app,
dependencies=[
Depends(dependency_check_token_defined),
Depends(dependency_metrics_proxy_enabled),
],
app, dependencies=[Depends(dependency_metrics_proxy_enabled)]
)
else:
instrumentator.expose(app)
Expand Down

0 comments on commit 5d2fa25

Please sign in to comment.