From cbd313d56d5d7bc74dd1aa6af7030b135cc53170 Mon Sep 17 00:00:00 2001 From: Guillaume Boutry Date: Tue, 3 Oct 2023 11:01:59 +0200 Subject: [PATCH] Rename to designate-bind-k8s Moved nonce from stored state to secret --- charms/designate-bind-k8s/CONTRIBUTING.md | 10 +- charms/designate-bind-k8s/README.md | 4 +- .../v0/bind_rndc.py | 92 +++++++++++-------- charms/designate-bind-k8s/metadata.yaml | 14 +-- charms/designate-bind-k8s/src/charm.py | 18 ++-- .../tests/bundles/smoke.yaml | 6 +- charms/designate-bind-k8s/tests/tests.yaml | 2 +- charms/designate-bind-k8s/tox.ini | 2 +- 8 files changed, 80 insertions(+), 68 deletions(-) rename charms/designate-bind-k8s/lib/charms/{bind9_k8s => designate_bind_k8s}/v0/bind_rndc.py (83%) diff --git a/charms/designate-bind-k8s/CONTRIBUTING.md b/charms/designate-bind-k8s/CONTRIBUTING.md index f0f4d65a..9faeb659 100644 --- a/charms/designate-bind-k8s/CONTRIBUTING.md +++ b/charms/designate-bind-k8s/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# bind9-k8s +# designate-bind-k8s ## Developing @@ -13,12 +13,12 @@ Create and activate a virtualenv with the development requirements: Get familiarise with [Charmed Operator Framework](https://juju.is/docs/sdk) and [Sunbeam documentation](sunbeam-docs). -bind9-k8s charm uses the ops\_sunbeam library and extends +designate-bind-k8s charm uses the ops\_sunbeam library and extends OSBaseOperatorAPICharm from the library. ## Intended use case -bind9-k8s charm deploys and configures OpenStack Identity service +designate-bind-k8s charm deploys and configures OpenStack Identity service on a kubernetes based environment. ## Roadmap @@ -41,11 +41,11 @@ run: To deploy the local test instance: - juju deploy ./bind9-k8s_ubuntu-20.04-amd64.charm --trust --resource bind9-image=ghcr.io/openstack-snaps/bind9:2023.1 + juju deploy ./designate-bind-k8s_ubuntu-20.04-amd64.charm --trust --resource designate-bind-image=ghcr.io/openstack-snaps/designate-bind:2023.1 -[bind9-k8s-libs-docs]: https://charmhub.io/sunbeam-bind9-operator/libraries/identity_service +[designate-bind-k8s-libs-docs]: https://charmhub.io/sunbeam-designate-bind-operator/libraries/identity_service [sunbeam-docs]: https://opendev.org/openstack/charm-ops-sunbeam/src/branch/main/README.rst diff --git a/charms/designate-bind-k8s/README.md b/charms/designate-bind-k8s/README.md index aedc5636..3fc97f72 100644 --- a/charms/designate-bind-k8s/README.md +++ b/charms/designate-bind-k8s/README.md @@ -8,10 +8,10 @@ Avoid using this README file for information that is maintained or published els Use links instead. --> -# charm-bind9 +# designate-bind-k8s Charmhub package name: operator-template -More information: https://charmhub.io/charm-bind9 +More information: https://charmhub.io/designate-bind-k8s Describe your charm in one or two sentences. diff --git a/charms/designate-bind-k8s/lib/charms/bind9_k8s/v0/bind_rndc.py b/charms/designate-bind-k8s/lib/charms/designate_bind_k8s/v0/bind_rndc.py similarity index 83% rename from charms/designate-bind-k8s/lib/charms/bind9_k8s/v0/bind_rndc.py rename to charms/designate-bind-k8s/lib/charms/designate_bind_k8s/v0/bind_rndc.py index f0fa68db..2bb2f93e 100644 --- a/charms/designate-bind-k8s/lib/charms/bind9_k8s/v0/bind_rndc.py +++ b/charms/designate-bind-k8s/lib/charms/designate_bind_k8s/v0/bind_rndc.py @@ -13,7 +13,7 @@ Two events are also available to respond to: - goneaway A basic example showing the usage of this relation follows: ``` -from charms.bind9_k8s.v0.bind_rndc import ( +from charms.designate_bind_k8s.v0.bind_rndc import ( BindRndcRequires ) class BindRndcClientCharm(CharmBase): @@ -31,6 +31,13 @@ class BindRndcClientCharm(CharmBase): self.bind_rndc.on.goneaway, self._on_bind_rndc_goneaway ) + def _on_bind_rndc_connected(self, event): + '''React to the Bind Rndc Connected event. + This event happens when BindRndc relation is added to the + model. + ''' + # Request the rndc key from the Bind Rndc relation. + self.bind_rndc.request_rndc_key("generated nonce") def _on_bind_rndc_ready(self, event): '''React to the Bind Rndc Ready event. This event happens when BindRndc relation is added to the @@ -49,7 +56,6 @@ class BindRndcClientCharm(CharmBase): import json import logging -import secrets from typing import ( Any, Dict, @@ -63,14 +69,41 @@ import ops logger = logging.getLogger(__name__) # The unique Charmhub library identifier, never change it -LIBID = "0fb2f64f2a1344feb80044cee22ef3a8" +LIBID = "1cb766c981874e7383d17cf54148b3d4" # Increment this major API version when introducing breaking changes LIBAPI = 0 # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 3 +LIBPATCH = 1 + + +class BindRndcConnectedEvent(ops.EventBase): + """Bind rndc connected event.""" + + def __init__( + self, + handle: ops.Handle, + relation_id: int, + relation_name: str, + ): + super().__init__(handle) + self.relation_id = relation_id + self.relation_name = relation_name + + def snapshot(self) -> dict: + """Return snapshot data that should be persisted.""" + return { + "relation_id": self.relation_id, + "relation_name": self.relation_name, + } + + def restore(self, snapshot: Dict[str, Any]): + """Restore the value state from a given snapshot.""" + super().restore(snapshot) + self.relation_id = snapshot["relation_id"] + self.relation_name = snapshot["relation_name"] class BindRndcReadyEvent(ops.EventBase): @@ -81,22 +114,16 @@ class BindRndcReadyEvent(ops.EventBase): handle: ops.Handle, relation_id: int, relation_name: str, - algorithm: str, - secret: str, ): super().__init__(handle) self.relation_id = relation_id self.relation_name = relation_name - self.algorithm = algorithm - self.secret = secret def snapshot(self) -> dict: """Return snapshot data that should be persisted.""" return { "relation_id": self.relation_id, "relation_name": self.relation_name, - "algorithm": self.algorithm, - "secret": self.secret, } def restore(self, snapshot: Dict[str, Any]): @@ -104,8 +131,6 @@ class BindRndcReadyEvent(ops.EventBase): super().restore(snapshot) self.relation_id = snapshot["relation_id"] self.relation_name = snapshot["relation_name"] - self.algorithm = snapshot["algorithm"] - self.secret = snapshot["secret"] class BindRndcGoneAwayEvent(ops.EventBase): @@ -117,7 +142,8 @@ class BindRndcGoneAwayEvent(ops.EventBase): class BindRndcRequirerEvents(ops.ObjectEvents): """List of events that the BindRndc requires charm can leverage.""" - bind_rndc_ready = ops.EventSource(BindRndcReadyEvent) + connected = ops.EventSource(BindRndcConnectedEvent) + ready = ops.EventSource(BindRndcReadyEvent) goneaway = ops.EventSource(BindRndcGoneAwayEvent) @@ -125,13 +151,11 @@ class BindRndcRequires(ops.Object): """Class to be instantiated by the requiring side of the relation.""" on = BindRndcRequirerEvents() - _stored = ops.StoredState() def __init__(self, charm: ops.CharmBase, relation_name: str): super().__init__(charm, relation_name) self.charm = charm self.relation_name = relation_name - self._stored.set_default(nonce="") self.framework.observe( self.charm.on[relation_name].relation_joined, self._on_relation_joined, @@ -147,24 +171,20 @@ class BindRndcRequires(ops.Object): def _on_relation_joined(self, event: ops.RelationJoinedEvent): """Handle relation joined event.""" - self._request_rndc_key(event.relation) + self.on.connected.emit( + event.relation.id, + event.relation.name, + ) def _on_relation_changed(self, event: ops.RelationJoinedEvent): """Handle relation changed event.""" host = self.host(event.relation) rndc_key = self.get_rndc_key(event.relation) - if rndc_key is None: - self._request_rndc_key(event.relation) - return - if host is not None: - algorithm = rndc_key["algorithm"] - secret = rndc_key["secret"] - self.on.bind_rndc_ready.emit( + if all((host, rndc_key)): + self.on.ready.emit( event.relation.id, event.relation.name, - algorithm, - secret, ) def _on_relation_broken(self, event: ops.RelationBrokenEvent): @@ -177,33 +197,25 @@ class BindRndcRequires(ops.Object): return None return relation.data[relation.app].get("host") - def nonce(self) -> str: - """Return nonce from stored state.""" - return self._stored.nonce + def nonce(self, relation: ops.Relation) -> Optional[str]: + """Return nonce from relation.""" + return relation.data[self.charm.unit].get("nonce") def get_rndc_key(self, relation: ops.Relation) -> Optional[dict]: """Get rndc keys.""" if relation.app is None: return None - if self._stored.nonce == "": + if self.nonce(relation) is None: logger.debug("No nonce set for unit yet") return None return json.loads( relation.data[relation.app].get("rndc_keys", "{}") - ).get(self._stored.nonce) + ).get(self.nonce(relation)) - def _request_rndc_key(self, relation: ops.Relation): + def request_rndc_key(self, relation: ops.Relation, nonce: str): """Request rndc key over the relation.""" - if self._stored.nonce == "": - self._stored.nonce = secrets.token_hex(16) - relation.data[self.charm.unit]["nonce"] = self._stored.nonce - - def reconcile_rndc_key(self, relation: ops.Relation): - """Reconcile rndc key over the relation.""" - if self._stored.nonce != relation.data[self.charm.unit].get("nonce"): - self._stored.nonce = secrets.token_hex(16) - relation.data[self.charm.unit]["nonce"] = self._stored.nonce + relation.data[self.charm.unit]["nonce"] = nonce class NewBindClientAttachedEvent(ops.EventBase): diff --git a/charms/designate-bind-k8s/metadata.yaml b/charms/designate-bind-k8s/metadata.yaml index 3b53e786..f8615165 100644 --- a/charms/designate-bind-k8s/metadata.yaml +++ b/charms/designate-bind-k8s/metadata.yaml @@ -1,5 +1,5 @@ -name: bind9-k8s -summary: OpenStack bind9 service +name: designate-bind-k8s +summary: OpenStack designate-bind service maintainer: OpenStack Charmers description: | Domain Name Service (DNS) is an Internet service that maps IP addresses and fully qualified domain names (FQDN) to one another. @@ -14,15 +14,15 @@ assumes: - juju >= 3.1 tags: - openstack -source: https://opendev.org/openstack/charm-bind9-k8s -issues: https://bugs.launchpad.net/charm-bind9-k8s +source: https://opendev.org/openstack/charm-designate-bind-k8s +issues: https://bugs.launchpad.net/charm-designate-bind-k8s containers: - bind9: - resource: bind9-image + designate-bind: + resource: designate-bind-image resources: - bind9-image: + designate-bind-image: type: oci-image description: OCI image for bind9 upstream-source: ubuntu/bind9:9.18-22.04_beta diff --git a/charms/designate-bind-k8s/src/charm.py b/charms/designate-bind-k8s/src/charm.py index fb7cd084..355f6772 100755 --- a/charms/designate-bind-k8s/src/charm.py +++ b/charms/designate-bind-k8s/src/charm.py @@ -12,9 +12,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""Bind9 Operator Charm. +"""designate-bind Operator Charm. -This charm provide Bind9 services +This charm provide designate-bind services """ import base64 @@ -27,7 +27,7 @@ from typing import ( List, ) -import charms.bind9_k8s.v0.bind_rndc as bind_rndc +import charms.designate_bind_k8s.v0.bind_rndc as bind_rndc import charms.observability_libs.v1.kubernetes_service_patch as kubernetes_service_patch import lightkube.models.core_v1 as core_v1 import ops.charm @@ -50,17 +50,17 @@ RNDC_REVISION_KEY = "rndc_revision" class BindPebbleHandler(sunbeam_chandlers.ServicePebbleHandler): - """Pebble handler for bind9 service.""" + """Pebble handler for designate-bind service.""" def get_layer(self) -> dict: """Pebble layer for bind 9 service.""" return { - "summary": "bind9 layer", - "description": "pebble config layer for bind9", + "summary": "designate-bind layer", + "description": "pebble config layer for designate-bind", "services": { - "bind9": { + "designate-bind": { "override": "replace", - "summary": "bind9", + "summary": "designate-bind", "command": "/usr/sbin/named -g -u bind", "startup": "enabled", } @@ -181,7 +181,7 @@ class BindOperatorCharm(sunbeam_charm.OSBaseOperatorCharmK8S): """Charm the service.""" _state = StoredState() - service_name = "bind9" + service_name = "designate-bind" # mandatory_relations = {} diff --git a/charms/designate-bind-k8s/tests/bundles/smoke.yaml b/charms/designate-bind-k8s/tests/bundles/smoke.yaml index 1e4c66cb..efa850f6 100644 --- a/charms/designate-bind-k8s/tests/bundles/smoke.yaml +++ b/charms/designate-bind-k8s/tests/bundles/smoke.yaml @@ -1,8 +1,8 @@ bundle: kubernetes applications: - bind9: - charm: ../../bind9-k8s.charm + designate-bind: + charm: ../../designate-bind-k8s.charm scale: 1 trust: false resources: - bind9-image: ubuntu/bind9:9.18-22.04_beta + designate-bind-image: ubuntu/designate-bind:9.18-22.04_beta diff --git a/charms/designate-bind-k8s/tests/tests.yaml b/charms/designate-bind-k8s/tests/tests.yaml index 9eb05a1b..fcc3cb55 100644 --- a/charms/designate-bind-k8s/tests/tests.yaml +++ b/charms/designate-bind-k8s/tests/tests.yaml @@ -17,6 +17,6 @@ tests_options: smoke: True target_deploy_status: - bind9: + designate-bind: workload-status: active workload-status-message-regex: '^$' diff --git a/charms/designate-bind-k8s/tox.ini b/charms/designate-bind-k8s/tox.ini index f8e4765b..a6803f6e 100644 --- a/charms/designate-bind-k8s/tox.ini +++ b/charms/designate-bind-k8s/tox.ini @@ -11,7 +11,7 @@ minversion = 3.18.0 src_path = {toxinidir}/src/ tst_path = {toxinidir}/tests/ lib_path = {toxinidir}/lib/ -project_lib_path = {toxinidir}/lib/charms/bind9_k8s +project_lib_path = {toxinidir}/lib/charms/designate_bind_k8s pyproject_toml = {toxinidir}/pyproject.toml all_path = {[vars]src_path} {[vars]tst_path} {[vars]project_lib_path}