Skip to content

Commit baef092

Browse files
authored
Update snap, charm libs and switch away from psycopg2-binary (#372)
1 parent 15b921c commit baef092

File tree

8 files changed

+127
-33
lines changed

8 files changed

+127
-33
lines changed

charmcraft.yaml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,13 @@ parts:
2525
- cargo
2626
- pkg-config
2727
charm-strict-dependencies: true
28-
charm-binary-python-packages:
29-
- psycopg2-binary
28+
libpq:
29+
build-packages:
30+
- libpq-dev
31+
plugin: dump
32+
source: /usr/lib/
33+
source-type: local
34+
prime:
35+
- lib/
36+
organize:
37+
"*-linux-gnu/libpq.so*": lib/

lib/charms/data_platform_libs/v0/data_interfaces.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def _on_topic_requested(self, event: TopicRequestedEvent):
320320

321321
# Increment this PATCH version before using `charmcraft publish-lib` or reset
322322
# to 0 if you are raising the major API version
323-
LIBPATCH = 27
323+
LIBPATCH = 28
324324

325325
PYDEPS = ["ops>=2.0.0"]
326326

@@ -1796,6 +1796,17 @@ def database(self) -> Optional[str]:
17961796
class DatabaseRequestedEvent(DatabaseProvidesEvent, ExtraRoleEvent):
17971797
"""Event emitted when a new database is requested for use on this relation."""
17981798

1799+
@property
1800+
def external_node_connectivity(self) -> bool:
1801+
"""Returns the requested external_node_connectivity field."""
1802+
if not self.relation.app:
1803+
return False
1804+
1805+
return (
1806+
self.relation.data[self.relation.app].get("external-node-connectivity", "false")
1807+
== "true"
1808+
)
1809+
17991810

18001811
class DatabaseProvidesEvents(CharmEvents):
18011812
"""Database events.
@@ -2014,11 +2025,13 @@ def __init__(
20142025
extra_user_roles: Optional[str] = None,
20152026
relations_aliases: Optional[List[str]] = None,
20162027
additional_secret_fields: Optional[List[str]] = [],
2028+
external_node_connectivity: bool = False,
20172029
):
20182030
"""Manager of database client relations."""
20192031
super().__init__(charm, relation_name, extra_user_roles, additional_secret_fields)
20202032
self.database = database_name
20212033
self.relations_aliases = relations_aliases
2034+
self.external_node_connectivity = external_node_connectivity
20222035

20232036
# Define custom event names for each alias.
20242037
if relations_aliases:
@@ -2169,16 +2182,16 @@ def _on_relation_created_event(self, event: RelationCreatedEvent) -> None:
21692182
if not self.local_unit.is_leader():
21702183
return
21712184

2185+
event_data = {"database": self.database}
2186+
21722187
if self.extra_user_roles:
2173-
self.update_relation_data(
2174-
event.relation.id,
2175-
{
2176-
"database": self.database,
2177-
"extra-user-roles": self.extra_user_roles,
2178-
},
2179-
)
2180-
else:
2181-
self.update_relation_data(event.relation.id, {"database": self.database})
2188+
event_data["extra-user-roles"] = self.extra_user_roles
2189+
2190+
# set external-node-connectivity field
2191+
if self.external_node_connectivity:
2192+
event_data["external-node-connectivity"] = "true"
2193+
2194+
self.update_relation_data(event.relation.id, event_data)
21822195

21832196
def _on_relation_changed_event(self, event: RelationChangedEvent) -> None:
21842197
"""Event emitted when the database relation has changed."""

lib/charms/operator_libs_linux/v2/snap.py

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383

8484
# Increment this PATCH version before using `charmcraft publish-lib` or reset
8585
# to 0 if you are raising the major API version
86-
LIBPATCH = 3
86+
LIBPATCH = 4
8787

8888

8989
# Regex to locate 7-bit C1 ANSI sequences
@@ -214,7 +214,7 @@ class Snap(object):
214214
- state: a `SnapState` representation of its install status
215215
- channel: "stable", "candidate", "beta", and "edge" are common
216216
- revision: a string representing the snap's revision
217-
- confinement: "classic" or "strict"
217+
- confinement: "classic", "strict", or "devmode"
218218
"""
219219

220220
def __init__(
@@ -475,6 +475,8 @@ def _install(
475475
args = []
476476
if self.confinement == "classic":
477477
args.append("--classic")
478+
if self.confinement == "devmode":
479+
args.append("--devmode")
478480
if channel:
479481
args.append('--channel="{}"'.format(channel))
480482
if revision:
@@ -489,6 +491,7 @@ def _refresh(
489491
channel: Optional[str] = "",
490492
cohort: Optional[str] = "",
491493
revision: Optional[str] = None,
494+
devmode: bool = False,
492495
leave_cohort: Optional[bool] = False,
493496
) -> None:
494497
"""Refresh a snap.
@@ -497,6 +500,7 @@ def _refresh(
497500
channel: the channel to install from
498501
cohort: optionally, specify a cohort.
499502
revision: optionally, specify the revision of the snap to refresh
503+
devmode: optionally, specify devmode confinement
500504
leave_cohort: leave the current cohort.
501505
"""
502506
args = []
@@ -506,6 +510,9 @@ def _refresh(
506510
if revision:
507511
args.append('--revision="{}"'.format(revision))
508512

513+
if devmode:
514+
args.append("--devmode")
515+
509516
if not cohort:
510517
cohort = self._cohort
511518

@@ -530,6 +537,7 @@ def ensure(
530537
self,
531538
state: SnapState,
532539
classic: Optional[bool] = False,
540+
devmode: bool = False,
533541
channel: Optional[str] = "",
534542
cohort: Optional[str] = "",
535543
revision: Optional[str] = None,
@@ -539,6 +547,7 @@ def ensure(
539547
Args:
540548
state: a `SnapState` to reconcile to.
541549
classic: an (Optional) boolean indicating whether classic confinement should be used
550+
devmode: an (Optional) boolean indicating whether devmode confinement should be used
542551
channel: the channel to install from
543552
cohort: optional. Specify the key of a snap cohort.
544553
revision: optional. the revision of the snap to install/refresh
@@ -549,7 +558,15 @@ def ensure(
549558
Raises:
550559
SnapError if an error is encountered
551560
"""
552-
self._confinement = "classic" if classic or self._confinement == "classic" else ""
561+
if classic and devmode:
562+
raise ValueError("Cannot set both classic and devmode confinement")
563+
564+
if classic or self._confinement == "classic":
565+
self._confinement = "classic"
566+
elif devmode or self._confinement == "devmode":
567+
self._confinement = "devmode"
568+
else:
569+
self._confinement = ""
553570

554571
if state not in (SnapState.Present, SnapState.Latest):
555572
# We are attempting to remove this snap.
@@ -566,7 +583,7 @@ def ensure(
566583
self._install(channel, cohort, revision)
567584
else:
568585
# The snap is installed, but we are changing it (e.g., switching channels).
569-
self._refresh(channel, cohort, revision)
586+
self._refresh(channel=channel, cohort=cohort, revision=revision, devmode=devmode)
570587

571588
self._update_snap_apps()
572589
self._state = state
@@ -892,6 +909,7 @@ def add(
892909
state: Union[str, SnapState] = SnapState.Latest,
893910
channel: Optional[str] = "",
894911
classic: Optional[bool] = False,
912+
devmode: bool = False,
895913
cohort: Optional[str] = "",
896914
revision: Optional[str] = None,
897915
) -> Union[Snap, List[Snap]]:
@@ -904,6 +922,8 @@ def add(
904922
channel: an (Optional) channel as a string. Defaults to 'latest'
905923
classic: an (Optional) boolean specifying whether it should be added with classic
906924
confinement. Default `False`
925+
devmode: an (Optional) boolean specifying whether it should be added with devmode
926+
confinement. Default `False`
907927
cohort: an (Optional) string specifying the snap cohort to use
908928
revision: an (Optional) string specifying the snap revision to use
909929
@@ -920,7 +940,7 @@ def add(
920940
if isinstance(state, str):
921941
state = SnapState(state)
922942

923-
return _wrap_snap_operations(snap_names, state, channel, classic, cohort, revision)
943+
return _wrap_snap_operations(snap_names, state, channel, classic, devmode, cohort, revision)
924944

925945

926946
@_cache_init
@@ -936,8 +956,13 @@ def remove(snap_names: Union[str, List[str]]) -> Union[Snap, List[Snap]]:
936956
snap_names = [snap_names] if isinstance(snap_names, str) else snap_names
937957
if not snap_names:
938958
raise TypeError("Expected at least one snap to add, received zero!")
939-
940-
return _wrap_snap_operations(snap_names, SnapState.Absent, "", False)
959+
return _wrap_snap_operations(
960+
snap_names=snap_names,
961+
state=SnapState.Absent,
962+
channel="",
963+
classic=False,
964+
devmode=False,
965+
)
941966

942967

943968
@_cache_init
@@ -946,6 +971,7 @@ def ensure(
946971
state: str,
947972
channel: Optional[str] = "",
948973
classic: Optional[bool] = False,
974+
devmode: bool = False,
949975
cohort: Optional[str] = "",
950976
revision: Optional[int] = None,
951977
) -> Union[Snap, List[Snap]]:
@@ -957,6 +983,8 @@ def ensure(
957983
channel: an (Optional) channel as a string. Defaults to 'latest'
958984
classic: an (Optional) boolean specifying whether it should be added with classic
959985
confinement. Default `False`
986+
devmode: an (Optional) boolean specifying whether it should be added with devmode
987+
confinement. Default `False`
960988
cohort: an (Optional) string specifying the snap cohort to use
961989
revision: an (Optional) integer specifying the snap revision to use
962990
@@ -970,7 +998,15 @@ def ensure(
970998
channel = "latest"
971999

9721000
if state in ("present", "latest") or revision:
973-
return add(snap_names, SnapState(state), channel, classic, cohort, revision)
1001+
return add(
1002+
snap_names=snap_names,
1003+
state=SnapState(state),
1004+
channel=channel,
1005+
classic=classic,
1006+
devmode=devmode,
1007+
cohort=cohort,
1008+
revision=revision,
1009+
)
9741010
else:
9751011
return remove(snap_names)
9761012

@@ -980,6 +1016,7 @@ def _wrap_snap_operations(
9801016
state: SnapState,
9811017
channel: str,
9821018
classic: bool,
1019+
devmode: bool,
9831020
cohort: Optional[str] = "",
9841021
revision: Optional[str] = None,
9851022
) -> Union[Snap, List[Snap]]:
@@ -995,7 +1032,12 @@ def _wrap_snap_operations(
9951032
snap.ensure(state=SnapState.Absent)
9961033
else:
9971034
snap.ensure(
998-
state=state, classic=classic, channel=channel, cohort=cohort, revision=revision
1035+
state=state,
1036+
classic=classic,
1037+
devmode=devmode,
1038+
channel=channel,
1039+
cohort=cohort,
1040+
revision=revision,
9991041
)
10001042
snaps["success"].append(snap)
10011043
except SnapError as e:
@@ -1014,13 +1056,17 @@ def _wrap_snap_operations(
10141056

10151057

10161058
def install_local(
1017-
filename: str, classic: Optional[bool] = False, dangerous: Optional[bool] = False
1059+
filename: str,
1060+
classic: Optional[bool] = False,
1061+
devmode: Optional[bool] = False,
1062+
dangerous: Optional[bool] = False,
10181063
) -> Snap:
10191064
"""Perform a snap operation.
10201065
10211066
Args:
10221067
filename: the path to a local .snap file to install
10231068
classic: whether to use classic confinement
1069+
devmode: whether to use devmode confinement
10241070
dangerous: whether --dangerous should be passed to install snaps without a signature
10251071
10261072
Raises:
@@ -1033,6 +1079,8 @@ def install_local(
10331079
]
10341080
if classic:
10351081
args.append("--classic")
1082+
if devmode:
1083+
args.append("--devmode")
10361084
if dangerous:
10371085
args.append("--dangerous")
10381086
try:

lib/charms/tls_certificates_interface/v2/tls_certificates.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def _on_all_certificates_invalidated(self, event: AllCertificatesInvalidatedEven
307307

308308
# Increment this PATCH version before using `charmcraft publish-lib` or reset
309309
# to 0 if you are raising the major API version
310-
LIBPATCH = 24
310+
LIBPATCH = 26
311311

312312
PYDEPS = ["cryptography", "jsonschema"]
313313

@@ -667,7 +667,7 @@ def generate_ca(
667667
668668
Args:
669669
private_key (bytes): Private key
670-
subject (str): Certificate subject
670+
subject (str): Common Name that can be an IP or a Full Qualified Domain Name (FQDN).
671671
private_key_password (bytes): Private key password
672672
validity (int): Certificate validity time (in days)
673673
country (str): Certificate Issuing country
@@ -678,7 +678,7 @@ def generate_ca(
678678
private_key_object = serialization.load_pem_private_key(
679679
private_key, password=private_key_password
680680
)
681-
subject = issuer = x509.Name(
681+
subject_name = x509.Name(
682682
[
683683
x509.NameAttribute(x509.NameOID.COUNTRY_NAME, country),
684684
x509.NameAttribute(x509.NameOID.COMMON_NAME, subject),
@@ -701,8 +701,8 @@ def generate_ca(
701701
)
702702
cert = (
703703
x509.CertificateBuilder()
704-
.subject_name(subject)
705-
.issuer_name(issuer)
704+
.subject_name(subject_name)
705+
.issuer_name(subject_name)
706706
.public_key(private_key_object.public_key()) # type: ignore[arg-type]
707707
.serial_number(x509.random_serial_number())
708708
.not_valid_before(datetime.utcnow())
@@ -965,7 +965,7 @@ def generate_csr(
965965
966966
Args:
967967
private_key (bytes): Private key
968-
subject (str): CSR Subject.
968+
subject (str): CSR Common Name that can be an IP or a Full Qualified Domain Name (FQDN).
969969
add_unique_id_to_subject_name (bool): Whether a unique ID must be added to the CSR's
970970
subject name. Always leave to "True" when the CSR is used to request certificates
971971
using the tls-certificates relation.

poetry.lock

Lines changed: 23 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)