Skip to content

Commit

Permalink
misc: resolve comments
Browse files Browse the repository at this point in the history
  • Loading branch information
wood-push-melon committed Jan 16, 2024
1 parent d8a9878 commit a3ba848
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repos:
- id: requirements-txt-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.11
rev: v0.1.13
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @canonical/identity
5 changes: 4 additions & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ options:
default: "dc=glauth,dc=com"
type: string
hostname:
description: The hostname of the LDAP server
description: |
The hostname of the LDAP server.
The hostname should NOT contain the LDAP scheme (e.g. ldap://) and port.
default: "ldap.glauth.com"
type: string
3 changes: 2 additions & 1 deletion src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from ops.pebble import ChangeError
from utils import (
after_config_updated,
block_on_missing,
leader_unit,
validate_container_connectivity,
validate_database_resource,
Expand Down Expand Up @@ -133,7 +134,7 @@ def _restart_glauth_service(self) -> None:
)

@validate_container_connectivity
@validate_integration_exists(DATABASE_INTEGRATION_NAME)
@validate_integration_exists(DATABASE_INTEGRATION_NAME, on_missing=block_on_missing)
@validate_database_resource
def _handle_event_update(self, event: HookEvent) -> None:
self.unit.status = MaintenanceStatus("Configuring GLAuth container")
Expand Down
27 changes: 20 additions & 7 deletions src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@
logger = logging.getLogger(__name__)


def _default_on_missing(charm: CharmBase, event: EventBase, **kwargs: Any) -> None:
logger.debug(f"Integration {kwargs.get('integration_name')} is missing.")


def block_on_missing(charm: CharmBase, event: EventBase, **kwargs: Any) -> None:
integration_name = kwargs.get("integration_name")
logger.debug(f"Integration {integration_name} is missing, defer event {event}.")
event.defer()

charm.unit.status = BlockedStatus(f"Missing required integration {integration_name}")


def leader_unit(func: Callable) -> Callable:
@wraps(func)
def wrapper(charm: CharmBase, *args: Any, **kwargs: Any) -> Optional[Any]:
Expand Down Expand Up @@ -41,20 +53,19 @@ def wrapper(charm: CharmBase, *args: EventBase, **kwargs: Any) -> Optional[Any]:
return wrapper


def validate_integration_exists(integration_name: str) -> Callable:
def validate_integration_exists(
integration_name: str, on_missing: Optional[Callable] = None
) -> Callable:
on_missing_request = on_missing or _default_on_missing

def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(charm: CharmBase, *args: EventBase, **kwargs: Any) -> Optional[Any]:
event, *_ = args
logger.debug(f"Handling event: {event}")

if not charm.model.relations[integration_name]:
logger.debug(f"Integration {integration_name} is missing, defer event {event}.")
event.defer()

charm.unit.status = BlockedStatus(
f"Missing required integration {integration_name}"
)
on_missing_request(charm, event, integration_name=integration_name)
return None

return func(charm, *args, **kwargs)
Expand Down Expand Up @@ -85,6 +96,8 @@ def wrapper(charm: CharmBase, *args: EventBase, **kwargs: Any) -> Optional[Any]:
def after_config_updated(func: Callable) -> Callable:
@wraps(func)
def wrapper(charm: CharmBase, *args: Any, **kwargs: Any) -> Optional[Any]:
charm.unit.status = WaitingStatus("Waiting for configuration to be updated.")

for attempt in Retrying(
wait=wait_fixed(3),
):
Expand Down
23 changes: 18 additions & 5 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

from constants import DATABASE_INTEGRATION_NAME, WORKLOAD_CONTAINER
from ops.charm import CharmBase, HookEvent
from ops.model import BlockedStatus, WaitingStatus
from ops.model import ActiveStatus, BlockedStatus, WaitingStatus
from ops.testing import Harness
from utils import (
block_on_missing,
leader_unit,
validate_container_connectivity,
validate_database_resource,
Expand Down Expand Up @@ -51,28 +52,40 @@ def wrapped(charm: CharmBase, event: HookEvent) -> sentinel:
assert wrapped(harness.charm, mocked_hook_event) is None
assert isinstance(harness.model.unit.status, WaitingStatus)

def test_when_database_relation_integrated(
def test_when_relation_exists_with_block_request(
self,
harness: Harness,
database_relation: int,
mocked_hook_event: MagicMock,
) -> None:
@validate_integration_exists(DATABASE_INTEGRATION_NAME)
@validate_integration_exists(DATABASE_INTEGRATION_NAME, on_missing=block_on_missing)
def wrapped(charm: CharmBase, event: HookEvent) -> sentinel:
return sentinel

assert wrapped(harness.charm, mocked_hook_event) is sentinel

def test_when_database_relation_not_integrated(
def test_when_relation_not_exists_with_block_request(
self, harness: Harness, mocked_hook_event: MagicMock
) -> None:
@validate_integration_exists(DATABASE_INTEGRATION_NAME)
@validate_integration_exists(DATABASE_INTEGRATION_NAME, on_missing=block_on_missing)
def wrapped(charm: CharmBase, event: HookEvent) -> sentinel:
return sentinel

assert wrapped(harness.charm, mocked_hook_event) is None
assert isinstance(harness.model.unit.status, BlockedStatus)

def test_when_relation_not_exists_without_request(
self, harness: Harness, mocked_hook_event: MagicMock
) -> None:
harness.model.unit.status = ActiveStatus()

@validate_integration_exists(DATABASE_INTEGRATION_NAME)
def wrapped(charm: CharmBase, event: HookEvent) -> sentinel:
return sentinel

assert wrapped(harness.charm, mocked_hook_event) is None
assert isinstance(harness.model.unit.status, ActiveStatus)

def test_database_resource_created(
self, harness: Harness, database_resource: MagicMock, mocked_hook_event: MagicMock
) -> None:
Expand Down

0 comments on commit a3ba848

Please sign in to comment.