Skip to content

Commit

Permalink
fix: use internal ingress if set, otherwise stick with k8s networking
Browse files Browse the repository at this point in the history
  • Loading branch information
shipperizer committed Jul 3, 2024
1 parent 6da9fa5 commit 0688ca8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 14 deletions.
26 changes: 14 additions & 12 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,15 @@ def __init__(self, *args: Any) -> None:
self.framework.observe(self.tracing.on.endpoint_removed, self._on_config_changed)

self.framework.observe(
self.on[INTERNAL_INGRESS_RELATION_NAME].relation_joined, self._configure_ingress
self.on[INTERNAL_INGRESS_RELATION_NAME].relation_joined,
self._configure_internal_ingress,
)
self.framework.observe(
self.on[INTERNAL_INGRESS_RELATION_NAME].relation_changed, self._configure_ingress
self.on[INTERNAL_INGRESS_RELATION_NAME].relation_changed,
self._configure_internal_ingress,
)
self.framework.observe(self.on.leader_elected, self._configure_ingress)
self.framework.observe(self.on.config_changed, self._configure_ingress)
self.framework.observe(self.on.leader_elected, self._configure_internal_ingress)
self.framework.observe(self.on.config_changed, self._configure_internal_ingress)

@property
def _http_proxy(self) -> str:
Expand Down Expand Up @@ -454,18 +456,14 @@ def _internal_ingress_config(self) -> dict:
@property
def _kratos_endpoints(self) -> Tuple[str, str]:
admin_endpoint = (
self._admin_url
self._internal_url
or f"http://{self.app.name}.{self.model.name}.svc.cluster.local:{KRATOS_ADMIN_PORT}"
)
public_endpoint = (
self._public_url
self._internal_url
or f"http://{self.app.name}.{self.model.name}.svc.cluster.local:{KRATOS_PUBLIC_PORT}"
)

admin_endpoint, public_endpoint = (
admin_endpoint.replace("https", "http"),
public_endpoint.replace("https", "http"),
)
return admin_endpoint, public_endpoint

@property
Expand Down Expand Up @@ -1193,8 +1191,10 @@ def _on_run_migration_action(self, event: ActionEvent) -> None:
def _promtail_error(self, event: PromtailDigestError) -> None:
logger.error(event.message)

def _configure_ingress(self, event: HookEvent) -> None:
"""Since :class:`TraefikRouteRequirer` may not have been constructed with an existing
def _configure_internal_ingress(self, event: HookEvent) -> None:
"""Method setting up the internal networking.
Since :class:`TraefikRouteRequirer` may not have been constructed with an existing
relation if a :class:`RelationJoinedEvent` comes through during the charm lifecycle, if we
get one here, we should recreate it, but OF will give us grief about "two objects claiming
to be ...", so manipulate its private `_relation` variable instead.
Expand All @@ -1214,6 +1214,8 @@ def _configure_ingress(self, event: HookEvent) -> None:
# and config-change
if self.internal_ingress.is_ready():
self.internal_ingress.submit_to_traefik(self._internal_ingress_config)
self._update_kratos_endpoints_relation_data(event)
self._update_kratos_info_relation_data(event)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion src/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Copyright 2023 Canonical Ltd.
# See LICENSE file for licensing details.

"""File contianing all constants"""
"""File containing all constants."""

INTERNAL_INGRESS_RELATION_NAME = "internal-ingress"
3 changes: 3 additions & 0 deletions src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ def normalise_url(url: str) -> str:
"""
parsed_url = urlparse(url)

# latest versions of traefik automatically redirect to https if ceritficate relation is
# set, this would void the changes below as even a request to the http url would be redirected
# make sure to disable the certificate relation for the internal ingress or trust that certificate
parsed_url = parsed_url._replace(scheme="https")
parsed_url = parsed_url._replace(netloc=parsed_url.netloc.rsplit(":", 1)[0])

Expand Down
24 changes: 23 additions & 1 deletion tests/integration/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
DB_APP = "postgresql-k8s"
TRAEFIK_CHARM = "traefik-k8s"
TRAEFIK_ADMIN_APP = "traefik-admin"
# drop internal app as soon ad admin-ingress is removed
TRAEFIK_INTERNAL_APP = "traefik-internal"
TRAEFIK_PUBLIC_APP = "traefik-public"
ADMIN_MAIL = "admin1@adminmail.com"
IDENTITY_SCHEMA = {
Expand Down Expand Up @@ -96,11 +98,18 @@ async def test_ingress_relation(ops_test: OpsTest) -> None:
channel="latest/edge",
config={"external_hostname": "some_hostname"},
)
await ops_test.model.deploy(
TRAEFIK_CHARM,
application_name=TRAEFIK_INTERNAL_APP,
channel="latest/edge",
config={"external_hostname": "some_hostname"},
)
await ops_test.model.integrate(f"{KRATOS_APP}:admin-ingress", TRAEFIK_ADMIN_APP)
await ops_test.model.integrate(f"{KRATOS_APP}:internal-ingress", TRAEFIK_INTERNAL_APP)
await ops_test.model.integrate(f"{KRATOS_APP}:public-ingress", TRAEFIK_PUBLIC_APP)

await ops_test.model.wait_for_idle(
apps=[TRAEFIK_PUBLIC_APP, TRAEFIK_ADMIN_APP],
apps=[TRAEFIK_PUBLIC_APP, TRAEFIK_ADMIN_APP, TRAEFIK_INTERNAL_APP],
status="active",
raise_on_blocked=True,
timeout=1000,
Expand Down Expand Up @@ -128,6 +137,19 @@ async def test_has_admin_ingress(ops_test: OpsTest) -> None:

assert resp.status_code == 200

async def test_has_internal_ingress(ops_test: OpsTest) -> None:
# Get the traefik address and try to reach kratos
internal_address = await get_unit_address(ops_test, TRAEFIK_INTERNAL_APP, 0)

# test admin endpoint
assert requests.get(
f"http://{internal_address}/{ops_test.model.name}-{KRATOS_APP}/admin/identities"
).status_code == 200
# test public endpoint
assert requests.get(
f"http://{internal_address}/{ops_test.model.name}-{KRATOS_APP}/sessions"
).status_code == 200


@pytest.mark.abort_on_fail
async def test_create_admin_account(ops_test: OpsTest) -> None:
Expand Down

0 comments on commit 0688ca8

Please sign in to comment.