Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add public-url config #12

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ links:
contact:
- https://launchpad.net/~canonical-is-devops

config:
options:
public-url:
description: >-
Public base URL where the server is visible.
type: string
default: "https://maubot.local"

resources:
maubot-image:
type: oci-image
Expand Down
16 changes: 0 additions & 16 deletions config.yaml

This file was deleted.

3 changes: 2 additions & 1 deletion src-docs/charm.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ Maubot charm service.
**Global Variables**
---------------
- **MAUBOT_NAME**
- **NGINX_NAME**


---

## <kbd>class</kbd> `MaubotCharm`
Maubot charm.

<a href="../src/charm.py#L39"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm.py#L40"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `__init__`

Expand Down
11 changes: 8 additions & 3 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
logger = logging.getLogger(__name__)

MAUBOT_NAME = "maubot"
NGINX_NAME = "nginx"


class MissingPostgreSQLRelationDataError(Exception):
Expand Down Expand Up @@ -71,6 +72,7 @@ def _configure_maubot(self, container: ops.Container) -> None:
config_content = str(container.pull("/data/config.yaml", encoding="utf-8").read())
config = yaml.safe_load(config_content)
config["database"] = self._get_postgresql_credentials()
config["server"]["public_url"] = self.config.get("public-url")
container.push("/data/config.yaml", yaml.safe_dump(config))

def _reconcile(self) -> None:
Expand All @@ -85,7 +87,8 @@ def _reconcile(self) -> None:
self.unit.status = ops.BlockedStatus("postgresql integration is required")
return
container.add_layer(MAUBOT_NAME, self._pebble_layer, combine=True)
container.replan()
container.restart(MAUBOT_NAME)
container.restart(NGINX_NAME)
self.unit.status = ops.ActiveStatus()

def _on_maubot_pebble_ready(self, _: ops.PebbleReadyEvent) -> None:
Expand Down Expand Up @@ -131,6 +134,8 @@ def _get_postgresql_credentials(self) -> str:
username = self.postgresql.fetch_relation_field(relation.id, "username")
password = self.postgresql.fetch_relation_field(relation.id, "password")

if not endpoints:
raise MissingPostgreSQLRelationDataError("Missing mandatory relation data")
primary_endpoint = endpoints.split(",")[0]
if not all((primary_endpoint, database, username, password)):
raise MissingPostgreSQLRelationDataError("Missing mandatory relation data")
Expand All @@ -144,7 +149,7 @@ def _pebble_layer(self) -> pebble.LayerDict:
"summary": "maubot layer",
"description": "pebble config layer for maubot",
"services": {
"nginx": {
NGINX_NAME: {
"override": "replace",
"summary": "nginx",
"command": "/usr/sbin/nginx",
Expand All @@ -163,4 +168,4 @@ def _pebble_layer(self) -> pebble.LayerDict:


if __name__ == "__main__": # pragma: nocover
ops.main.main(MaubotCharm)
ops.main(MaubotCharm)
36 changes: 36 additions & 0 deletions tests/integration/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,39 @@ async def test_build_and_deploy(
)
assert response.status_code == 200
assert "Maubot Manager" in response.text


@pytest.mark.abort_on_fail
async def test_public_url_config(
ops_test: OpsTest,
):
"""
arrange: Maubot is active and paths.json contains default value.
act: change public_url with a different path called /internal/.
assert: api_path contains the extra subpath /internal/ extracted from the
public_url.
"""
response = requests.get(
"http://127.0.0.1/_matrix/maubot/paths.json",
timeout=5,
headers={"Host": "maubot.local"},
)
assert response.status_code == 200
data = response.json()
assert "api_path" in data
assert data["api_path"] == "/_matrix/maubot/v1"

assert ops_test.model
application = ops_test.model.applications["maubot"]
await application.set_config({"public-url": "http://foo.com/internal/"})
await ops_test.model.wait_for_idle(timeout=600, status="active")

response = requests.get(
"http://127.0.0.1/_matrix/maubot/paths.json",
timeout=5,
headers={"Host": "maubot.local"},
)
assert response.status_code == 200
data = response.json()
assert "api_path" in data
assert data["api_path"] == "/internal/_matrix/maubot/v1"
9 changes: 8 additions & 1 deletion tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ def harness_fixture():
)
root = harness.get_filesystem_root("maubot")
(root / "data").mkdir()
(root / "data" / "config.yaml").write_text("database: sqlite:maubot.db")
yaml_content = """\
jdkandersson marked this conversation as resolved.
Show resolved Hide resolved
database: sqlite:maubot.db
server:
hostname: 0.0.0.0
port: 29316
public_url: https://example.com
"""
(root / "data" / "config.yaml").write_text(yaml_content)
yield harness
harness.cleanup()
16 changes: 16 additions & 0 deletions tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,19 @@ def test_database_created(harness):
harness.charm._get_postgresql_credentials()
== "postgresql://someuser:somepasswd@dbhost:5432/maubot"
)


def test_public_url_config_changed(harness):
"""
arrange: initialize harness and set postgresql integration.
act: change public-url config.
assert: charm is active.
"""
harness.begin_with_initial_hooks()
set_postgresql_integration(harness)

harness.update_config({"public-url": "https://example1.com"})

service = harness.model.unit.get_container("maubot").get_service("maubot")
assert service.is_running()
assert harness.model.unit.status == ops.ActiveStatus()
Loading