Skip to content

Commit

Permalink
Merge branch 'feature-rebac' into charm-updates-01
Browse files Browse the repository at this point in the history
  • Loading branch information
alesstimec authored Jun 27, 2023
2 parents e855a95 + 88bdd1e commit 49d04ce
Show file tree
Hide file tree
Showing 19 changed files with 1,706 additions and 64 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/charm-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v3
- run: git fetch --prune --unshallow
- run: sudo snap install charmcraft --channel=2.x/stable --classic
- run: sudo charmcraft pack --project-dir ./charms/${{ matrix.charm-type }} --destructive-mode
- run: sudo charmcraft pack --project-dir ./charms/${{ matrix.charm-type }} --destructive-mode --verbosity=trace
- uses: actions/upload-artifact@v3
with:
name: ${{ matrix.charm-type }}-charm
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/charm-release.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Release to latest/edge
name: Release to v2/edge

on:
workflow_dispatch:
Expand Down Expand Up @@ -35,7 +35,7 @@ jobs:
with:
credentials: "${{ secrets.CHARMHUB_TOKEN }}"
github-token: "${{ secrets.GITHUB_TOKEN }}"
channel: "latest/edge"
channel: "v2/edge"
charm-path: "./charms/jimm-k8s"
local-image: "true"

Expand All @@ -54,15 +54,15 @@ jobs:
with:
name: jimm-snap
- name: Install charmcraft
run: sudo snap install charmcraft --channel=2.x/stable
run: sudo snap install charmcraft --channel=2.x/stable --classic
- name: Publish Charm Resource
run: charmcraft upload-resource juju-jimm jimm-snap --filepath ./jimm-snap
run: charmcraft upload-resource juju-jimm jimm-snap --filepath ./jimm.snap
env:
CHARMCRAFT_AUTH: "${{ secrets.CHARMHUB_TOKEN }}"
- name: Upload charm to charmhub
uses: canonical/charming-actions/[email protected]
with:
credentials: "${{ secrets.CHARMHUB_TOKEN }}"
github-token: "${{ secrets.GITHUB_TOKEN }}"
channel: "latest/edge"
channel: "v2/edge"
charm-path: "./charms/jimm"
2 changes: 1 addition & 1 deletion .github/workflows/snap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- run: sudo snap install snapcraft --channel=7.x/stable --classic
- run: mkdir -p snap
- run: cp ./snaps/jimm/snapcraft.yaml ./snap/snapcraft.yaml
- run: snapcraft --destructive-mode
- run: snapcraft --destructive-mode --output jimm.snap
- uses: actions/upload-artifact@v3
with:
name: jimm-snap
Expand Down
16 changes: 9 additions & 7 deletions charms/jimm-k8s/charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
type: "charm"
parts:
charm:
charm-python-packages: [setuptools, pyopenssl]
build-packages:
- libffi-dev
- libssl-dev
- rustc
- cargo
- pkg-config
charm-python-packages: [setuptools]
charm-binary-python-packages:
- cryptography
- jsonschema
- PyYAML
- attrs
- importlib-resources
- urllib3
- zipp
bases:
# This run-on is not as strict as the machine charm
# as the jimm-server runs in a container.
Expand Down
5 changes: 2 additions & 3 deletions charms/jimm-k8s/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
markupsafe >= 2.0.1
Jinja2 >= 2.11.3
ops >= 2.0.0
charmhelpers >= 0.20.22
hvac >= 0.11.0
jsonschema >= 3.2.0
cryptography >= 3.4.8
requests >= 2.25.1
hvac >= 0.11.0
requests >= 2.25.1
8 changes: 5 additions & 3 deletions charms/jimm-k8s/src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
"OPENFGA_PORT",
]

DATABASE_NAME = "jimm"
OPENFGA_STORE_NAME = "jimm"
LOG_FILE = "/var/log/jimm"
# This likely will just be JIMM's port.
PROMETHEUS_PORT = 8080
Expand Down Expand Up @@ -141,7 +143,7 @@ def __init__(self, *args):
self.database = DatabaseRequires(
self,
relation_name="database",
database_name="jimm",
database_name=DATABASE_NAME,
)
self.framework.observe(self.database.on.database_created, self._on_database_event)
self.framework.observe(
Expand All @@ -151,7 +153,7 @@ def __init__(self, *args):
self.framework.observe(self.on.database_relation_broken, self._on_database_relation_broken)

# OpenFGA relation
self.openfga = OpenFGARequires(self, "jimm")
self.openfga = OpenFGARequires(self, OPENFGA_STORE_NAME)
self.framework.observe(
self.openfga.on.openfga_store_created,
self._on_openfga_store_created,
Expand Down Expand Up @@ -360,7 +362,7 @@ def _on_database_event(self, event: DatabaseEvent) -> None:
# get the first endpoint from a comma separate list
ep = event.endpoints.split(",", 1)[0]
# compose the db connection string
uri = f"postgresql://{event.username}:{event.password}@{ep}/jimm"
uri = f"postgresql://{event.username}:{event.password}@{ep}/{DATABASE_NAME}"

logger.info("received database uri: {}".format(uri))

Expand Down
2 changes: 1 addition & 1 deletion charms/jimm-k8s/tests/integration/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ async def test_build_and_deploy(ops_test: OpsTest, local_charm):
),
)

