Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Juju secret expiry is null #1316

Closed
gruyaume opened this issue Aug 15, 2024 · 1 comment · Fixed by #1317
Closed

Juju secret expiry is null #1316

gruyaume opened this issue Aug 15, 2024 · 1 comment · Fixed by #1317
Assignees
Labels
bug Something isn't working ops-next To be done before shipping the next version of ops small item

Comments

@gruyaume
Copy link

gruyaume commented Aug 15, 2024

Description

We have a charm that creates a secret with an expiry date on a given event and reads that secret on another event. During that second event, the expiry shows up as None when we would have expected it to be the value we initially set it to.

Example charm

In this example charm we would expect the charm status to be Secret expires on: .... Instead we see that the expiry date is not set. The content is set correctly however.

#!/usr/bin/env python3
# Copyright 2024 Canonical Ltd.
# See LICENSE file for licensing details.

"""My charm."""

import datetime
import logging
from typing import Optional

from ops.charm import CharmBase, CollectStatusEvent
from ops.framework import EventBase
from ops.main import main
from ops.model import ActiveStatus, BlockedStatus, SecretNotFoundError, WaitingStatus

logger = logging.getLogger(__name__)

SECRET_LABEL = "food"


class MyCharm(CharmBase):
    """Main class to handle Juju events."""

    def __init__(self, *args):
        super().__init__(*args)
        self.framework.observe(self.on.collect_unit_status, self._on_collect_unit_status)
        self.framework.observe(self.on.update_status, self._configure)
        self.framework.observe(self.on.config_changed, self._configure)

    def _on_collect_unit_status(self, event: CollectStatusEvent):
        """Centralized status management for the charm."""
        if not self.unit.is_leader():
            event.add_status(BlockedStatus("Scaling is not implemented for this charm"))
            return
        if not self._secret_is_created():
            event.add_status(WaitingStatus("Waiting for the secret to be created"))
            return
        secret_expiry = self._get_secret_expiry()
        if not secret_expiry:
            event.add_status(ActiveStatus("Error: Secret expiry not found"))
            return
        event.add_status(ActiveStatus("Secret expires on: {}".format(secret_expiry)))

    def _configure(self, event: EventBase) -> None:
        if not self._secret_is_created():
            self._create_secret()

    def _create_secret(self):
        """Create a secret."""
        secret_content = {
            "food": "apple",
        }
        self.app.add_secret(
            content=secret_content,
            label=SECRET_LABEL,
            expire=datetime.timedelta(days=20),
        )

    def _secret_is_created(self) -> bool:
        """Check if the secret is created."""
        try:
            self.model.get_secret(label=SECRET_LABEL)
            return True
        except SecretNotFoundError:
            return False

    def _get_secret_expiry(self) -> Optional[datetime.datetime]:
        """Get the expiry date of the secret."""
        secret = self.model.get_secret(label=SECRET_LABEL)
        secret_info = secret.get_info()
        secret_content = secret.get_content()
        logger.info("Secret info: %s", secret_info)
        logger.info("Secret content: %s", secret_content)
        return secret_info.expires


if __name__ == "__main__":
    main(MyCharm)

Logs

unit-self-signed-certificates-0: 16:42:26 INFO unit.self-signed-certificates/0.juju-log Secret info: SecretInfo(id='secret:cqv6gcfmp25c77ug4n5g', label='food', revision=1, expires=None, rotation=SecretRotate.NEVER, rotates=None)
unit-self-signed-certificates-0: 16:42:26 INFO unit.self-signed-certificates/0.juju-log Secret content: {'food': 'apple'}
guillaume@thinkpad:~/code/self-signed-certificates-operator$ juju status
Model  Controller          Cloud/Region        Version  SLA          Timestamp
ddd    microk8s-localhost  microk8s/localhost  3.5.1    unsupported  16:36:48-04:00

App                       Version  Status  Scale  Charm                     Channel  Rev  Address         Exposed  Message
self-signed-certificates           active      1  self-signed-certificates             0  10.152.183.137  no       Error: Secret expiry not found

Unit                         Workload  Agent  Address      Ports  Message
self-signed-certificates/0*  active    idle   10.1.19.182         Error: Secret expiry not found

Is the issue in Juju?

At this point I don't know whether the issue is with ops, with Juju, or with me.

Environment

  • Juju: 3.5.1
  • Ops: 2.15.0
  • MicroK8s: 1.29-strict/stable
@tonyandrewmeyer
Copy link
Contributor

Thanks for the excellent report - it really speeds things up so much to have that level of detail.

This is an ops bug - we're looking for a field expires in the secret-info-get response but Juju gives it in a field expiry.

@tonyandrewmeyer tonyandrewmeyer added bug Something isn't working small item ops-next To be done before shipping the next version of ops labels Aug 15, 2024
@tonyandrewmeyer tonyandrewmeyer self-assigned this Aug 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working ops-next To be done before shipping the next version of ops small item
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants