← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad-layers:interface-apache-vhost-config into launchpad-layers:main

 

Colin Watson has proposed merging ~cjwatson/launchpad-layers:interface-apache-vhost-config into launchpad-layers:main.

Commit message:
Add interface to publish Apache virtual host configuration

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad-layers/+git/launchpad-layers/+merge/447537

This implements the interface described under "Using the vhost-config relation" in https://git.launchpad.net/apache2-charm/tree/README.md.  It will allow us to put the desired Apache frontend configuration in the corresponding service charm and then just add some relations to make everything work.  I have a functioning prototype of this for the librarian.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad-layers:interface-apache-vhost-config into launchpad-layers:main.
diff --git a/apache-vhost-config/interface.yaml b/apache-vhost-config/interface.yaml
new file mode 100644
index 0000000..0394b31
--- /dev/null
+++ b/apache-vhost-config/interface.yaml
@@ -0,0 +1,3 @@
+name: apache-vhost-config
+summary: Apache virtual host configuration interface
+version: 1
diff --git a/apache-vhost-config/provides.py b/apache-vhost-config/provides.py
new file mode 100644
index 0000000..7bd4a3e
--- /dev/null
+++ b/apache-vhost-config/provides.py
@@ -0,0 +1,53 @@
+# Copyright 2023 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+import base64
+from dataclasses import dataclass
+from typing import Dict, Iterable
+
+from charmhelpers.core import hookenv
+from charms.reactive import Endpoint, clear_flag, set_flag, when
+
+
+@dataclass
+class Vhost:
+    port: int
+    template: str
+
+    def to_publish(self) -> Dict[str, str]:
+        return {
+            "port": self.port,
+            "template": base64.b64encode(self.template.encode()).decode(),
+        }
+
+
+class ApacheVhostConfigProvides(Endpoint):
+    @when("endpoint.{endpoint_name}.joined")
+    def handle_joined_unit(self):
+        set_flag(self.expand_name("{endpoint_name}.available"))
+
+    @when("endpoint.{endpoint_name}.changed")
+    def handle_changed_unit(self):
+        set_flag(self.expand_name("{endpoint_name}.available"))
+        clear_flag(self.expand_name("changed"))
+
+    @when("endpoint.{endpoint_name}.departed")
+    def handle_departed_unit(self):
+        clear_flag(self.expand_name("{endpoint_name}.available"))
+        self.all_departed_units.clear()
+        clear_flag(self.expand_name("departed"))
+
+    def make_vhost(self, port: int, template: str):
+        """Prepare a vhost entry for use by `publish_vhosts`."""
+        return Vhost(port=port, template=template)
+
+    def publish_vhosts(self, vhosts: Iterable[Vhost]):
+        """Publish virtual host configurations for use by the Apache charm.
+
+        :param vhosts: An iterable of objects returned by `make_vhost`.
+        """
+        hookenv.log("Publishing Apache virtual host configurations")
+        for relation in self.relations:
+            relation.to_publish.update(
+                {"vhosts": [vhost.to_publish() for vhost in vhosts]}
+            )