postgresql-charms-single-kernel 16.2.2__tar.gz → 16.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/PKG-INFO +12 -2
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/pyproject.toml +20 -8
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/charms/__init__.py +5 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/charms/abstract_charm.py +84 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/charms/k8s_charm.py +65 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/charms/vm_charm.py +58 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/config/enums.py +13 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/config/exceptions.py +27 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/config/literals.py +163 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/config/locales.py +527 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/config/statuses.py +47 -0
- {postgresql_charms_single_kernel-16.2.2/single_kernel_postgresql/events → postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/core}/__init__.py +1 -1
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/core/config.py +266 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/core/peer_relation.py +328 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/core/relation_state.py +110 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/core/state.py +405 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/events/__init__.py +3 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/events/postgresql.py +230 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/lib/charms/data_platform_libs/v0/data_interfaces.py +5774 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/lib/charms/data_platform_libs/v1/data_models.py +361 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/managers/__init__.py +8 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/managers/base.py +48 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/managers/cluster.py +150 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/managers/config.py +194 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/managers/k8s.py +162 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/managers/patroni.py +109 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/managers/tls.py +101 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/utils/__init__.py +14 -1
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/utils/arch.py +46 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/utils/postgresql.py +1 -1
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/utils/secret.py +14 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/utils/status.py +32 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/workload/__init__.py +12 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/workload/base.py +240 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/workload/k8s.py +203 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/workload/paths/__init__.py +7 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/workload/paths/base.py +70 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/workload/paths/k8s.py +63 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/workload/paths/vm.py +93 -0
- postgresql_charms_single_kernel-16.3.0/single_kernel_postgresql/workload/vm.py +225 -0
- postgresql_charms_single_kernel-16.2.2/single_kernel_postgresql/abstract_charm.py +0 -27
- postgresql_charms_single_kernel-16.2.2/single_kernel_postgresql/config/literals.py +0 -32
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/LICENSE +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/README.md +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/__init__.py +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/charmcraft.yaml +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/compat/__init__.py +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/compat/postgresql.py +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/compat/pyproject.toml +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/config/__init__.py +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/config/pyproject.toml +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/events/tls_transfer.py +0 -0
- {postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/single_kernel_postgresql/utils/filesystem.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: postgresql-charms-single-kernel
|
|
3
|
-
Version: 16.
|
|
3
|
+
Version: 16.3.0
|
|
4
4
|
Summary: Shared and reusable code for PostgreSQL-related charms
|
|
5
5
|
Author: Canonical Data Platform
|
|
6
6
|
Author-email: Canonical Data Platform <data-platform@lists.launchpad.net>
|
|
@@ -210,9 +210,19 @@ Classifier: Development Status :: 3 - Alpha
|
|
|
210
210
|
Classifier: Intended Audience :: Developers
|
|
211
211
|
Classifier: Operating System :: POSIX :: Linux
|
|
212
212
|
Requires-Dist: ops>=2.0.0
|
|
213
|
-
Requires-Dist: psycopg2>=2.9.10
|
|
214
213
|
Requires-Dist: tenacity>=9.0.0
|
|
214
|
+
Requires-Dist: psycopg2>=2.9.10 ; extra == 'postgresql'
|
|
215
215
|
Requires-Dist: httpx ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
216
|
+
Requires-Dist: data-platform-helpers>=0.1.7 ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
217
|
+
Requires-Dist: charmlibs-pathops>=1.0.1 ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
218
|
+
Requires-Dist: charmlibs-snap>=1.0.1 ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
219
|
+
Requires-Dist: charmlibs-interfaces-tls-certificates>=1.8.3 ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
220
|
+
Requires-Dist: charm-refresh ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
221
|
+
Requires-Dist: requests ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
222
|
+
Requires-Dist: tomli ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
223
|
+
Requires-Dist: pydantic>=2.0 ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
224
|
+
Requires-Dist: jinja2>=3.1.6 ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
225
|
+
Requires-Dist: charmlibs-rollingops>=1.1.1 ; python_full_version >= '3.12' and extra == 'postgresql'
|
|
216
226
|
Requires-Python: >=3.8, <4.0
|
|
217
227
|
Provides-Extra: postgresql
|
|
218
228
|
Description-Content-Type: text/markdown
|
{postgresql_charms_single_kernel-16.2.2 → postgresql_charms_single_kernel-16.3.0}/pyproject.toml
RENAMED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[project]
|
|
5
5
|
name = "postgresql-charms-single-kernel"
|
|
6
6
|
description = "Shared and reusable code for PostgreSQL-related charms"
|
|
7
|
-
version = "16.
|
|
7
|
+
version = "16.3.0"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
license = {file = "LICENSE"}
|
|
10
10
|
authors = [
|
|
@@ -18,12 +18,24 @@ classifiers = [
|
|
|
18
18
|
requires-python = ">=3.8,<4.0"
|
|
19
19
|
dependencies = [
|
|
20
20
|
"ops>=2.0.0",
|
|
21
|
-
"psycopg2>=2.9.10",
|
|
22
21
|
"tenacity>=9.0.0",
|
|
23
22
|
]
|
|
24
23
|
|
|
25
24
|
[project.optional-dependencies]
|
|
26
|
-
postgresql = [
|
|
25
|
+
postgresql = [
|
|
26
|
+
"psycopg2>=2.9.10",
|
|
27
|
+
"httpx; python_version >= '3.12'",
|
|
28
|
+
"data-platform-helpers>=0.1.7; python_version >= '3.12'",
|
|
29
|
+
"charmlibs-pathops>=1.0.1; python_version >= '3.12'",
|
|
30
|
+
"charmlibs-snap>=1.0.1; python_version >= '3.12'",
|
|
31
|
+
"charmlibs-interfaces-tls-certificates>=1.8.3; python_version >= '3.12'",
|
|
32
|
+
"charm-refresh; python_version >= '3.12'",
|
|
33
|
+
"requests; python_version >= '3.12'",
|
|
34
|
+
"tomli; python_version >= '3.12'",
|
|
35
|
+
"pydantic>=2.0; python_version >= '3.12'",
|
|
36
|
+
"jinja2 >=3.1.6; python_version >= '3.12'",
|
|
37
|
+
"charmlibs-rollingops>=1.1.1; python_version >= '3.12'",
|
|
38
|
+
]
|
|
27
39
|
|
|
28
40
|
[build-system]
|
|
29
41
|
requires = ["uv_build>=0.11.0,<0.12.0"]
|
|
@@ -35,15 +47,15 @@ module-root = ""
|
|
|
35
47
|
|
|
36
48
|
[dependency-groups]
|
|
37
49
|
format = [
|
|
38
|
-
"ruff==0.15.
|
|
50
|
+
"ruff==0.15.17"
|
|
39
51
|
]
|
|
40
52
|
lint = [
|
|
41
53
|
"codespell==2.4.2",
|
|
42
|
-
"ty==0.0.
|
|
54
|
+
"ty==0.0.49"
|
|
43
55
|
]
|
|
44
56
|
unit = [
|
|
45
|
-
"coverage[toml]==7.14.
|
|
46
|
-
"pytest==9.0
|
|
57
|
+
"coverage[toml]==7.14.1",
|
|
58
|
+
"pytest==9.1.0"
|
|
47
59
|
]
|
|
48
60
|
|
|
49
61
|
|
|
@@ -117,4 +129,4 @@ python = ".tox/lint/"
|
|
|
117
129
|
python-version = "3.12"
|
|
118
130
|
|
|
119
131
|
[tool.ty.src]
|
|
120
|
-
exclude = ["tests"]
|
|
132
|
+
exclude = ["tests", "single_kernel_postgresql/lib"]
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Copyright 2025 Canonical Ltd.
|
|
2
|
+
# See LICENSE file for licensing details.
|
|
3
|
+
"""Skeleton for the abstract charm."""
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
|
|
7
|
+
from data_platform_helpers.advanced_statuses import StatusHandler
|
|
8
|
+
from ops.charm import CharmBase
|
|
9
|
+
|
|
10
|
+
from single_kernel_postgresql.core.state import CharmState
|
|
11
|
+
from single_kernel_postgresql.events.postgresql import PostgreSQLEventsHandler
|
|
12
|
+
from single_kernel_postgresql.managers.cluster import ClusterManager
|
|
13
|
+
from single_kernel_postgresql.managers.config import ConfigManager
|
|
14
|
+
from single_kernel_postgresql.managers.patroni import PatroniManager
|
|
15
|
+
from single_kernel_postgresql.managers.tls import TLSManager
|
|
16
|
+
from single_kernel_postgresql.workload.base import BaseWorkload
|
|
17
|
+
|
|
18
|
+
from ..config.enums import Substrates
|
|
19
|
+
from ..utils.postgresql import PostgreSQL
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AbstractPostgreSQLCharm(CharmBase, ABC):
|
|
23
|
+
"""An abstract PostgreSQL charm."""
|
|
24
|
+
|
|
25
|
+
def __init__(self, *args):
|
|
26
|
+
super().__init__(*args)
|
|
27
|
+
|
|
28
|
+
# State
|
|
29
|
+
self.state = CharmState(charm=self, substrate=self.substrate)
|
|
30
|
+
|
|
31
|
+
# Managers
|
|
32
|
+
self.cluster_manager = ClusterManager(
|
|
33
|
+
state=self.state, workload=self.workload, client=self.postgresql
|
|
34
|
+
)
|
|
35
|
+
self.tls_manager = TLSManager(
|
|
36
|
+
state=self.state, workload=self.workload, client=self.postgresql
|
|
37
|
+
)
|
|
38
|
+
self.config_manager = ConfigManager(
|
|
39
|
+
state=self.state, workload=self.workload, client=self.postgresql
|
|
40
|
+
)
|
|
41
|
+
self.patroni_manager = PatroniManager(
|
|
42
|
+
state=self.state, workload=self.workload, client=self.postgresql
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Events Handler
|
|
46
|
+
self.postgresql_events_handler = PostgreSQLEventsHandler(
|
|
47
|
+
self,
|
|
48
|
+
self.workload,
|
|
49
|
+
self.state,
|
|
50
|
+
self.cluster_manager,
|
|
51
|
+
self.tls_manager,
|
|
52
|
+
self.config_manager,
|
|
53
|
+
self.patroni_manager,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Status Handler
|
|
57
|
+
self.status_handler = StatusHandler(
|
|
58
|
+
self,
|
|
59
|
+
self.cluster_manager,
|
|
60
|
+
self.tls_manager,
|
|
61
|
+
self.config_manager,
|
|
62
|
+
self.patroni_manager,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Postgresql Client
|
|
66
|
+
@property
|
|
67
|
+
@abstractmethod
|
|
68
|
+
def postgresql(self) -> PostgreSQL:
|
|
69
|
+
"""Return a PostgreSQL client."""
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
# Postgresql Workload
|
|
73
|
+
@property
|
|
74
|
+
@abstractmethod
|
|
75
|
+
def workload(self) -> BaseWorkload:
|
|
76
|
+
"""Access current workload."""
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
# Postgresql Substrate
|
|
80
|
+
@property
|
|
81
|
+
@abstractmethod
|
|
82
|
+
def substrate(self) -> Substrates:
|
|
83
|
+
"""Access current substrate."""
|
|
84
|
+
pass
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Copyright 2025 Canonical Ltd.
|
|
3
|
+
# See LICENSE file for licensing details.
|
|
4
|
+
|
|
5
|
+
"""PostgreSQL Kubernetes Charm."""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
from single_kernel_postgresql.charms.abstract_charm import AbstractPostgreSQLCharm, PostgreSQL
|
|
10
|
+
from single_kernel_postgresql.config.enums import Substrates
|
|
11
|
+
from single_kernel_postgresql.config.literals import CONTAINER_NAME, SYSTEM_USERS, USER
|
|
12
|
+
from single_kernel_postgresql.managers.k8s import K8sManager
|
|
13
|
+
from single_kernel_postgresql.workload.base import BaseWorkload
|
|
14
|
+
from single_kernel_postgresql.workload.k8s import K8sWorkload
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PostgreSQLK8sCharm(AbstractPostgreSQLCharm):
|
|
20
|
+
"""PostgreSQL K8s Charm."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, *args):
|
|
23
|
+
"""Initialize the PostgreSQL Kubernetes Charm."""
|
|
24
|
+
super().__init__(*args)
|
|
25
|
+
assert isinstance(self.workload, K8sWorkload), ( # noqa: S101
|
|
26
|
+
"Workload must be an instance of K8sWorkload"
|
|
27
|
+
)
|
|
28
|
+
self.k8s_manager = K8sManager(self.state, self.workload, self.postgresql)
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def postgresql(self) -> PostgreSQL:
|
|
32
|
+
"""Return a PostgreSQL client."""
|
|
33
|
+
return PostgreSQL(
|
|
34
|
+
substrate=Substrates.K8S,
|
|
35
|
+
primary_host="localhost",
|
|
36
|
+
current_host="localhost",
|
|
37
|
+
user=USER,
|
|
38
|
+
# The password is hardcoded because this is an abstract charm and
|
|
39
|
+
# it meant to be used only in unit tests.
|
|
40
|
+
password="test-password", # noqa S106
|
|
41
|
+
database="test-database",
|
|
42
|
+
system_users=SYSTEM_USERS,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def workload(self) -> BaseWorkload:
|
|
47
|
+
"""Access current workload instance.
|
|
48
|
+
|
|
49
|
+
Returns the workload object.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
BaseWorkload: The K8sWorkload instance for this charm
|
|
53
|
+
"""
|
|
54
|
+
return K8sWorkload(
|
|
55
|
+
charm_dir=self.charm_dir, container=self.unit.get_container(CONTAINER_NAME)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def substrate(self) -> Substrates:
|
|
60
|
+
"""Access current substrate type.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Substrates: always Substrates.K8S for this charm
|
|
64
|
+
"""
|
|
65
|
+
return Substrates.K8S
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Copyright 2025 Canonical Ltd.
|
|
3
|
+
# See LICENSE file for licensing details.
|
|
4
|
+
|
|
5
|
+
"""PostgreSQL VM Charm."""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
from single_kernel_postgresql.charms.abstract_charm import AbstractPostgreSQLCharm, PostgreSQL
|
|
10
|
+
from single_kernel_postgresql.config.enums import Substrates
|
|
11
|
+
from single_kernel_postgresql.config.literals import SYSTEM_USERS, USER
|
|
12
|
+
from single_kernel_postgresql.workload.base import BaseWorkload
|
|
13
|
+
from single_kernel_postgresql.workload.vm import VMWorkload
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class PostgreSQLVMCharm(AbstractPostgreSQLCharm):
|
|
19
|
+
"""PostgreSQL VM Charm."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, *args):
|
|
22
|
+
"""Initialize the PostgreSQL VM Charm."""
|
|
23
|
+
super().__init__(*args)
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def postgresql(self) -> PostgreSQL:
|
|
27
|
+
"""Return a PostgreSQL client."""
|
|
28
|
+
return PostgreSQL(
|
|
29
|
+
substrate=Substrates.VM,
|
|
30
|
+
primary_host="localhost",
|
|
31
|
+
current_host="localhost",
|
|
32
|
+
user=USER,
|
|
33
|
+
# The password is hardcoded because this is an abstract charm and
|
|
34
|
+
# it meant to be used only in unit tests.
|
|
35
|
+
password="test-password", # noqa S106
|
|
36
|
+
database="test-database",
|
|
37
|
+
system_users=SYSTEM_USERS,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def workload(self) -> BaseWorkload:
|
|
42
|
+
"""Access current workload instance.
|
|
43
|
+
|
|
44
|
+
Returns the workload object.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
BaseWorkload: The VMWorkload instance for this charm
|
|
48
|
+
"""
|
|
49
|
+
return VMWorkload(charm_dir=self.charm_dir)
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def substrate(self) -> Substrates:
|
|
53
|
+
"""Access current substrate type.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Substrates: always Substrates.VM for this charm
|
|
57
|
+
"""
|
|
58
|
+
return Substrates.VM
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Copyright 2025 Canonical Ltd.
|
|
3
|
+
# See LICENSE file for licensing details.
|
|
4
|
+
|
|
5
|
+
"""Charm-specific exceptions."""
|
|
6
|
+
|
|
7
|
+
from single_kernel_postgresql.compat.postgresql import PostgreSQLBaseError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PostgreSQLFileOperationError(PostgreSQLBaseError):
|
|
11
|
+
"""Exception thrown when file operations related to PostgreSQL fail."""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class StorageUnavailableError(Exception):
|
|
15
|
+
"""Cannot find storage mountpoint."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SettingSystemPasswordError(PostgreSQLBaseError):
|
|
19
|
+
"""Exception thrown when setting the system password fails."""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PostgreSQLCannotConnectError(Exception):
|
|
23
|
+
"""Cannot run smoke check on connected Database."""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TlsError(Exception):
|
|
27
|
+
"""TLS implementation internal exception."""
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Copyright 2025 Canonical Ltd.
|
|
2
|
+
# See LICENSE file for licensing details.
|
|
3
|
+
"""Literal string for the different charms.
|
|
4
|
+
|
|
5
|
+
This module should contain the literals used in the charms (paths, relation names, etc).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
# Permissions.
|
|
11
|
+
POSTGRESQL_STORAGE_PERMISSIONS = 0o700
|
|
12
|
+
|
|
13
|
+
# Relations
|
|
14
|
+
PEER_RELATION = "database-peers"
|
|
15
|
+
STATUS_PEERS_RELATION = "status-peers"
|
|
16
|
+
|
|
17
|
+
# Users.
|
|
18
|
+
BACKUP_USER = "backup"
|
|
19
|
+
MONITORING_USER = "monitoring"
|
|
20
|
+
REPLICATION_USER = "replication"
|
|
21
|
+
REWIND_USER = "rewind"
|
|
22
|
+
SNAP_USER = "_daemon_"
|
|
23
|
+
USER = "operator"
|
|
24
|
+
SYSTEM_USERS = [BACKUP_USER, MONITORING_USER, REPLICATION_USER, REWIND_USER, USER]
|
|
25
|
+
|
|
26
|
+
# Paths
|
|
27
|
+
## VM Paths
|
|
28
|
+
BASE_SNAP_DIR = "/var/snap/charmed-postgresql"
|
|
29
|
+
SNAP_DATA = "current"
|
|
30
|
+
SNAP_COMMON = "common"
|
|
31
|
+
SNAP = "/snap/charmed-postgresql/current"
|
|
32
|
+
VM_LOGS_PATH = "var/log/postgresql"
|
|
33
|
+
VM_DATA_PATH = "var/lib/postgresql"
|
|
34
|
+
|
|
35
|
+
## K8s Paths
|
|
36
|
+
K8S_DATA_PATH = "var/lib/pg/data"
|
|
37
|
+
|
|
38
|
+
## Shared Paths
|
|
39
|
+
# NOTE: The paths don't have leading slahes since pathops
|
|
40
|
+
# will handle path concatenation otherwise it will use "/var/lib/postgresql"
|
|
41
|
+
# instead of using the root path or any other part defined by the / operator.
|
|
42
|
+
# e.g. snap_current / "/etc/postgresql" will result in "/etc/postgresql" instead of "/var/snap/postgresql/current/etc/postgresql"
|
|
43
|
+
POSTGRESQL_CONF_PATH = "etc/postgresql"
|
|
44
|
+
POSTGRESQL_CONF_FILE = "postgresql.conf"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## TLS Paths
|
|
48
|
+
TLS_CA_BUNDLE_FILE = "peer_ca_bundle.pem"
|
|
49
|
+
|
|
50
|
+
# Scopes
|
|
51
|
+
SCOPES = Literal["app", "unit"]
|
|
52
|
+
APP_SCOPE = "app"
|
|
53
|
+
UNIT_SCOPE = "unit"
|
|
54
|
+
|
|
55
|
+
# Patroni
|
|
56
|
+
## Patroni Paths
|
|
57
|
+
PATRONI_CONF_PATH = "etc/patroni"
|
|
58
|
+
PATRONI_LOGS_PATH = "var/log/patroni"
|
|
59
|
+
## Patroni states
|
|
60
|
+
STARTED_STATES = ["running", "streaming"]
|
|
61
|
+
RUNNING_STATES = [*STARTED_STATES, "starting"]
|
|
62
|
+
## Patroni config
|
|
63
|
+
ORIGINAL_PATRONI_ON_FAILURE_CONDITION = "restart"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# Secrets
|
|
67
|
+
SECRET_KEY_OVERRIDES = {"ca": "cauth"}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Password keys
|
|
71
|
+
REPLICATION_PASSWORD_KEY = "replication-password" # noqa: S105
|
|
72
|
+
REWIND_PASSWORD_KEY = "rewind-password" # noqa: S105
|
|
73
|
+
USER_PASSWORD_KEY = "operator-password" # noqa: S105
|
|
74
|
+
MONITORING_PASSWORD_KEY = "monitoring-password" # noqa: S105
|
|
75
|
+
RAFT_PASSWORD_KEY = "raft-password" # noqa: S105
|
|
76
|
+
PATRONI_PASSWORD_KEY = "patroni-password" # noqa: S105
|
|
77
|
+
SECRET_INTERNAL_LABEL = "internal-secret" # noqa: S105
|
|
78
|
+
SECRET_DELETED_LABEL = "None" # noqa: S105
|
|
79
|
+
SYSTEM_USERS_PASSWORD_CONFIG = "system-users" # noqa: S105
|
|
80
|
+
|
|
81
|
+
# K8s
|
|
82
|
+
## K8s Services
|
|
83
|
+
K8S_POSTGRESQL_SERVICE_NAME = "postgresql"
|
|
84
|
+
K8S_PGBACK_REST_SERVER_SERVICE_NAME = "pgbackrest server"
|
|
85
|
+
K8S_LDAP_SYNC_SERVICE_NAME = "ldap-sync"
|
|
86
|
+
K8S_METRICS_SERVER_SERVICE_NAME = "metrics_server"
|
|
87
|
+
K8S_PGBACKREST_METRICS_SERVER_SERVICE_NAME = "pgbackrest_metrics_server"
|
|
88
|
+
K8S_ROTATE_LOGS_SERVICE_NAME = "rotate-logs"
|
|
89
|
+
## K8s User and group
|
|
90
|
+
K8S_WORKLOAD_OS_GROUP = "postgres"
|
|
91
|
+
K8S_WORKLOAD_OS_USER = "postgres"
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# File permissions as octal
|
|
95
|
+
# standard directory permissions
|
|
96
|
+
DIR_PERMISSIONS_READONLY = 0o750
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# Container name for K8s deployments
|
|
100
|
+
CONTAINER_NAME = "postgresql"
|
|
101
|
+
|
|
102
|
+
API_REQUEST_TIMEOUT = 5
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# --- Shared constants migrated from the charms ---
|
|
106
|
+
|
|
107
|
+
# Database
|
|
108
|
+
DATABASE = "database"
|
|
109
|
+
DATABASE_DEFAULT_NAME = "postgres"
|
|
110
|
+
DATABASE_PORT = "5432"
|
|
111
|
+
|
|
112
|
+
# Client relations
|
|
113
|
+
ALL_CLIENT_RELATIONS = [DATABASE]
|
|
114
|
+
|
|
115
|
+
# Async replication relations
|
|
116
|
+
REPLICATION_CONSUMER_RELATION = "replication"
|
|
117
|
+
REPLICATION_OFFER_RELATION = "replication-offer"
|
|
118
|
+
|
|
119
|
+
# TLS files
|
|
120
|
+
TLS_KEY_FILE = "key.pem"
|
|
121
|
+
TLS_CA_FILE = "ca.pem"
|
|
122
|
+
TLS_CERT_FILE = "cert.pem"
|
|
123
|
+
|
|
124
|
+
# Metrics ports (kept as str to match the K8s charm; VM adapts on flip)
|
|
125
|
+
METRICS_PORT = "9187"
|
|
126
|
+
PGBACKREST_METRICS_PORT = "9854"
|
|
127
|
+
|
|
128
|
+
# Secret/database mapping labels
|
|
129
|
+
USERNAME_MAPPING_LABEL = "custom-usernames"
|
|
130
|
+
DATABASE_MAPPING_LABEL = "prefix-databases"
|
|
131
|
+
|
|
132
|
+
# Overrides
|
|
133
|
+
BACKUP_TYPE_OVERRIDES = {"full": "full", "differential": "diff", "incremental": "incr"}
|
|
134
|
+
PLUGIN_OVERRIDES = {"audit": "pgaudit", "uuid_ossp": '"uuid-ossp"'}
|
|
135
|
+
|
|
136
|
+
# SPI extension modules
|
|
137
|
+
SPI_MODULE = ["refint", "autoinc", "insert_username", "moddatetime"]
|
|
138
|
+
|
|
139
|
+
# Tracing
|
|
140
|
+
TRACING_RELATION_NAME = "tracing"
|
|
141
|
+
TRACING_PROTOCOL = "otlp_http"
|
|
142
|
+
|
|
143
|
+
# Patroni
|
|
144
|
+
PATRONI_CLUSTER_STATUS_ENDPOINT = "cluster"
|
|
145
|
+
|
|
146
|
+
# pgBackRest
|
|
147
|
+
PGBACKREST_LOGROTATE_FILE = "/etc/logrotate.d/pgbackrest.logrotate"
|
|
148
|
+
# pgBackRest emits all error/warning output on stderr (the default is stdout) so error
|
|
149
|
+
# extraction stays consistent. Reference: https://pgbackrest.org/configuration.html#section-log
|
|
150
|
+
PGBACKREST_LOG_LEVEL_STDERR = "--log-level-stderr=warn"
|
|
151
|
+
# Archive timeout: unable to archive WAL files within the configured timeout period.
|
|
152
|
+
PGBACKREST_ARCHIVE_TIMEOUT_ERROR_CODE = 82
|
|
153
|
+
|
|
154
|
+
# Backup ID formats
|
|
155
|
+
BACKUP_ID_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
|
|
156
|
+
PGBACKREST_BACKUP_ID_FORMAT = "%Y%m%d-%H%M%S"
|
|
157
|
+
|
|
158
|
+
# Watcher relation (VM)
|
|
159
|
+
WATCHER_OFFER_RELATION = "watcher-offer"
|
|
160
|
+
WATCHER_RELATION = "watcher"
|
|
161
|
+
WATCHER_USER = "watcher"
|
|
162
|
+
WATCHER_PASSWORD_KEY = "watcher-password" # noqa: S105
|
|
163
|
+
WATCHER_SECRET_LABEL = "watcher-secret" # noqa: S105
|