Skip to content

Commit

Permalink
[DPE-2055] PGB extensions suport (#93)
Browse files Browse the repository at this point in the history
* Update snap charm lib

* Update lock

* Initial plugin support

* Integration test
  • Loading branch information
dragomirp authored Jun 28, 2023
1 parent 8fc0517 commit 4f35b23
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 46 deletions.
1 change: 1 addition & 0 deletions charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ parts:
charm:
charm-binary-python-packages:
- psycopg2-binary==2.9.6 # renovate
- psycopg[binary]==3.1.9 # renovate
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@
LIBID = "05394e5893f94f2d90feb7cbe6b633cd"

# Increment this major API version when introducing breaking changes
LIBAPI = 1
LIBAPI = 2

# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 12
LIBPATCH = 0


# Regex to locate 7-bit C1 ANSI sequences
Expand Down Expand Up @@ -222,7 +222,7 @@ def __init__(
name,
state: SnapState,
channel: str,
revision: int,
revision: str,
confinement: str,
apps: Optional[List[Dict[str, str]]] = None,
cohort: Optional[str] = "",
Expand Down Expand Up @@ -415,7 +415,7 @@ def restart(
"""Restarts a snap's services.
Args:
services (list): (optional) list of individual snap services to show logs from.
services (list): (optional) list of individual snap services to restart.
(otherwise all)
reload (bool): (optional) flag to use the service reload command, if available.
Default `False`
Expand All @@ -427,7 +427,7 @@ def _install(
self,
channel: Optional[str] = "",
cohort: Optional[str] = "",
revision: Optional[int] = None,
revision: Optional[str] = None,
) -> None:
"""Add a snap to the system.
Expand All @@ -454,7 +454,7 @@ def _refresh(
self,
channel: Optional[str] = "",
cohort: Optional[str] = "",
revision: Optional[int] = None,
revision: Optional[str] = None,
leave_cohort: Optional[bool] = False,
) -> None:
"""Refresh a snap.
Expand Down Expand Up @@ -498,7 +498,7 @@ def ensure(
classic: Optional[bool] = False,
channel: Optional[str] = "",
cohort: Optional[str] = "",
revision: Optional[int] = None,
revision: Optional[str] = None,
):
"""Ensure that a snap is in a given state.
Expand Down Expand Up @@ -575,7 +575,7 @@ def state(self, state: SnapState) -> None:
self._state = state

@property
def revision(self) -> int:
def revision(self) -> str:
"""Returns the revision for a snap."""
return self._revision

Expand Down Expand Up @@ -828,7 +828,7 @@ def _load_installed_snaps(self) -> None:
name=i["name"],
state=SnapState.Latest,
channel=i["channel"],
revision=int(i["revision"]),
revision=i["revision"],
confinement=i["confinement"],
apps=i.get("apps", None),
)
Expand All @@ -846,7 +846,7 @@ def _load_info(self, name) -> Snap:
name=info["name"],
state=SnapState.Available,
channel=info["channel"],
revision=int(info["revision"]),
revision=info["revision"],
confinement=info["confinement"],
apps=None,
)
Expand All @@ -859,7 +859,7 @@ def add(
channel: Optional[str] = "",
classic: Optional[bool] = False,
cohort: Optional[str] = "",
revision: Optional[int] = None,
revision: Optional[str] = None,
) -> Union[Snap, List[Snap]]:
"""Add a snap to the system.
Expand All @@ -871,7 +871,7 @@ def add(
classic: an (Optional) boolean specifying whether it should be added with classic
confinement. Default `False`
cohort: an (Optional) string specifying the snap cohort to use
revision: an (Optional) integer specifying the snap revision to use
revision: an (Optional) string specifying the snap revision to use
Raises:
SnapError if some snaps failed to install or were not found.
Expand Down Expand Up @@ -947,7 +947,7 @@ def _wrap_snap_operations(
channel: str,
classic: bool,
cohort: Optional[str] = "",
revision: Optional[int] = None,
revision: Optional[str] = None,
) -> Union[Snap, List[Snap]]:
"""Wrap common operations for bare commands."""
snaps = {"success": [], "failed": []}
Expand Down
38 changes: 27 additions & 11 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ optional = true

[tool.poetry.group.relation_charm.dependencies]
ops = "2.3.0"
ops-lib-pgsql = "1.4"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
2 changes: 1 addition & 1 deletion renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"extractVersionTemplate": "Juju release"
}, {
"fileMatch": ["(^|/)([\\w-]*)charmcraft\\.ya?ml$"],
"matchStrings": ["- (?<depName>.*?)==(?<currentValue>.*?) +# renovate"],
"matchStrings": ["- (?<depName>.*?)(?:\\[.*?\\])?==(?<currentValue>.*?) +# renovate"],
"datasourceTemplate": "pypi",
"versioningTemplate": "loose"
}
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,6 @@ tenacity==8.2.2 ; python_full_version >= "3.8.10" and python_full_version < "4.0
typing-extensions==4.6.3 ; python_full_version >= "3.8.10" and python_full_version < "4.0.0" \
--hash=sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26 \
--hash=sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5
websocket-client==1.6.1; python_full_version >= "3.8.10" and python_full_version < "4.0.0" \
websocket-client==1.6.1 ; python_full_version >= "3.8.10" and python_full_version < "4.0.0" \
--hash=sha256:c951af98631d24f8df89ab1019fc365f2227c0892f12fd150e935607c79dd0dd \
--hash=sha256:f1f9f2ad5291f0225a49efad77abf9e700b6fef553900623060dad6e26503b9d
7 changes: 6 additions & 1 deletion src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
from typing import List, Optional, Union

from charms.grafana_agent.v0.cos_agent import COSAgentProvider
from charms.operator_libs_linux.v1 import snap, systemd
from charms.operator_libs_linux.v1 import systemd
from charms.operator_libs_linux.v2 import snap
from charms.pgbouncer_k8s.v0 import pgb
from jinja2 import Template
from ops.charm import CharmBase
Expand All @@ -24,6 +25,7 @@
from constants import (
AUTH_FILE_NAME,
CLIENT_RELATION_NAME,
EXTENSIONS_BLOCKING_MESSAGE,
INI_NAME,
MONITORING_PASSWORD_KEY,
PEER_RELATION_NAME,
Expand Down Expand Up @@ -266,6 +268,9 @@ def check_status(self) -> Union[ActiveStatus, BlockedStatus, WaitingStatus]:
logger.warning(backend_wait_msg)
return BlockedStatus(backend_wait_msg)

if self.unit.status.message == EXTENSIONS_BLOCKING_MESSAGE:
return BlockedStatus(EXTENSIONS_BLOCKING_MESSAGE)

prom_service = f"{PGB}-{self.app.name}-prometheus"
services = [*self.pgb_services]

Expand Down
4 changes: 3 additions & 1 deletion src/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# Snap constants.
PGBOUNCER_EXECUTABLE = "charmed-postgresql.pgbouncer"
POSTGRESQL_SNAP_NAME = "charmed-postgresql"
SNAP_PACKAGES = [(POSTGRESQL_SNAP_NAME, {"revision": 62})]
SNAP_PACKAGES = [(POSTGRESQL_SNAP_NAME, {"revision": "62"})]

SNAP_COMMON_PATH = "/var/snap/charmed-postgresql/common"
SNAP_CURRENT_PATH = "/var/snap/charmed-postgresql/current"
Expand All @@ -33,3 +33,5 @@
CLIENT_RELATION_NAME = "database"

MONITORING_PASSWORD_KEY = "monitoring_password"

EXTENSIONS_BLOCKING_MESSAGE = "bad relation request - remote app requested extensions, which are unsupported. Please remove this relation."
47 changes: 31 additions & 16 deletions src/relations/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
""" # noqa: W505

import logging
from typing import Dict, Iterable
from typing import Dict, Iterable, List

from charms.pgbouncer_k8s.v0 import pgb
from charms.postgresql_k8s.v0.postgresql import (
Expand All @@ -111,7 +111,7 @@
WaitingStatus,
)

from constants import PG
from constants import EXTENSIONS_BLOCKING_MESSAGE, PG

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -165,6 +165,34 @@ def __init__(self, charm: CharmBase, admin: bool = False):
self.charm = charm
self.admin = admin

def _check_extensions(self, extensions: List) -> bool:
"""Checks if requested extensions are enabled."""
for extension in extensions:
extension_name = extension.split(":")[0]
if not self.charm.backend.database.is_postgresql_plugin_enabled(extension_name):
return False
return True

def _block_on_extensions(self, relation, remote_app_databag: Dict) -> bool:
"""Verifies that extensions are enabled or blocks the charm."""
if "extensions" in remote_app_databag:
self.update_databags(
relation,
{
"extensions": remote_app_databag["extensions"],
},
)
extensions = remote_app_databag["extensions"].split(",")
if not self._check_extensions(extensions):
# Do not allow apps requesting extensions to be installed.
logger.error(
f"ERROR - `extensions` ({', '.join(extensions)}) cannot be requested through relations"
" - Please enable extensions through `juju config` and add the relation again."
)
self.charm.unit.status = BlockedStatus(EXTENSIONS_BLOCKING_MESSAGE)
return True
return False

def _on_relation_joined(self, join_event: RelationJoinedEvent):
"""Handle db-relation-joined event.
Expand Down Expand Up @@ -193,20 +221,7 @@ def _on_relation_joined(self, join_event: RelationJoinedEvent):
join_event.defer()
return

# Do not allow apps requesting extensions to be installed. Extensions should be installed
# through db charm config
if (
remote_app_databag.get("extensions") is not None
or remote_unit_databag.get("extensions") is not None
):
logger.error(
"ERROR - `extensions` cannot be requested through relations"
" - they should be installed through a database charm config in the future"
)
self.charm.unit.status = BlockedStatus(
"bad relation request - remote app requested extensions, which are unsupported. Please remove this relation."
)
join_event.fail()
if self._block_on_extensions(join_event.relation, remote_app_databag):
return

user = self._generate_username(join_event)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ requires:
interface: postgresql_client
multiple-database-clusters:
interface: postgresql_client
db:
interface: pgsql
limit: 1
optional: true
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
ops-lib-pgsql==1.4 ; python_full_version >= "3.8.10" and python_full_version < "4.0.0" \
--hash=sha256:3ea802a1a9e6be4457dbe49959a76c50d63b689abc1b803c127bd24e5bd98654 \
--hash=sha256:85b07a364339da2423c2631680f03aab8f9b4d8a6493efc66303224ff9ab34af
ops==2.3.0 ; python_full_version >= "3.8.10" and python_full_version < "4.0.0" \
--hash=sha256:24a5c6e985d3f08cb3dfccfd1adb93ca9247dc867b192baaf3265fe5736fd992 \
--hash=sha256:438c217be75f641948114bc24ecbb2adca2b5e407b401401e1b7dbc0f912731b
pgconnstr==1.0.1 ; python_full_version >= "3.8.10" and python_full_version < "4.0.0" \
--hash=sha256:0656129961ae879675d0842f5237db82d31ce59c7b3211b051c33e37a864826e \
--hash=sha256:0f65830e7e3b76adf4390a8592ee52343171a17caef7436257e7bc81c44e21a7
pyyaml==6.0 ; python_full_version >= "3.8.10" and python_full_version < "4.0.0" \
--hash=sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf \
--hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \
Expand Down Expand Up @@ -42,6 +48,6 @@ pyyaml==6.0 ; python_full_version >= "3.8.10" and python_full_version < "4.0.0"
--hash=sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f \
--hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \
--hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5
websocket-client==1.6.1; python_full_version >= "3.8.10" and python_full_version < "4.0.0" \
websocket-client==1.6.1 ; python_full_version >= "3.8.10" and python_full_version < "4.0.0" \
--hash=sha256:c951af98631d24f8df89ab1019fc365f2227c0892f12fd150e935607c79dd0dd \
--hash=sha256:f1f9f2ad5291f0225a49efad77abf9e700b6fef553900623060dad6e26503b9d
Loading

0 comments on commit 4f35b23

Please sign in to comment.