Skip to content

Commit

Permalink
Use traefik_route v0 library from traefik-k8s (#348)
Browse files Browse the repository at this point in the history
* use traefik_route from traefik-k8s

* pin scenario
  • Loading branch information
michaeldmitry authored Sep 19, 2024
1 parent 1c80f74 commit 124e9c2
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
```shell
cd some-charm
charmcraft fetch-lib charms.traefik_route_k8s.v0.traefik_route
charmcraft fetch-lib charms.traefik_k8s.v0.traefik_route
```
To use the library from the provider side (Traefik):
Expand All @@ -28,7 +28,7 @@
```
```python
from charms.traefik_route_k8s.v0.traefik_route import TraefikRouteProvider
from charms.traefik_k8s.v0.traefik_route import TraefikRouteProvider
class TraefikCharm(CharmBase):
def __init__(self, *args):
Expand Down Expand Up @@ -56,7 +56,7 @@ def _handle_traefik_route_ready(self, event):
```python
# ...
from charms.traefik_route_k8s.v0.traefik_route import TraefikRouteRequirer
from charms.traefik_k8s.v0.traefik_route import TraefikRouteRequirer
class TraefikRouteCharm(CharmBase):
def __init__(self, *args):
Expand All @@ -81,14 +81,14 @@ def __init__(self, *args):
from ops.model import Relation

# The unique Charmhub library identifier, never change it
LIBID = "fe2ac43a373949f2bf61383b9f35c83c"
LIBID = "f0d93d2bdf354b99a527463a9c49fce3"

# Increment this major API version when introducing breaking changes
LIBAPI = 0

# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 9
LIBPATCH = 1

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -243,29 +243,43 @@ def update_traefik_address(
self._stored.external_host = external_host
self._stored.scheme = scheme

@staticmethod
def is_ready(relation: Relation) -> bool:
def is_ready(self, relation: Relation) -> bool:
"""Whether TraefikRoute is ready on this relation.
Returns True when the remote app shared the config; False otherwise.
"""
assert relation.app is not None # not currently handled anyway
if not relation.app or not relation.data[relation.app]:
return False
return "config" in relation.data[relation.app]

@staticmethod
def get_config(relation: Relation) -> Optional[str]:
"""Retrieve the config published by the remote application."""
# TODO: validate this config
assert relation.app is not None # not currently handled anyway
def get_config(self, relation: Relation) -> Optional[str]:
"""Renamed to ``get_dynamic_config``."""
log.warning(
"``TraefikRouteProvider.get_config`` is deprecated. "
"Use ``TraefikRouteProvider.get_dynamic_config`` instead"
)
return self.get_dynamic_config(relation)

def get_dynamic_config(self, relation: Relation) -> Optional[str]:
"""Retrieve the dynamic config published by the remote application."""
if not self.is_ready(relation):
return None
return relation.data[relation.app].get("config")

def get_static_config(self, relation: Relation) -> Optional[str]:
"""Retrieve the static config published by the remote application."""
if not self.is_ready(relation):
return None
return relation.data[relation.app].get("static")


class TraefikRouteRequirer(Object):
"""Wrapper for the requirer side of traefik-route.
The traefik_route requirer will publish to the application databag an object like:
{
'config': <Traefik_config>
'static': <Traefik_config> # optional
}
NB: TraefikRouteRequirer does no validation; it assumes that the
Expand Down Expand Up @@ -344,11 +358,15 @@ def is_ready(self) -> bool:
"""Is the TraefikRouteRequirer ready to submit data to Traefik?"""
return self._relation is not None

def submit_to_traefik(self, config):
def submit_to_traefik(self, config: dict, static: Optional[dict] = None):
"""Relay an ingress configuration data structure to traefik.
This will publish to TraefikRoute's traefik-route relation databag
the config traefik needs to route the units behind this charm.
This will publish to the traefik-route relation databag
a chunk of Traefik dynamic config that the traefik charm on the other end can pick
up and apply.
Use ``static`` if you need to update traefik's **static** configuration.
Note that this will force traefik to restart to comply.
"""
if not self._charm.unit.is_leader():
raise UnauthorizedError()
Expand All @@ -357,3 +375,6 @@ def submit_to_traefik(self, config):

# Traefik thrives on yaml, feels pointless to talk json to Route
app_databag["config"] = yaml.safe_dump(config)

if static:
app_databag["static"] = yaml.safe_dump(static)
2 changes: 1 addition & 1 deletion src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
CertificateTransferRequires,
)
from charms.prometheus_k8s.v0.prometheus_scrape import MetricsEndpointProvider
from charms.traefik_route_k8s.v0.traefik_route import TraefikRouteRequirer
from charms.traefik_k8s.v0.traefik_route import TraefikRouteRequirer
from ops.charm import (
ActionEvent,
CharmBase,
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_external_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from unittest.mock import MagicMock, patch

import ops
from charms.traefik_route_k8s.v0.traefik_route import TraefikRouteRequirer
from charms.traefik_k8s.v0.traefik_route import TraefikRouteRequirer
from ops.model import ActiveStatus
from ops.testing import Harness

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ deps =
pytest<8.2.0 # https://github.com/pytest-dev/pytest/issues/12263
responses
cosl
ops-scenario==6
ops-scenario<7.0.0
-r{toxinidir}/requirements.txt
commands =
/usr/bin/env sh -c 'stat sqlite-static > /dev/null 2>&1 || curl -L https://github.com/CompuRoot/static-sqlite3/releases/latest/download/sqlite3 -o sqlite-static && chmod +x sqlite-static'
Expand Down

0 comments on commit 124e9c2

Please sign in to comment.