Rename to designate-bind-k8s
Moved nonce from stored state to secret
This commit is contained in:
parent
1b42ad3265
commit
cbd313d56d
@ -1,4 +1,4 @@
|
|||||||
# bind9-k8s
|
# designate-bind-k8s
|
||||||
|
|
||||||
## Developing
|
## 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)
|
Get familiarise with [Charmed Operator Framework](https://juju.is/docs/sdk)
|
||||||
and [Sunbeam documentation](sunbeam-docs).
|
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.
|
OSBaseOperatorAPICharm from the library.
|
||||||
|
|
||||||
## Intended use case
|
## 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.
|
on a kubernetes based environment.
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
@ -41,11 +41,11 @@ run:
|
|||||||
|
|
||||||
To deploy the local test instance:
|
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
|
||||||
|
|
||||||
<!-- LINKS -->
|
<!-- LINKS -->
|
||||||
|
|
||||||
[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
|
[sunbeam-docs]: https://opendev.org/openstack/charm-ops-sunbeam/src/branch/main/README.rst
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@ Avoid using this README file for information that is maintained or published els
|
|||||||
Use links instead.
|
Use links instead.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
# charm-bind9
|
# designate-bind-k8s
|
||||||
|
|
||||||
Charmhub package name: operator-template
|
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.
|
Describe your charm in one or two sentences.
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ Two events are also available to respond to:
|
|||||||
- goneaway
|
- goneaway
|
||||||
A basic example showing the usage of this relation follows:
|
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
|
BindRndcRequires
|
||||||
)
|
)
|
||||||
class BindRndcClientCharm(CharmBase):
|
class BindRndcClientCharm(CharmBase):
|
||||||
@ -31,6 +31,13 @@ class BindRndcClientCharm(CharmBase):
|
|||||||
self.bind_rndc.on.goneaway,
|
self.bind_rndc.on.goneaway,
|
||||||
self._on_bind_rndc_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):
|
def _on_bind_rndc_ready(self, event):
|
||||||
'''React to the Bind Rndc Ready event.
|
'''React to the Bind Rndc Ready event.
|
||||||
This event happens when BindRndc relation is added to the
|
This event happens when BindRndc relation is added to the
|
||||||
@ -49,7 +56,6 @@ class BindRndcClientCharm(CharmBase):
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import secrets
|
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
Dict,
|
Dict,
|
||||||
@ -63,14 +69,41 @@ import ops
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# The unique Charmhub library identifier, never change it
|
# The unique Charmhub library identifier, never change it
|
||||||
LIBID = "0fb2f64f2a1344feb80044cee22ef3a8"
|
LIBID = "1cb766c981874e7383d17cf54148b3d4"
|
||||||
|
|
||||||
# Increment this major API version when introducing breaking changes
|
# Increment this major API version when introducing breaking changes
|
||||||
LIBAPI = 0
|
LIBAPI = 0
|
||||||
|
|
||||||
# Increment this PATCH version before using `charmcraft publish-lib` or reset
|
# Increment this PATCH version before using `charmcraft publish-lib` or reset
|
||||||
# to 0 if you are raising the major API version
|
# 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):
|
class BindRndcReadyEvent(ops.EventBase):
|
||||||
@ -81,22 +114,16 @@ class BindRndcReadyEvent(ops.EventBase):
|
|||||||
handle: ops.Handle,
|
handle: ops.Handle,
|
||||||
relation_id: int,
|
relation_id: int,
|
||||||
relation_name: str,
|
relation_name: str,
|
||||||
algorithm: str,
|
|
||||||
secret: str,
|
|
||||||
):
|
):
|
||||||
super().__init__(handle)
|
super().__init__(handle)
|
||||||
self.relation_id = relation_id
|
self.relation_id = relation_id
|
||||||
self.relation_name = relation_name
|
self.relation_name = relation_name
|
||||||
self.algorithm = algorithm
|
|
||||||
self.secret = secret
|
|
||||||
|
|
||||||
def snapshot(self) -> dict:
|
def snapshot(self) -> dict:
|
||||||
"""Return snapshot data that should be persisted."""
|
"""Return snapshot data that should be persisted."""
|
||||||
return {
|
return {
|
||||||
"relation_id": self.relation_id,
|
"relation_id": self.relation_id,
|
||||||
"relation_name": self.relation_name,
|
"relation_name": self.relation_name,
|
||||||
"algorithm": self.algorithm,
|
|
||||||
"secret": self.secret,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def restore(self, snapshot: Dict[str, Any]):
|
def restore(self, snapshot: Dict[str, Any]):
|
||||||
@ -104,8 +131,6 @@ class BindRndcReadyEvent(ops.EventBase):
|
|||||||
super().restore(snapshot)
|
super().restore(snapshot)
|
||||||
self.relation_id = snapshot["relation_id"]
|
self.relation_id = snapshot["relation_id"]
|
||||||
self.relation_name = snapshot["relation_name"]
|
self.relation_name = snapshot["relation_name"]
|
||||||
self.algorithm = snapshot["algorithm"]
|
|
||||||
self.secret = snapshot["secret"]
|
|
||||||
|
|
||||||
|
|
||||||
class BindRndcGoneAwayEvent(ops.EventBase):
|
class BindRndcGoneAwayEvent(ops.EventBase):
|
||||||
@ -117,7 +142,8 @@ class BindRndcGoneAwayEvent(ops.EventBase):
|
|||||||
class BindRndcRequirerEvents(ops.ObjectEvents):
|
class BindRndcRequirerEvents(ops.ObjectEvents):
|
||||||
"""List of events that the BindRndc requires charm can leverage."""
|
"""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)
|
goneaway = ops.EventSource(BindRndcGoneAwayEvent)
|
||||||
|
|
||||||
|
|
||||||
@ -125,13 +151,11 @@ class BindRndcRequires(ops.Object):
|
|||||||
"""Class to be instantiated by the requiring side of the relation."""
|
"""Class to be instantiated by the requiring side of the relation."""
|
||||||
|
|
||||||
on = BindRndcRequirerEvents()
|
on = BindRndcRequirerEvents()
|
||||||
_stored = ops.StoredState()
|
|
||||||
|
|
||||||
def __init__(self, charm: ops.CharmBase, relation_name: str):
|
def __init__(self, charm: ops.CharmBase, relation_name: str):
|
||||||
super().__init__(charm, relation_name)
|
super().__init__(charm, relation_name)
|
||||||
self.charm = charm
|
self.charm = charm
|
||||||
self.relation_name = relation_name
|
self.relation_name = relation_name
|
||||||
self._stored.set_default(nonce="")
|
|
||||||
self.framework.observe(
|
self.framework.observe(
|
||||||
self.charm.on[relation_name].relation_joined,
|
self.charm.on[relation_name].relation_joined,
|
||||||
self._on_relation_joined,
|
self._on_relation_joined,
|
||||||
@ -147,24 +171,20 @@ class BindRndcRequires(ops.Object):
|
|||||||
|
|
||||||
def _on_relation_joined(self, event: ops.RelationJoinedEvent):
|
def _on_relation_joined(self, event: ops.RelationJoinedEvent):
|
||||||
"""Handle relation joined event."""
|
"""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):
|
def _on_relation_changed(self, event: ops.RelationJoinedEvent):
|
||||||
"""Handle relation changed event."""
|
"""Handle relation changed event."""
|
||||||
host = self.host(event.relation)
|
host = self.host(event.relation)
|
||||||
rndc_key = self.get_rndc_key(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:
|
if all((host, rndc_key)):
|
||||||
algorithm = rndc_key["algorithm"]
|
self.on.ready.emit(
|
||||||
secret = rndc_key["secret"]
|
|
||||||
self.on.bind_rndc_ready.emit(
|
|
||||||
event.relation.id,
|
event.relation.id,
|
||||||
event.relation.name,
|
event.relation.name,
|
||||||
algorithm,
|
|
||||||
secret,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def _on_relation_broken(self, event: ops.RelationBrokenEvent):
|
def _on_relation_broken(self, event: ops.RelationBrokenEvent):
|
||||||
@ -177,33 +197,25 @@ class BindRndcRequires(ops.Object):
|
|||||||
return None
|
return None
|
||||||
return relation.data[relation.app].get("host")
|
return relation.data[relation.app].get("host")
|
||||||
|
|
||||||
def nonce(self) -> str:
|
def nonce(self, relation: ops.Relation) -> Optional[str]:
|
||||||
"""Return nonce from stored state."""
|
"""Return nonce from relation."""
|
||||||
return self._stored.nonce
|
return relation.data[self.charm.unit].get("nonce")
|
||||||
|
|
||||||
def get_rndc_key(self, relation: ops.Relation) -> Optional[dict]:
|
def get_rndc_key(self, relation: ops.Relation) -> Optional[dict]:
|
||||||
"""Get rndc keys."""
|
"""Get rndc keys."""
|
||||||
if relation.app is None:
|
if relation.app is None:
|
||||||
return None
|
return None
|
||||||
if self._stored.nonce == "":
|
if self.nonce(relation) is None:
|
||||||
logger.debug("No nonce set for unit yet")
|
logger.debug("No nonce set for unit yet")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return json.loads(
|
return json.loads(
|
||||||
relation.data[relation.app].get("rndc_keys", "{}")
|
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."""
|
"""Request rndc key over the relation."""
|
||||||
if self._stored.nonce == "":
|
relation.data[self.charm.unit]["nonce"] = 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
|
|
||||||
|
|
||||||
|
|
||||||
class NewBindClientAttachedEvent(ops.EventBase):
|
class NewBindClientAttachedEvent(ops.EventBase):
|
@ -1,5 +1,5 @@
|
|||||||
name: bind9-k8s
|
name: designate-bind-k8s
|
||||||
summary: OpenStack bind9 service
|
summary: OpenStack designate-bind service
|
||||||
maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>
|
maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>
|
||||||
description: |
|
description: |
|
||||||
Domain Name Service (DNS) is an Internet service that maps IP addresses and fully qualified domain names (FQDN) to one another.
|
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
|
- juju >= 3.1
|
||||||
tags:
|
tags:
|
||||||
- openstack
|
- openstack
|
||||||
source: https://opendev.org/openstack/charm-bind9-k8s
|
source: https://opendev.org/openstack/charm-designate-bind-k8s
|
||||||
issues: https://bugs.launchpad.net/charm-bind9-k8s
|
issues: https://bugs.launchpad.net/charm-designate-bind-k8s
|
||||||
|
|
||||||
containers:
|
containers:
|
||||||
bind9:
|
designate-bind:
|
||||||
resource: bind9-image
|
resource: designate-bind-image
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
bind9-image:
|
designate-bind-image:
|
||||||
type: oci-image
|
type: oci-image
|
||||||
description: OCI image for bind9
|
description: OCI image for bind9
|
||||||
upstream-source: ubuntu/bind9:9.18-22.04_beta
|
upstream-source: ubuntu/bind9:9.18-22.04_beta
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Bind9 Operator Charm.
|
"""designate-bind Operator Charm.
|
||||||
|
|
||||||
This charm provide Bind9 services
|
This charm provide designate-bind services
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
@ -27,7 +27,7 @@ from typing import (
|
|||||||
List,
|
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 charms.observability_libs.v1.kubernetes_service_patch as kubernetes_service_patch
|
||||||
import lightkube.models.core_v1 as core_v1
|
import lightkube.models.core_v1 as core_v1
|
||||||
import ops.charm
|
import ops.charm
|
||||||
@ -50,17 +50,17 @@ RNDC_REVISION_KEY = "rndc_revision"
|
|||||||
|
|
||||||
|
|
||||||
class BindPebbleHandler(sunbeam_chandlers.ServicePebbleHandler):
|
class BindPebbleHandler(sunbeam_chandlers.ServicePebbleHandler):
|
||||||
"""Pebble handler for bind9 service."""
|
"""Pebble handler for designate-bind service."""
|
||||||
|
|
||||||
def get_layer(self) -> dict:
|
def get_layer(self) -> dict:
|
||||||
"""Pebble layer for bind 9 service."""
|
"""Pebble layer for bind 9 service."""
|
||||||
return {
|
return {
|
||||||
"summary": "bind9 layer",
|
"summary": "designate-bind layer",
|
||||||
"description": "pebble config layer for bind9",
|
"description": "pebble config layer for designate-bind",
|
||||||
"services": {
|
"services": {
|
||||||
"bind9": {
|
"designate-bind": {
|
||||||
"override": "replace",
|
"override": "replace",
|
||||||
"summary": "bind9",
|
"summary": "designate-bind",
|
||||||
"command": "/usr/sbin/named -g -u bind",
|
"command": "/usr/sbin/named -g -u bind",
|
||||||
"startup": "enabled",
|
"startup": "enabled",
|
||||||
}
|
}
|
||||||
@ -181,7 +181,7 @@ class BindOperatorCharm(sunbeam_charm.OSBaseOperatorCharmK8S):
|
|||||||
"""Charm the service."""
|
"""Charm the service."""
|
||||||
|
|
||||||
_state = StoredState()
|
_state = StoredState()
|
||||||
service_name = "bind9"
|
service_name = "designate-bind"
|
||||||
|
|
||||||
# mandatory_relations = {}
|
# mandatory_relations = {}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
bundle: kubernetes
|
bundle: kubernetes
|
||||||
applications:
|
applications:
|
||||||
bind9:
|
designate-bind:
|
||||||
charm: ../../bind9-k8s.charm
|
charm: ../../designate-bind-k8s.charm
|
||||||
scale: 1
|
scale: 1
|
||||||
trust: false
|
trust: false
|
||||||
resources:
|
resources:
|
||||||
bind9-image: ubuntu/bind9:9.18-22.04_beta
|
designate-bind-image: ubuntu/designate-bind:9.18-22.04_beta
|
||||||
|
@ -17,6 +17,6 @@ tests_options:
|
|||||||
smoke: True
|
smoke: True
|
||||||
|
|
||||||
target_deploy_status:
|
target_deploy_status:
|
||||||
bind9:
|
designate-bind:
|
||||||
workload-status: active
|
workload-status: active
|
||||||
workload-status-message-regex: '^$'
|
workload-status-message-regex: '^$'
|
||||||
|
@ -11,7 +11,7 @@ minversion = 3.18.0
|
|||||||
src_path = {toxinidir}/src/
|
src_path = {toxinidir}/src/
|
||||||
tst_path = {toxinidir}/tests/
|
tst_path = {toxinidir}/tests/
|
||||||
lib_path = {toxinidir}/lib/
|
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
|
pyproject_toml = {toxinidir}/pyproject.toml
|
||||||
all_path = {[vars]src_path} {[vars]tst_path} {[vars]project_lib_path}
|
all_path = {[vars]src_path} {[vars]tst_path} {[vars]project_lib_path}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user