Skip to content

Commit

Permalink
bump libs so they are published (#515)
Browse files Browse the repository at this point in the history
## Issue
the latest changes to the libs do not bump the libpatch

## Solution
bump them so they are published
  • Loading branch information
MiaAltieri authored Nov 12, 2024
1 parent be7e778 commit 6c91b8b
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 32 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
# Workaround for https://github.com/canonical/charmcraft/issues/1389#issuecomment-1880921728
touch requirements.txt
- name: Check libs
uses: canonical/charming-actions/check-libraries@2.4.0
uses: canonical/charming-actions/check-libraries@2.6.3
with:
credentials: ${{ secrets.CHARMHUB_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -113,7 +113,7 @@ jobs:
- build
uses: canonical/data-platform-workflows/.github/workflows/[email protected]
with:
artifact-prefix: packed-charm-cache-false # TODO revert to "packed-charm-cache-true" when cache re-enabled
artifact-prefix: packed-charm-cache-false # TODO revert to "packed-charm-cache-true" when cache re-enabled
cloud: lxd
juju-agent-version: ${{ matrix.juju.agent }}
juju-snap-channel: ${{ matrix.juju.snap_channel }}
Expand Down
22 changes: 14 additions & 8 deletions lib/charms/grafana_agent/v0/cos_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
Using the `COSAgentProvider` object only requires instantiating it,
typically in the `__init__` method of your charm (the one which sends telemetry).
The constructor of `COSAgentProvider` has only one required and nine optional parameters:
The constructor of `COSAgentProvider` has only one required and ten optional parameters:
```python
def __init__(
Expand All @@ -36,6 +36,7 @@ def __init__(
log_slots: Optional[List[str]] = None,
dashboard_dirs: Optional[List[str]] = None,
refresh_events: Optional[List] = None,
tracing_protocols: Optional[List[str]] = None,
scrape_configs: Optional[Union[List[Dict], Callable]] = None,
):
```
Expand Down Expand Up @@ -65,6 +66,8 @@ def __init__(
- `refresh_events`: List of events on which to refresh relation data.
- `tracing_protocols`: List of requested tracing protocols that the charm requires to send traces.
- `scrape_configs`: List of standard scrape_configs dicts or a callable that returns the list in
case the configs need to be generated dynamically. The contents of this list will be merged
with the configs from `metrics_endpoints`.
Expand Down Expand Up @@ -108,6 +111,7 @@ def __init__(self, *args):
log_slots=["my-app:slot"],
dashboard_dirs=["./src/dashboards_1", "./src/dashboards_2"],
refresh_events=["update-status", "upgrade-charm"],
tracing_protocols=["otlp_http", "otlp_grpc"],
scrape_configs=[
{
"job_name": "custom_job",
Expand Down Expand Up @@ -231,10 +235,10 @@ def __init__(self, *args):
import pydantic
from cosl import GrafanaDashboard, JujuTopology
from cosl.rules import AlertRules
from ops import CharmBase
from ops.charm import RelationChangedEvent
from ops.framework import EventBase, EventSource, Object, ObjectEvents
from ops.model import ModelError, Relation
from ops.testing import CharmType

if TYPE_CHECKING:
try:
Expand All @@ -249,7 +253,7 @@ class _MetricsEndpointDict(TypedDict):

LIBID = "dc15fa84cef84ce58155fb84f6c6213a"
LIBAPI = 0
LIBPATCH = 10
LIBPATCH = 11

PYDEPS = ["cosl", "pydantic"]

Expand Down Expand Up @@ -464,7 +468,7 @@ def dump(self, databag: Optional[MutableMapping] = None, clear: bool = True):
return databag


class CosAgentProviderUnitData(DatabagModel):
class CosAgentProviderUnitData(DatabagModel): # pyright: ignore [reportGeneralTypeIssues]
"""Unit databag model for `cos-agent` relation."""

# The following entries are the same for all units of the same principal.
Expand All @@ -491,7 +495,7 @@ class CosAgentProviderUnitData(DatabagModel):
KEY: ClassVar[str] = "config"


class CosAgentPeersUnitData(DatabagModel):
class CosAgentPeersUnitData(DatabagModel): # pyright: ignore [reportGeneralTypeIssues]
"""Unit databag model for `peers` cos-agent machine charm peer relation."""

# We need the principal unit name and relation metadata to be able to render identifiers
Expand Down Expand Up @@ -590,7 +594,9 @@ class Receiver(pydantic.BaseModel):
)


class CosAgentRequirerUnitData(DatabagModel): # noqa: D101
class CosAgentRequirerUnitData(
DatabagModel
): # pyright: ignore [reportGeneralTypeIssues] # noqa: D101
"""Application databag model for the COS-agent requirer."""

receivers: List[Receiver] = pydantic.Field(
Expand All @@ -604,7 +610,7 @@ class COSAgentProvider(Object):

def __init__(
self,
charm: CharmType,
charm: CharmBase,
relation_name: str = DEFAULT_RELATION_NAME,
metrics_endpoints: Optional[List["_MetricsEndpointDict"]] = None,
metrics_rules_dir: str = "./src/prometheus_alert_rules",
Expand Down Expand Up @@ -873,7 +879,7 @@ class COSAgentRequirer(Object):

def __init__(
self,
charm: CharmType,
charm: CharmBase,
*,
relation_name: str = DEFAULT_RELATION_NAME,
peer_relation_name: str = DEFAULT_PEER_RELATION_NAME,
Expand Down
2 changes: 1 addition & 1 deletion lib/charms/mongodb/v0/config_server_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

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


class ClusterProvider(Object):
Expand Down
2 changes: 1 addition & 1 deletion lib/charms/mongodb/v1/mongodb_backups.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

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

logger = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion lib/charms/mongodb/v1/mongodb_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

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

logger = logging.getLogger(__name__)
REL_NAME = "database"
Expand Down
89 changes: 70 additions & 19 deletions lib/charms/tls_certificates_interface/v3/tls_certificates.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ def _on_all_certificates_invalidated(self, event: AllCertificatesInvalidatedEven
ModelError,
Relation,
RelationDataContent,
Secret,
SecretNotFoundError,
Unit,
)
Expand All @@ -317,7 +318,7 @@ def _on_all_certificates_invalidated(self, event: AllCertificatesInvalidatedEven

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

PYDEPS = ["cryptography", "jsonschema"]

Expand Down Expand Up @@ -735,16 +736,16 @@ def calculate_expiry_notification_time(
"""
if provider_recommended_notification_time is not None:
provider_recommended_notification_time = abs(provider_recommended_notification_time)
provider_recommendation_time_delta = (
expiry_time - timedelta(hours=provider_recommended_notification_time)
provider_recommendation_time_delta = expiry_time - timedelta(
hours=provider_recommended_notification_time
)
if validity_start_time < provider_recommendation_time_delta:
return provider_recommendation_time_delta

if requirer_recommended_notification_time is not None:
requirer_recommended_notification_time = abs(requirer_recommended_notification_time)
requirer_recommendation_time_delta = (
expiry_time - timedelta(hours=requirer_recommended_notification_time)
requirer_recommendation_time_delta = expiry_time - timedelta(
hours=requirer_recommended_notification_time
)
if validity_start_time < requirer_recommendation_time_delta:
return requirer_recommendation_time_delta
Expand Down Expand Up @@ -1448,18 +1449,31 @@ def _revoke_certificates_for_which_no_csr_exists(self, relation_id: int) -> None
Returns:
None
"""
provider_certificates = self.get_provider_certificates(relation_id)
requirer_csrs = self.get_requirer_csrs(relation_id)
provider_certificates = self.get_unsolicited_certificates(relation_id=relation_id)
for provider_certificate in provider_certificates:
self.on.certificate_revocation_request.emit(
certificate=provider_certificate.certificate,
certificate_signing_request=provider_certificate.csr,
ca=provider_certificate.ca,
chain=provider_certificate.chain,
)
self.remove_certificate(certificate=provider_certificate.certificate)

def get_unsolicited_certificates(
self, relation_id: Optional[int] = None
) -> List[ProviderCertificate]:
"""Return provider certificates for which no certificate requests exists.
Those certificates should be revoked.
"""
unsolicited_certificates: List[ProviderCertificate] = []
provider_certificates = self.get_provider_certificates(relation_id=relation_id)
requirer_csrs = self.get_requirer_csrs(relation_id=relation_id)
list_of_csrs = [csr.csr for csr in requirer_csrs]
for certificate in provider_certificates:
if certificate.csr not in list_of_csrs:
self.on.certificate_revocation_request.emit(
certificate=certificate.certificate,
certificate_signing_request=certificate.csr,
ca=certificate.ca,
chain=certificate.chain,
)
self.remove_certificate(certificate=certificate.certificate)
unsolicited_certificates.append(certificate)
return unsolicited_certificates

def get_outstanding_certificate_requests(
self, relation_id: Optional[int] = None
Expand Down Expand Up @@ -1877,8 +1891,7 @@ def _on_relation_changed(self, event: RelationChangedEvent) -> None:
"Removing secret with label %s",
f"{LIBID}-{csr_in_sha256_hex}",
)
secret = self.model.get_secret(
label=f"{LIBID}-{csr_in_sha256_hex}")
secret = self.model.get_secret(label=f"{LIBID}-{csr_in_sha256_hex}")
secret.remove_all_revisions()
self.on.certificate_invalidated.emit(
reason="revoked",
Expand All @@ -1889,10 +1902,20 @@ def _on_relation_changed(self, event: RelationChangedEvent) -> None:
)
else:
try:
secret = self.model.get_secret(label=f"{LIBID}-{csr_in_sha256_hex}")
logger.debug(
"Setting secret with label %s", f"{LIBID}-{csr_in_sha256_hex}"
)
secret = self.model.get_secret(label=f"{LIBID}-{csr_in_sha256_hex}")
# Juju < 3.6 will create a new revision even if the content is the same
if (
secret.get_content(refresh=True).get("certificate", "")
== certificate.certificate
):
logger.debug(
"Secret %s with correct certificate already exists",
f"{LIBID}-{csr_in_sha256_hex}",
)
continue
secret.set_content(
{"certificate": certificate.certificate, "csr": certificate.csr}
)
Expand Down Expand Up @@ -1966,17 +1989,26 @@ def _on_secret_expired(self, event: SecretExpiredEvent) -> None:
Args:
event (SecretExpiredEvent): Juju event
"""
if not event.secret.label or not event.secret.label.startswith(f"{LIBID}-"):
csr = self._get_csr_from_secret(event.secret)
if not csr:
logger.error("Failed to get CSR from secret %s", event.secret.label)
return
csr = event.secret.get_content()["csr"]
provider_certificate = self._find_certificate_in_relation_data(csr)
if not provider_certificate:
# A secret expired but we did not find matching certificate. Cleaning up
logger.warning(
"Failed to find matching certificate for csr, cleaning up secret %s",
event.secret.label,
)
event.secret.remove_all_revisions()
return

if not provider_certificate.expiry_time:
# A secret expired but matching certificate is invalid. Cleaning up
logger.warning(
"Certificate matching csr is invalid, cleaning up secret %s",
event.secret.label,
)
event.secret.remove_all_revisions()
return

Expand Down Expand Up @@ -2008,3 +2040,22 @@ def _find_certificate_in_relation_data(self, csr: str) -> Optional[ProviderCerti
continue
return provider_certificate
return None

def _get_csr_from_secret(self, secret: Secret) -> Union[str, None]:
"""Extract the CSR from the secret label or content.
This function is a workaround to maintain backwards compatibility
and fix the issue reported in
https://github.com/canonical/tls-certificates-interface/issues/228
"""
try:
content = secret.get_content(refresh=True)
except SecretNotFoundError:
return None
if not (csr := content.get("csr", None)):
# In versions <14 of the Lib we were storing the CSR in the label of the secret
# The CSR now is stored int the content of the secret, which was a breaking change
# Here we get the CSR if the secret was created by an app using libpatch 14 or lower
if secret.label and secret.label.startswith(f"{LIBID}-"):
csr = secret.label[len(f"{LIBID}-") :]
return csr

0 comments on commit 6c91b8b

Please sign in to comment.