From 22882d15fff2690a77e4e350fa6df2679b20057b Mon Sep 17 00:00:00 2001 From: gtrkiller Date: Mon, 8 Jan 2024 14:07:07 -0300 Subject: [PATCH] migrate to nginx_route --- config.yaml | 4 +- docs/tutorial/getting-started.md | 4 +- .../nginx_ingress_integrator/v0/ingress.py | 10 +- .../v0/nginx_route.py | 427 ++++++++++++++++++ metadata.yaml | 8 +- src-docs/charm.py.md | 2 +- src/charm.py | 42 +- tests/integration/any_charm.py | 2 +- tests/integration/conftest.py | 4 +- tests/unit/test_charm.py | 17 +- 10 files changed, 473 insertions(+), 47 deletions(-) create mode 100644 lib/charms/nginx_ingress_integrator/v0/nginx_route.py diff --git a/config.yaml b/config.yaml index 60e1e83..7221e3a 100644 --- a/config.yaml +++ b/config.yaml @@ -5,13 +5,13 @@ options: site: type: string description: > - Required if no ingress-proxy relation is established. The site name, e.g. "mysite.local". + Required if no nginx-proxy relation is established. The site name, e.g. "mysite.local". If the backend is set and this option is empty then the site will default to the application name. backend: type: string description: > - Required if no ingress-proxy relation is established. The backend to use for site, e.g. "http://mybackend.local:80". + Required if no nginx-proxy relation is established. The backend to use for site, e.g. "http://mybackend.local:80". default: "" backend_site_name: type: string diff --git a/docs/tutorial/getting-started.md b/docs/tutorial/getting-started.md index f731a83..6ba263b 100644 --- a/docs/tutorial/getting-started.md +++ b/docs/tutorial/getting-started.md @@ -41,7 +41,7 @@ This is because the Content-cache-k8s charm isn't integrated with Hello-kubecon Provide integration between Content-cache-k8s and Hello-kubecon by running the following [`juju relate`](https://juju.is/docs/olm/juju-relate) command: ```bash -juju relate content-cache-k8s:ingress-proxy hello-kubecon +juju relate content-cache-k8s:nginx-proxy hello-kubecon ``` Run `juju status` to see that the message has changed: @@ -51,7 +51,7 @@ content-cache-k8s/0* active idle 10.1.97.227 Ready hello-kubecon/0* active idle 10.1.97.193 ``` -Note: `ingress-proxy` is the name of the relation. You can run `juju info content-cache-k8s` to check what are the relation names provided by the Content-cache-k8s application and `juju status --relations` to see the relations currently established in the model. +Note: `nginx-proxy` is the name of the relation. You can run `juju info content-cache-k8s` to check what are the relation names provided by the Content-cache-k8s application and `juju status --relations` to see the relations currently established in the model. The deployment finishes when the status shows "Active". diff --git a/lib/charms/nginx_ingress_integrator/v0/ingress.py b/lib/charms/nginx_ingress_integrator/v0/ingress.py index 84857e7..c6a6e67 100644 --- a/lib/charms/nginx_ingress_integrator/v0/ingress.py +++ b/lib/charms/nginx_ingress_integrator/v0/ingress.py @@ -79,7 +79,7 @@ from ops.model import BlockedStatus INGRESS_RELATION_NAME = "ingress" -INGRESS_PROXY_RELATION_NAME = "ingress-proxy" +INGRESS_PROXY_RELATION_NAME = "nginx-proxy" # The unique Charmhub library identifier, never change it LIBID = "db0af4367506491c91663468fb5caa4c" @@ -295,14 +295,14 @@ def __init__(self, charm: CharmBase, relation_name: str) -> None: """Init function for the IngressProxyProvides class. Args: - charm: The charm that provides the ingress-proxy relation. + charm: The charm that provides the nginx-proxy relation. relation_name: The name of the relation. """ super().__init__(charm, relation_name) self.charm = charm def _on_relation_changed(self, event: RelationChangedEvent) -> None: - """Handle a change to the ingress/ingress-proxy relation. + """Handle a change to the ingress/nginx-proxy relation. Confirm we have the fields we expect to receive. @@ -396,7 +396,7 @@ def _on_relation_broken(self, event: RelationBrokenEvent) -> None: class IngressProxyProvides(IngressBaseProvides): - """Class containing the functionality for the 'provides' side of the 'ingress-proxy' relation. + """Class containing the functionality for the 'provides' side of the 'nginx-proxy' relation. Hook events observed: - relation-changed @@ -406,7 +406,7 @@ def __init__(self, charm: CharmBase) -> None: """Init function for the IngressProxyProvides class. Args: - charm: The charm that provides the ingress-proxy relation. + charm: The charm that provides the nginx-proxy relation. """ super().__init__(charm, INGRESS_PROXY_RELATION_NAME) # Observe the relation-changed hook event and bind diff --git a/lib/charms/nginx_ingress_integrator/v0/nginx_route.py b/lib/charms/nginx_ingress_integrator/v0/nginx_route.py new file mode 100644 index 0000000..9eb99dd --- /dev/null +++ b/lib/charms/nginx_ingress_integrator/v0/nginx_route.py @@ -0,0 +1,427 @@ +# Copyright 2023 Canonical Ltd. +# Licensed under the Apache2.0. See LICENSE file in charm source for details. +"""Library for the nginx-route relation. + +This library contains the require and provide functions for handling +the nginx-route interface. + +Import `require_nginx_route` in your charm, with four required keyword arguments: +- charm: (the charm itself) +- service_hostname +- service_name +- service_port + +Other optional arguments include: +- additional_hostnames +- backend_protocol +- limit_rps +- limit_whitelist +- max_body_size +- owasp_modsecurity_crs +- owasp_modsecurity_custom_rules +- path_routes +- retry_errors +- rewrite_target +- rewrite_enabled +- service_namespace +- session_cookie_max_age +- tls_secret_name + +See [the config section](https://charmhub.io/nginx-ingress-integrator/configure) for descriptions +of each, along with the required type. + +As an example, add the following to `src/charm.py`: +```python +from charms.nginx_ingress_integrator.v0.nginx_route import NginxRouteRequirer + +# In your charm's `__init__` method (assuming your app is listening on port 8080). +require_nginx_route( + charm=self, + service_hostname=self.app.name, + service_name=self.app.name, + service_port=8080 +) + +``` +And then add the following to `metadata.yaml`: +``` +requires: + nginx-route: + interface: nginx-route +``` +You _must_ require nginx route as part of the `__init__` method +rather than, for instance, a config-changed event handler, for the relation +changed event to be properly handled. + +In the example above we're setting `service_hostname` (which translates to the +external hostname for the application when related to nginx-ingress-integrator) +to `self.app.name` here. This ensures by default the charm will be available on +the name of the deployed juju application, but can be overridden in a +production deployment by setting `service-hostname` on the +nginx-ingress-integrator charm. For example: +```bash +juju deploy nginx-ingress-integrator +juju deploy my-charm +juju relate nginx-ingress-integrator my-charm:nginx-route +# The service is now reachable on the ingress IP(s) of your k8s cluster at +# 'http://my-charm'. +juju config nginx-ingress-integrator service-hostname='my-charm.example.com' +# The service is now reachable on the ingress IP(s) of your k8s cluster at +# 'http://my-charm.example.com'. +``` +""" +import logging +import typing +import weakref + +import ops.charm +import ops.framework +import ops.model + +# The unique Charmhub library identifier, never change it +LIBID = "3c212b6ed3cf43dfbf9f2e322e634beb" + +# 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 = 4 + +__all__ = ["require_nginx_route", "provide_nginx_route"] + +logger = logging.getLogger(__name__) + + +class _NginxRouteAvailableEvent(ops.framework.EventBase): + """NginxRouteAvailableEvent custom event. + + This event indicates the nginx-route provider is available. + """ + + +class _NginxRouteProxyAvailableEvent(ops.framework.EventBase): + """NginxRouteProxyAvailableEvent custom event. + + This event indicates the NginxRouteProxy provider is available. + """ + + +class _NginxRouteBrokenEvent(ops.charm.RelationBrokenEvent): + """NginxRouteBrokenEvent custom event. + + This event indicates the nginx-route provider is broken. + """ + + +class _NginxRouteCharmEvents(ops.charm.CharmEvents): + """Custom charm events. + + Attrs: + nginx_route_available: Event to indicate that Nginx route relation is available. + nginx_route_broken: Event to indicate that Nginx route relation is broken. + """ + + nginx_route_proxy_available = ops.framework.EventSource(_NginxRouteProxyAvailableEvent) + nginx_route_available = ops.framework.EventSource(_NginxRouteAvailableEvent) + nginx_route_broken = ops.framework.EventSource(_NginxRouteBrokenEvent) + + +class _NginxRouteRequirer(ops.framework.Object): + """This class defines the functionality for the 'requires' side of the 'nginx-route' relation. + + Hook events observed: + - relation-changed + """ + + def __init__( + self, + charm: ops.charm.CharmBase, + config: typing.Dict[str, typing.Union[str, int, bool]], + nginx_route_relation_name: str = "nginx-route", + ): + """Init function for the NginxRouteRequires class. + + Args: + charm: The charm that requires the nginx-route relation. + config: Contains all the configuration options for nginx-route. + nginx_route_relation_name: Specifies the relation name of the relation handled by this + requirer class. The relation must have the nginx-route interface. + """ + super().__init__(charm, nginx_route_relation_name) + self._charm = charm + self._nginx_route_relation_name = nginx_route_relation_name + self._charm.framework.observe( + self._charm.on[self._nginx_route_relation_name].relation_changed, + self._config_reconciliation, + ) + # Set default values. + self._config: typing.Dict[str, typing.Union[str, int, bool]] = { + "service-namespace": self._charm.model.name, + **config, + } + self._config_reconciliation(None) + + def _config_reconciliation(self, _event: typing.Any = None) -> None: + """Update the nginx-route relation data to be exactly as defined by config.""" + if not self._charm.model.unit.is_leader(): + return + for relation in self._charm.model.relations[self._nginx_route_relation_name]: + relation_app_data = relation.data[self._charm.app] + delete_keys = { + relation_field + for relation_field in relation_app_data + if relation_field not in self._config + } + for delete_key in delete_keys: + del relation_app_data[delete_key] + relation_app_data.update({k: str(v) for k, v in self._config.items()}) + + +# C901 is ignored since the method has too many ifs but wouldn't be +# necessarily good to reduce to smaller methods. +# E501: line too long +def require_nginx_route( # pylint: disable=too-many-locals,too-many-branches,too-many-arguments # noqa: C901,E501 + *, + charm: ops.charm.CharmBase, + service_hostname: str, + service_name: str, + service_port: int, + additional_hostnames: typing.Optional[str] = None, + backend_protocol: typing.Optional[str] = None, + limit_rps: typing.Optional[int] = None, + limit_whitelist: typing.Optional[str] = None, + max_body_size: typing.Optional[int] = None, + owasp_modsecurity_crs: typing.Optional[str] = None, + owasp_modsecurity_custom_rules: typing.Optional[str] = None, + path_routes: typing.Optional[str] = None, + retry_errors: typing.Optional[str] = None, + rewrite_target: typing.Optional[str] = None, + rewrite_enabled: typing.Optional[bool] = None, + service_namespace: typing.Optional[str] = None, + session_cookie_max_age: typing.Optional[int] = None, + tls_secret_name: typing.Optional[str] = None, + nginx_route_relation_name: str = "nginx-route", +) -> None: + """Set up nginx-route relation handlers on the requirer side. + + This function must be invoked in the charm class constructor. + + Args: + charm: The charm that requires the nginx-route relation. + service_hostname: configure Nginx ingress integrator + service-hostname option via relation. + service_name: configure Nginx ingress integrator service-name + option via relation. + service_port: configure Nginx ingress integrator service-port + option via relation. + additional_hostnames: configure Nginx ingress integrator + additional-hostnames option via relation, optional. + backend_protocol: configure Nginx ingress integrator + backend-protocol option via relation, optional. + limit_rps: configure Nginx ingress integrator limit-rps + option via relation, optional. + limit_whitelist: configure Nginx ingress integrator + limit-whitelist option via relation, optional. + max_body_size: configure Nginx ingress integrator + max-body-size option via relation, optional. + owasp_modsecurity_crs: configure Nginx ingress integrator + owasp-modsecurity-crs option via relation, optional. + owasp_modsecurity_custom_rules: configure Nginx ingress + integrator owasp-modsecurity-custom-rules option via + relation, optional. + path_routes: configure Nginx ingress integrator path-routes + option via relation, optional. + retry_errors: configure Nginx ingress integrator retry-errors + option via relation, optional. + rewrite_target: configure Nginx ingress integrator + rewrite-target option via relation, optional. + rewrite_enabled: configure Nginx ingress integrator + rewrite-enabled option via relation, optional. + service_namespace: configure Nginx ingress integrator + service-namespace option via relation, optional. + session_cookie_max_age: configure Nginx ingress integrator + session-cookie-max-age option via relation, optional. + tls_secret_name: configure Nginx ingress integrator + tls-secret-name option via relation, optional. + nginx_route_relation_name: Specifies the relation name of + the relation handled by this requirer class. The relation + must have the nginx-route interface. + """ + config: typing.Dict[str, typing.Union[str, int, bool]] = {} + if service_hostname is not None: + config["service-hostname"] = service_hostname + if service_name is not None: + config["service-name"] = service_name + if service_port is not None: + config["service-port"] = service_port + if additional_hostnames is not None: + config["additional-hostnames"] = additional_hostnames + if backend_protocol is not None: + config["backend-protocol"] = backend_protocol + if limit_rps is not None: + config["limit-rps"] = limit_rps + if limit_whitelist is not None: + config["limit-whitelist"] = limit_whitelist + if max_body_size is not None: + config["max-body-size"] = max_body_size + if owasp_modsecurity_crs is not None: + config["owasp-modsecurity-crs"] = owasp_modsecurity_crs + if owasp_modsecurity_custom_rules is not None: + config["owasp-modsecurity-custom-rules"] = owasp_modsecurity_custom_rules + if path_routes is not None: + config["path-routes"] = path_routes + if retry_errors is not None: + config["retry-errors"] = retry_errors + if rewrite_target is not None: + config["rewrite-target"] = rewrite_target + if rewrite_enabled is not None: + config["rewrite-enabled"] = rewrite_enabled + if service_namespace is not None: + config["service-namespace"] = service_namespace + if session_cookie_max_age is not None: + config["session-cookie-max-age"] = session_cookie_max_age + if tls_secret_name is not None: + config["tls-secret-name"] = tls_secret_name + + _NginxRouteRequirer( + charm=charm, config=config, nginx_route_relation_name=nginx_route_relation_name + ) + + +class _NginxRouteProvider(ops.framework.Object): + """Class containing the functionality for the 'provides' side of the 'nginx-route' relation. + + Attrs: + on: nginx-route relation event describer. + + Hook events observed: + - relation-changed + """ + + on = _NginxRouteCharmEvents() + + def __init__( + self, + charm: ops.charm.CharmBase, + nginx_route_relation_name: str = "nginx-route", + ): + """Init function for the NginxRouterProvides class. + + Args: + charm: The charm that provides the nginx-route relation. + nginx_route_relation_name: Specifies the relation name of the relation handled by this + provider class. The relation must have the nginx-route interface. + """ + # Observe the relation-changed hook event and bind + # self.on_relation_changed() to handle the event. + super().__init__(charm, nginx_route_relation_name) + self._charm = charm + self._charm.framework.observe( + self._charm.on[nginx_route_relation_name].relation_changed, self._on_relation_changed + ) + self._charm.framework.observe( + self._charm.on[nginx_route_relation_name].relation_broken, self._on_relation_broken + ) + + def _on_relation_changed(self, event: ops.charm.RelationChangedEvent) -> None: + """Handle a change to the nginx-route relation. + + Confirm we have the fields we expect to receive. + + Args: + event: Event triggering the relation-changed hook for the relation. + + Raises: + RuntimeError: if _on_relation changed is triggered by a broken relation. + """ + # `self.unit` isn't available here, so use `self.model.unit`. + if not self._charm.model.unit.is_leader(): + return + + relation_name = event.relation.name + remote_app = event.app + if remote_app is None: + raise RuntimeError("_on_relation_changed was triggered by a broken relation.") + + if not event.relation.data[remote_app]: + logger.info( + "%s hasn't finished configuring, waiting until the relation data is populated.", + relation_name, + ) + return + + required_fields = {"service-hostname", "service-port", "service-name"} + missing_fields = sorted( + field + for field in required_fields + if event.relation.data[remote_app].get(field) is None + ) + if missing_fields: + logger.warning( + "Missing required data fields for %s relation: %s", + relation_name, + ", ".join(missing_fields), + ) + self._charm.model.unit.status = ops.model.BlockedStatus( + f"Missing fields for {relation_name}: {', '.join(missing_fields)}" + ) + return + + # Create an event that our charm can use to decide it's okay to + # configure the Kubernetes Nginx ingress resources. + self.on.nginx_route_available.emit() + + def _on_relation_broken(self, event: ops.charm.RelationBrokenEvent) -> None: + """Handle a relation-broken event in the nginx-route relation. + + Args: + event: Event triggering the relation-broken hook for the relation. + """ + if not self._charm.model.unit.is_leader(): + return + + # Create an event that our charm can use to remove the Kubernetes Nginx ingress resources. + self.on.nginx_route_broken.emit(event.relation) + + +# This is here only to maintain a reference to the instance of NginxRouteProvider created by +# the provide_nginx_route function. This is required for ops framework event handling to work. +# The provider instance will have the same lifetime as the charm that creates it. +__provider_references: weakref.WeakKeyDictionary = weakref.WeakKeyDictionary() + + +def provide_nginx_route( + charm: ops.charm.CharmBase, + on_nginx_route_available: typing.Callable, + on_nginx_route_broken: typing.Callable, + nginx_route_relation_name: str = "nginx-route", +) -> None: + """Set up nginx-route relation handlers on the provider side. + + This function must be invoked in the charm class constructor. + + Args: + charm: The charm that requires the nginx-route relation. + on_nginx_route_available: Callback function for the nginx-route-available event. + on_nginx_route_broken: Callback function for the nginx-route-broken event. + nginx_route_relation_name: Specifies the relation name of the relation handled by this + provider class. The relation must have the nginx-route interface. + + Raises: + RuntimeError: If provide_nginx_route was invoked twice with + the same nginx-route relation name + """ + if __provider_references.get(charm, {}).get(nginx_route_relation_name) is not None: + raise RuntimeError( + "provide_nginx_route was invoked twice with the same nginx-route relation name" + ) + provider = _NginxRouteProvider( + charm=charm, nginx_route_relation_name=nginx_route_relation_name + ) + if charm in __provider_references: + __provider_references[charm][nginx_route_relation_name] = provider + else: + __provider_references[charm] = {nginx_route_relation_name: provider} + charm.framework.observe(provider.on.nginx_route_available, on_nginx_route_available) + charm.framework.observe(provider.on.nginx_route_broken, on_nginx_route_broken) diff --git a/metadata.yaml b/metadata.yaml index 6b9e6cf..29f1e4a 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -46,13 +46,13 @@ provides: interface: prometheus_scrape grafana-dashboard: interface: grafana_dashboard - ingress-proxy: - interface: ingress + nginx-proxy: + interface: nginx-route requires: logging: interface: loki_push_api limit: 1 - ingress: - interface: ingress + nginx-route: + interface: nginx-route limit: 1 diff --git a/src-docs/charm.py.md b/src-docs/charm.py.md index e7cac91..a6b6ec7 100644 --- a/src-docs/charm.py.md +++ b/src-docs/charm.py.md @@ -20,7 +20,7 @@ Charm for Content-cache on Kubernetes. ## class `ContentCacheCharm` Charm the service. -Attrs: on: Ingress Charm Events ERROR_LOG_PATH: NGINX error log ACCESS_LOG_PATH: NGINX access log _metrics_endpoint: Provider of metrics for Prometheus charm _logging: Requirer of logs for Loki charm _grafana_dashboards: Dashboard Provider for Grafana charm ingress_proxy_provides: Ingress proxy provider ingress: Ingress requirer unit: Charm's designated juju unit model: Charm's designated juju model +Attrs: on: Ingress Charm Events ERROR_LOG_PATH: NGINX error log ACCESS_LOG_PATH: NGINX access log _metrics_endpoint: Provider of metrics for Prometheus charm _logging: Requirer of logs for Loki charm _grafana_dashboards: Dashboard Provider for Grafana charm nginx_proxy_provides: Ingress proxy provider ingress: Ingress requirer unit: Charm's designated juju unit model: Charm's designated juju model diff --git a/src/charm.py b/src/charm.py index 7ed86bf..dd59116 100755 --- a/src/charm.py +++ b/src/charm.py @@ -13,11 +13,10 @@ from charms.grafana_k8s.v0.grafana_dashboard import GrafanaDashboardProvider from charms.loki_k8s.v0.loki_push_api import LogProxyConsumer -from charms.nginx_ingress_integrator.v0.ingress import ( - REQUIRED_INGRESS_RELATION_FIELDS, - IngressCharmEvents, - IngressProxyProvides, - IngressRequires, +from charms.nginx_ingress_integrator.v0.nginx_route import ( + _NginxRouteCharmEvents, + provide_nginx_route, + require_nginx_route, ) from charms.prometheus_k8s.v0.prometheus_scrape import MetricsEndpointProvider from ops.charm import ActionEvent, CharmBase, ConfigChangedEvent, UpgradeCharmEvent @@ -34,6 +33,7 @@ EXPORTER_CONTAINER_NAME = "nginx-prometheus-exporter" CONTAINER_PORT = 8080 REQUIRED_JUJU_CONFIGS = ["backend"] +REQUIRED_INGRESS_RELATION_FIELDS = {"service-hostname", "service-name", "service-port"} class ContentCacheCharm(CharmBase): @@ -46,13 +46,11 @@ class ContentCacheCharm(CharmBase): _metrics_endpoint: Provider of metrics for Prometheus charm _logging: Requirer of logs for Loki charm _grafana_dashboards: Dashboard Provider for Grafana charm - ingress_proxy_provides: Ingress proxy provider - ingress: Ingress requirer unit: Charm's designated juju unit model: Charm's designated juju model """ - on = IngressCharmEvents() + on = _NginxRouteCharmEvents() ERROR_LOG_PATH = "/var/log/nginx/error.log" ACCESS_LOG_PATH = "/var/log/nginx/access.log" @@ -90,11 +88,22 @@ def __init__(self, *args): self._grafana_dashboards = GrafanaDashboardProvider( self, relation_name="grafana-dashboard" ) - - self.ingress_proxy_provides = IngressProxyProvides(self) - self.ingress = IngressRequires(self, self._make_ingress_config()) - self.framework.observe(self.on.ingress_available, self._on_config_changed) - self.framework.observe(self.on.ingress_proxy_available, self._on_config_changed) + ingress_config = self._make_ingress_config() + require_nginx_route( + charm=self, + max_body_size=ingress_config.get("max-body-size", None), + service_hostname=ingress_config.get("service-hostname"), + service_name=ingress_config.get("service-name"), + service_port=ingress_config.get("service-port"), + tls_secret_name=ingress_config.get("tls-secret-name", None), + ) + provide_nginx_route( + charm=self, + on_nginx_route_available=self._on_config_changed, + on_nginx_route_broken=self._on_config_changed, + nginx_route_relation_name="nginx-proxy", + ) + self.framework.observe(self.on.nginx_route_proxy_available, self._on_config_changed) def _on_content_cache_pebble_ready(self, event) -> None: """Handle content_cache_pebble_ready event and configure workload container. @@ -206,7 +215,6 @@ def configure_workload_container(self, event: ConfigChangedEvent) -> None: Args: event: config-changed event. """ - self.ingress.update_config(self._make_ingress_config()) missing = sorted(self._missing_charm_configs()) if missing: msg = f"Required config(s) empty: {', '.join(missing)}" @@ -305,7 +313,7 @@ def _make_ingress_config(self) -> dict: site = config.get("site") - relation = self.model.get_relation("ingress-proxy") + relation = self.model.get_relation("nginx-proxy") if relation: # in case the relation app is not available yet prev_site = site @@ -334,7 +342,7 @@ def _make_env_config(self, domain="svc.cluster.local") -> dict: Charm's environment config """ config = self.model.config - relation = self.model.get_relation("ingress-proxy") + relation = self.model.get_relation("nginx-proxy") if relation and relation.data[relation.app] and relation.units: if any( relation.data[relation.app].get(nginx_config) is None @@ -438,7 +446,7 @@ def _missing_charm_configs(self) -> list[str]: Returns: Missing settings in the required juju configs. """ - relation = self.model.get_relation("ingress-proxy") + relation = self.model.get_relation("nginx-proxy") if relation: return [] config = self.model.config diff --git a/tests/integration/any_charm.py b/tests/integration/any_charm.py index eae765a..aedc9b0 100644 --- a/tests/integration/any_charm.py +++ b/tests/integration/any_charm.py @@ -13,7 +13,7 @@ class AnyCharm(AnyCharmBase): - """Execute a simple web-server charm to test the ingress-proxy relation. + """Execute a simple web-server charm to test the nginx-proxy relation. Attrs: ingress: The attribute that mimics a real ingress relation. diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 5108e22..d72401c 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -162,10 +162,10 @@ async def app( try: await ops_test.model.wait_for_idle(raise_on_blocked=True) except (JujuAppError, JujuUnitError): - print("BlockedStatus raised: will be solved after relation ingress-proxy") + print("BlockedStatus raised: will be solved after relation nginx-proxy") apps = [app_name, nginx_integrator_app.name, any_app_name] - await ops_test.model.add_relation(any_app_name, f"{app_name}:ingress-proxy") + await ops_test.model.add_relation(any_app_name, f"{app_name}:nginx-proxy") await ops_test.model.wait_for_idle(apps=apps, status=ActiveStatus.name, timeout=60 * 5) await ops_test.model.add_relation(nginx_integrator_app.name, f"{app_name}:ingress") await ops_test.model.wait_for_idle(apps=apps, status=ActiveStatus.name, timeout=60 * 5) diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py index ea6e138..ca5b6bc 100644 --- a/tests/unit/test_charm.py +++ b/tests/unit/test_charm.py @@ -132,7 +132,6 @@ def test_on_upgrade_charm(self, configure_workload_container): @mock.patch("charm.ContentCacheCharm._make_nginx_config") @mock.patch("charm.ContentCacheCharm._make_pebble_config") - @mock.patch("charms.nginx_ingress_integrator.v0.ingress.IngressRequires.update_config") @mock.patch("ops.model.Container.add_layer") @mock.patch("ops.model.Container.get_service") @mock.patch("ops.model.Container.make_dir") @@ -149,7 +148,6 @@ def test_configure_workload_container( make_dir, get_service, add_layer, - ingress_update, make_pebble_config, make_nginx_config, ): @@ -161,13 +159,6 @@ def test_configure_workload_container( config = self.config harness = self.harness harness.update_config(config) - expect = { - "max-body-size": "1m", - "service-hostname": "mysite.local", - "service-name": "content-cache-k8s", - "service-port": 8080, - } - ingress_update.assert_called_with(expect) make_pebble_config.assert_called_once() make_nginx_config.assert_called_once() assert add_layer.call_count == 2 @@ -439,14 +430,14 @@ def test_make_ingress_config_tls_secret(self): def test_make_ingress_config_with_proxy_relation(self): """ - arrange: set ingress-proxy relation + arrange: set nginx-proxy relation act: verify ingress config assert: ingress config is generated as expected """ harness = self.harness expected = copy.deepcopy(INGRESS_CONFIG) assert harness.charm._make_ingress_config() == expected - relation_id = harness.add_relation("ingress-proxy", "hello-kubecon") + relation_id = harness.add_relation("nginx-proxy", "hello-kubecon") harness.add_relation_unit(relation_id, "hello-kubecon/0") relations_data = { "service-name": "test-proxy", @@ -479,7 +470,7 @@ def test_make_env_config(self): def test_make_env_config_with_proxy_relation(self): """ - arrange: set ingress-proxy relation + arrange: set nginx-proxy relation act: verify env config assert: env config is generated as expected """ @@ -490,7 +481,7 @@ def test_make_env_config_with_proxy_relation(self): current_env_config = harness.charm._make_env_config() current_site = current_env_config["CONTENT_CACHE_SITE"] assert current_site == "mysite.local" - relation_id = harness.add_relation("ingress-proxy", "hello-kubecon") + relation_id = harness.add_relation("nginx-proxy", "hello-kubecon") harness.add_relation_unit(relation_id, "hello-kubecon/0") relations_data = { "service-name": "test-proxy",