logger.info("waiting for postgresql")
logger.info("waiting for postgresql and traefik")
await ops_test.model.wait_for_idle(
apps=["postgresql", "traefik"],
status="active",
Expand Down
157 changes: 157 additions & 0 deletions charms/jimm-k8s/tests/integration/test_upgrade.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#!/usr/bin/env python3
# Copyright 2022 Canonical Ltd
# See LICENSE file for licensing details.

import asyncio
import logging
import time
from pathlib import Path

import pytest
import utils
import yaml
from juju.action import Action
from pytest_operator.plugin import OpsTest

logger = logging.getLogger(__name__)

METADATA = yaml.safe_load(Path("./metadata.yaml").read_text())
APP_NAME = "juju-jimm-k8s"


@pytest.mark.abort_on_fail
async def test_upgrade_running_application(ops_test: OpsTest, local_charm):
"""Deploy latest published charm and upgrade it with charm-under-test.
Assert on the application status and health check endpoint after upgrade/refresh took place.
"""

# Deploy the charm and wait for active/idle status
logger.debug("deploying charms")
await ops_test.model.deploy(
METADATA["name"],
channel="edge",
application_name=APP_NAME,
series="focal",
config={
"uuid": "f4dec11e-e2b6-40bb-871a-cc38e958af49",
"candid-url": "https://api.jujucharms.com/identity",
"public-key": "izcYsQy3TePp6bLjqOo3IRPFvkQd2IKtyODGqC6SdFk=",
"private-key": "ly/dzsI9Nt/4JxUILQeAX79qZ4mygDiuYGqc2ZEiDEc=",
},
)
await ops_test.model.deploy(
"traefik-k8s",
application_name="traefik",
config={
"external_hostname": "traefik.test.canonical.com",
},
)
await asyncio.gather(
ops_test.model.deploy("postgresql-k8s", application_name="postgresql", channel="14/stable", trust=True),
ops_test.model.deploy(
"openfga-k8s",
application_name="openfga",
channel="latest/edge",
),
)

logger.info("waiting for postgresql and traefik")
await ops_test.model.wait_for_idle(
apps=["postgresql", "traefik"],
status="active",
raise_on_blocked=True,
timeout=40000,
)

logger.info("adding traefik relation")
await ops_test.model.relate("{}:ingress".format(APP_NAME), "traefik")

logger.info("adding openfga postgresql relation")
await ops_test.model.relate("openfga:database", "postgresql:database")

logger.info("waiting for openfga")
await ops_test.model.wait_for_idle(
apps=["openfga"],
status="blocked",
timeout=40000,
)

openfga_unit = await utils.get_unit_by_name("openfga", "0", ops_test.model.units)
for i in range(10):
action: Action = await openfga_unit.run_action("schema-upgrade")
result = await action.wait()
logger.info("attempt {} -> action result {} {}".format(i, result.status, result.results))
if result.results == {"result": "done", "return-code": 0}:
break
time.sleep(2)

logger.info("adding openfga relation")
await ops_test.model.relate(APP_NAME, "openfga")

logger.info("adding postgresql relation")
await ops_test.model.relate(APP_NAME, "postgresql:database")

logger.info("waiting for jimm")
await ops_test.model.wait_for_idle(
apps=[APP_NAME],
status="active",
# raise_on_blocked=True,
timeout=40000,
)

logger.info("running the create authorization model action")
jimm_unit = await utils.get_unit_by_name(APP_NAME, "0", ops_test.model.units)
with open("../../local/openfga/authorisation_model.json", "r") as model_file:
model_data = model_file.read()
for i in range(10):
action: Action = await jimm_unit.run_action(
"create-authorization-model",
model=model_data,
)
result = await action.wait()
logger.info("attempt {} -> action result {} {}".format(i, result.status, result.results))
if result.results == {"return-code": 0}:
break
time.sleep(2)

assert ops_test.model.applications[APP_NAME].status == "active"

# Starting upgrade/refresh
logger.info("starting upgrade test")

# Build and deploy charm from local source folder
logger.info("building local charm")

# (Optionally build) and deploy charm from local source folder
if local_charm:
charm = Path(utils.get_local_charm()).resolve()
else:
charm = await ops_test.build_charm(".")
resources = {"jimm-image": "localhost:32000/jimm:latest"}

# Deploy the charm and wait for active/idle status
logger.info("refreshing running application with the new local charm")

await ops_test.model.applications[APP_NAME].refresh(
path=charm,
resources=resources,
)

logger.info("waiting for the upgraded unit to be ready")
async with ops_test.fast_forward():
await ops_test.model.wait_for_idle(
apps=[APP_NAME],
status="active",
timeout=60,
)

assert ops_test.model.applications[APP_NAME].status == "active"

logger.info("checking status of the running unit")
upgraded_jimm_unit = await utils.get_unit_by_name(APP_NAME, "0", ops_test.model.units)

health = await upgraded_jimm_unit.run("curl -i http://localhost:8080/debug/status")
await health.wait()
assert health.results.get("return-code") == 0
assert health.results.get("stdout").strip().splitlines()[0].endswith("200 OK")
2 changes: 1 addition & 1 deletion charms/jimm/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pip install tox
```

The charm additionally requires the following relations:
- db, interface: pgsql
- database, interface: postgresql_client
- vault, interface: vault-kv
- openfga, interface: openfga

Expand Down
21 changes: 19 additions & 2 deletions charms/jimm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,31 @@ juju deploy ./jimm.charm --resource jimm-snap=jimm.snap
To upgrade the workload attach a new version of the snap:

```
juju attach jimm jimm-snap=jimm.snap
juju attach juju-jimm jimm-snap=jimm.snap
```
## Dependencies

### Postgresql

JIMM requires a postgresql database for data storage:

```
juju deploy postgresql
juju add-relation jimm:db postgresql:db
juju add-relation juju-jimm:database postgresql:database
```

### OpenFGA

JIMM requires a OpenFGA store for access control data storage:

<!-- TODO (@babakks) This is not accurate/working. We need to elaborate on
this because there's no machine charm for OpenFGA, and the user needs to create
a cross-model relation to a k8s model running OpenFGA.
-->

```
juju deploy openfga
juju add-relation juju-jimm:openfga postgresql:openfga
```

## Developing
Expand Down
Loading

0 comments on commit 49d04ce

Please sign in to comment.