Skip to content

Commit

Permalink
Block if hostname is invalid (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
sed-i authored Aug 29, 2022
1 parent d80dab2 commit 5bd328b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import logging
import typing
from typing import Tuple, Union
from urllib.parse import urlparse

import yaml
from charms.observability_libs.v0.kubernetes_service_patch import KubernetesServicePatch
Expand Down Expand Up @@ -262,12 +263,26 @@ def _process_status_and_configurations(self):
)
return

if not self._external_host:
hostname = self._external_host

if not hostname:
self.unit.status = MaintenanceStatus("resetting ingress relations")
self._wipe_ingress_for_all_relations()
self.unit.status = WaitingStatus("gateway address unavailable")
return

if hostname != urlparse(f"scheme://{hostname}").hostname:
self.unit.status = MaintenanceStatus("resetting ingress relations")
self._wipe_ingress_for_all_relations()
self.unit.status = BlockedStatus(f"invalid hostname: {hostname}; see logs.")

logger.error(
"'%s' is not a valid hostname value; "
"hostname must not include port or any other netloc components",
hostname,
)
return

if not self._traefik_service_running:
self.unit.status = WaitingStatus(f"waiting for service: '{_TRAEFIK_SERVICE_NAME}'")
return
Expand Down
42 changes: 42 additions & 0 deletions tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,3 +563,45 @@ def test_tcp_config(self):

static_config = charm.unit.get_container("traefik").pull(_STATIC_CONFIG_PATH).read()
assert yaml.safe_load(static_config)["entryPoints"][prefix] == expected_entrypoint


class TestConfigOptionsValidation(unittest.TestCase):
@patch("charm._get_loadbalancer_status", lambda **_: "10.0.0.1")
@patch("charm.KubernetesServicePatch", lambda **_: None)
def setUp(self):
self.harness: Harness[TraefikIngressCharm] = Harness(TraefikIngressCharm)
self.harness.set_model_name("test-model")
self.addCleanup(self.harness.cleanup)

self.harness.set_leader(True)
self.harness.begin_with_initial_hooks()
self.harness.container_pebble_ready("traefik")

self.relation = relate(self.harness)
_requirer_provide_ingress_requirements(
harness=self.harness, relation=self.relation, host="10.1.10.1", port=9000
)

@patch("charm._get_loadbalancer_status", lambda **_: "10.0.0.1")
@patch("charm.KubernetesServicePatch", lambda **_: None)
def test_when_external_hostname_not_set_use_ip_with_port_80(self):
self.assertEqual(requirer.urls, {"remote/0": "http://10.0.0.1:80/test-model-remote-0"})

@patch("charm._get_loadbalancer_status", lambda **_: "10.0.0.1")
@patch("charm.KubernetesServicePatch", lambda **_: None)
def test_when_external_hostname_is_set_use_it_with_port_80(self):
self.harness.update_config({"external_hostname": "testhostname"})
self.assertEqual(requirer.urls, {"remote/0": "http://testhostname:80/test-model-remote-0"})

@patch("charm._get_loadbalancer_status", lambda **_: "10.0.0.1")
@patch("charm.KubernetesServicePatch", lambda **_: None)
def test_when_external_hostname_is_invalid_go_into_blocked_status(self):
for invalid_hostname in [
"testhostname:8080",
"user:pass@testhostname",
"testhostname/prefix",
]:
with self.subTest(invalid_hostname=invalid_hostname):
self.harness.update_config({"external_hostname": invalid_hostname})
self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
self.assertEqual(requirer.urls, {})

0 comments on commit 5bd328b

Please sign in to comment.