Use new rabbitmq-k8s operator and interfaces

Use renamed rabbitmq-k8s operator in bundles and the new rabbitmq
interface from the same operator in the codebase.

This will require an update to fetch-libs.sh for all charms
to rollout.

Change-Id: I53c8b9d1194895bdf6322cf8a256f32459aa76d7
This commit is contained in:
James Page 2022-10-13 10:06:19 +01:00
parent 6f0acf386c
commit ffb6177be5
6 changed files with 79 additions and 76 deletions

View File

@ -18,7 +18,7 @@ applications:
scale: 1 scale: 1
trust: false trust: false
rabbitmq: rabbitmq:
charm: ch:sunbeam-rabbitmq-operator charm: ch:rabbitmq-k8s
channel: edge channel: edge
scale: 1 scale: 1
trust: true trust: true

View File

@ -19,7 +19,7 @@ applications:
scale: 1 scale: 1
trust: false trust: false
rabbitmq: rabbitmq:
charm: ch:sunbeam-rabbitmq-operator charm: ch:rabbitmq-k8s
channel: edge channel: edge
scale: 1 scale: 1
trust: true trust: true

View File

@ -8,7 +8,7 @@ charmcraft fetch-lib charms.nginx_ingress_integrator.v0.ingress
charmcraft fetch-lib charms.data_platform_libs.v0.database_requires charmcraft fetch-lib charms.data_platform_libs.v0.database_requires
charmcraft fetch-lib charms.sunbeam_keystone_operator.v0.identity_service charmcraft fetch-lib charms.sunbeam_keystone_operator.v0.identity_service
charmcraft fetch-lib charms.keystone_k8s.v0.cloud_credentials charmcraft fetch-lib charms.keystone_k8s.v0.cloud_credentials
charmcraft fetch-lib charms.sunbeam_rabbitmq_operator.v0.amqp charmcraft fetch-lib charms.rabbitmq_k8s.v0.rabbitmq
charmcraft fetch-lib charms.sunbeam_ovn_central_operator.v0.ovsdb charmcraft fetch-lib charms.sunbeam_ovn_central_operator.v0.ovsdb
charmcraft fetch-lib charms.observability_libs.v0.kubernetes_service_patch charmcraft fetch-lib charms.observability_libs.v0.kubernetes_service_patch
charmcraft fetch-lib charms.traefik_k8s.v1.ingress charmcraft fetch-lib charms.traefik_k8s.v1.ingress

View File

@ -95,7 +95,7 @@ class OSBaseOperatorCharm(ops.charm.CharmBase):
"""Relation handlers for the service.""" """Relation handlers for the service."""
handlers = handlers or [] handlers = handlers or []
if self.can_add_handler("amqp", handlers): if self.can_add_handler("amqp", handlers):
self.amqp = sunbeam_rhandlers.AMQPHandler( self.amqp = sunbeam_rhandlers.RabbitMQHandler(
self, self,
"amqp", "amqp",
self.configure_charm, self.configure_charm,

View File

@ -308,8 +308,8 @@ class DBHandler(RelationHandler):
} }
class AMQPHandler(RelationHandler): class RabbitMQHandler(RelationHandler):
"""Handler for managing a amqp relation.""" """Handler for managing a rabbitmq relation."""
DEFAULT_PORT = "5672" DEFAULT_PORT = "5672"
@ -332,8 +332,8 @@ class AMQPHandler(RelationHandler):
logger.debug("Setting up AMQP event handler") logger.debug("Setting up AMQP event handler")
# Lazy import to ensure this lib is only required if the charm # Lazy import to ensure this lib is only required if the charm
# has this relation. # has this relation.
import charms.sunbeam_rabbitmq_operator.v0.amqp as sunbeam_amqp import charms.rabbitmq_k8s.v0.rabbitmq as sunbeam_rabbitmq
amqp = sunbeam_amqp.AMQPRequires( amqp = sunbeam_rabbitmq.RabbitMQRequires(
self.charm, self.relation_name, self.username, self.vhost self.charm, self.relation_name, self.username, self.vhost
) )
self.framework.observe(amqp.on.ready, self._on_amqp_ready) self.framework.observe(amqp.on.ready, self._on_amqp_ready)
@ -383,6 +383,12 @@ class AMQPHandler(RelationHandler):
return ctxt return ctxt
class AMQPHandler(RabbitMQHandler):
"""Backwards compatibility class for older library consumers."""
pass
class IdentityServiceRequiresHandler(RelationHandler): class IdentityServiceRequiresHandler(RelationHandler):
"""Handler for managing a identity-service relation.""" """Handler for managing a identity-service relation."""

View File

@ -1,10 +1,9 @@
"""AMQPProvides and Requires module. """RabbitMQProvides and Requires module.
This library contains the Requires and Provides classes for handling This library contains the Requires and Provides classes for handling
the amqp interface. the rabbitmq interface.
Import `AMQPRequires` in your charm, with the charm object and the Import `RabbitMQRequires` in your charm, with the charm object and the
relation name: relation name:
- self - self
- "amqp" - "amqp"
@ -21,13 +20,13 @@ Two events are also available to respond to:
A basic example showing the usage of this relation follows: A basic example showing the usage of this relation follows:
``` ```
from charms.sunbeam_rabbitmq_operator.v0.amqp import AMQPRequires from charms.rabbitmq_k8s.v0.rabbitmq import RabbitMQRequires
class AMQPClientCharm(CharmBase): class RabbitMQClientCharm(CharmBase):
def __init__(self, *args): def __init__(self, *args):
super().__init__(*args) super().__init__(*args)
# AMQP Requires # RabbitMQ Requires
self.amqp = AMQPRequires( self.amqp = RabbitMQRequires(
self, "amqp", self, "amqp",
username="myusername", username="myusername",
vhost="vhostname" vhost="vhostname"
@ -40,42 +39,42 @@ class AMQPClientCharm(CharmBase):
self.amqp.on.goneaway, self._on_amqp_goneaway) self.amqp.on.goneaway, self._on_amqp_goneaway)
def _on_amqp_connected(self, event): def _on_amqp_connected(self, event):
'''React to the AMQP connected event. '''React to the RabbitMQ connected event.
This event happens when n AMQP relation is added to the This event happens when n RabbitMQ relation is added to the
model before credentials etc have been provided. model before credentials etc have been provided.
''' '''
# Do something before the relation is complete # Do something before the relation is complete
pass pass
def _on_amqp_ready(self, event): def _on_amqp_ready(self, event):
'''React to the AMQP ready event. '''React to the RabbitMQ ready event.
The AMQP interface will use the provided username and vhost for the The RabbitMQ interface will use the provided username and vhost for the
request to the rabbitmq server. request to the rabbitmq server.
''' '''
# AMQP Relation is ready. Do something with the completed relation. # RabbitMQ Relation is ready. Do something with the completed relation.
pass pass
def _on_amqp_goneaway(self, event): def _on_amqp_goneaway(self, event):
'''React to the AMQP goneaway event. '''React to the RabbitMQ goneaway event.
This event happens when an AMQP relation is removed. This event happens when an RabbitMQ relation is removed.
''' '''
# AMQP Relation has goneaway. shutdown services or suchlike # RabbitMQ Relation has goneaway. shutdown services or suchlike
pass pass
``` ```
""" """
# The unique Charmhub library identifier, never change it # The unique Charmhub library identifier, never change it
LIBID = "ab1414b6baf044f099caf9c117f1a101" LIBID = "45622352791142fd9cf87232e3bd6f2a"
# 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 = 4 LIBPATCH = 1
import logging import logging
@ -94,39 +93,38 @@ from typing import List
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class AMQPConnectedEvent(EventBase): class RabbitMQConnectedEvent(EventBase):
"""AMQP connected Event.""" """RabbitMQ connected Event."""
pass pass
class AMQPReadyEvent(EventBase): class RabbitMQReadyEvent(EventBase):
"""AMQP ready for use Event.""" """RabbitMQ ready for use Event."""
pass pass
class AMQPGoneAwayEvent(EventBase): class RabbitMQGoneAwayEvent(EventBase):
"""AMQP relation has gone-away Event""" """RabbitMQ relation has gone-away Event"""
pass pass
class AMQPServerEvents(ObjectEvents): class RabbitMQServerEvents(ObjectEvents):
"""Events class for `on`""" """Events class for `on`"""
connected = EventSource(AMQPConnectedEvent) connected = EventSource(RabbitMQConnectedEvent)
ready = EventSource(AMQPReadyEvent) ready = EventSource(RabbitMQReadyEvent)
goneaway = EventSource(AMQPGoneAwayEvent) goneaway = EventSource(RabbitMQGoneAwayEvent)
class AMQPRequires(Object): class RabbitMQRequires(Object):
""" """
AMQPRequires class RabbitMQRequires class
""" """
on = AMQPServerEvents() on = RabbitMQServerEvents()
_stored = StoredState()
def __init__(self, charm, relation_name: str, username: str, vhost: str): def __init__(self, charm, relation_name: str, username: str, vhost: str):
super().__init__(charm, relation_name) super().__init__(charm, relation_name)
@ -152,89 +150,88 @@ class AMQPRequires(Object):
) )
def _on_amqp_relation_joined(self, event): def _on_amqp_relation_joined(self, event):
"""AMQP relation joined.""" """RabbitMQ relation joined."""
logging.debug("RabbitMQAMQPRequires on_joined") logging.debug("RabbitMQRabbitMQRequires on_joined")
self.on.connected.emit() self.on.connected.emit()
self.request_access(self.username, self.vhost) self.request_access(self.username, self.vhost)
def _on_amqp_relation_changed(self, event): def _on_amqp_relation_changed(self, event):
"""AMQP relation changed.""" """RabbitMQ relation changed."""
logging.debug("RabbitMQAMQPRequires on_changed/departed") logging.debug("RabbitMQRabbitMQRequires on_changed/departed")
if self.password: if self.password:
self.on.ready.emit() self.on.ready.emit()
def _on_amqp_relation_broken(self, event): def _on_amqp_relation_broken(self, event):
"""AMQP relation broken.""" """RabbitMQ relation broken."""
logging.debug("RabbitMQAMQPRequires on_broken") logging.debug("RabbitMQRabbitMQRequires on_broken")
self.on.goneaway.emit() self.on.goneaway.emit()
@property @property
def _amqp_rel(self) -> Relation: def _amqp_rel(self) -> Relation:
"""The AMQP relation.""" """The RabbitMQ relation."""
return self.framework.model.get_relation(self.relation_name) return self.framework.model.get_relation(self.relation_name)
@property @property
def password(self) -> str: def password(self) -> str:
"""Return the AMQP password from the server side of the relation.""" """Return the RabbitMQ password from the server side of the relation."""
return self._amqp_rel.data[self._amqp_rel.app].get("password") return self._amqp_rel.data[self._amqp_rel.app].get("password")
@property @property
def hostname(self) -> str: def hostname(self) -> str:
"""Return the hostname from the AMQP relation""" """Return the hostname from the RabbitMQ relation"""
return self._amqp_rel.data[self._amqp_rel.app].get("hostname") return self._amqp_rel.data[self._amqp_rel.app].get("hostname")
@property @property
def ssl_port(self) -> str: def ssl_port(self) -> str:
"""Return the SSL port from the AMQP relation""" """Return the SSL port from the RabbitMQ relation"""
return self._amqp_rel.data[self._amqp_rel.app].get("ssl_port") return self._amqp_rel.data[self._amqp_rel.app].get("ssl_port")
@property @property
def ssl_ca(self) -> str: def ssl_ca(self) -> str:
"""Return the SSL port from the AMQP relation""" """Return the SSL port from the RabbitMQ relation"""
return self._amqp_rel.data[self._amqp_rel.app].get("ssl_ca") return self._amqp_rel.data[self._amqp_rel.app].get("ssl_ca")
@property @property
def hostnames(self) -> List[str]: def hostnames(self) -> List[str]:
"""Return a list of remote RMQ hosts from the AMQP relation""" """Return a list of remote RMQ hosts from the RabbitMQ relation"""
_hosts = [] _hosts = []
for unit in self._amqp_rel.units: for unit in self._amqp_rel.units:
_hosts.append(self._amqp_rel.data[unit].get("ingress-address")) _hosts.append(self._amqp_rel.data[unit].get("ingress-address"))
return _hosts return _hosts
def request_access(self, username: str, vhost: str) -> None: def request_access(self, username: str, vhost: str) -> None:
"""Request access to the AMQP server.""" """Request access to the RabbitMQ server."""
if self.model.unit.is_leader(): if self.model.unit.is_leader():
logging.debug("Requesting AMQP user and vhost") logging.debug("Requesting RabbitMQ user and vhost")
self._amqp_rel.data[self.charm.app]["username"] = username self._amqp_rel.data[self.charm.app]["username"] = username
self._amqp_rel.data[self.charm.app]["vhost"] = vhost self._amqp_rel.data[self.charm.app]["vhost"] = vhost
class HasAMQPClientsEvent(EventBase): class HasRabbitMQClientsEvent(EventBase):
"""Has AMQPClients Event.""" """Has RabbitMQClients Event."""
pass pass
class ReadyAMQPClientsEvent(EventBase): class ReadyRabbitMQClientsEvent(EventBase):
"""AMQPClients Ready Event.""" """RabbitMQClients Ready Event."""
pass pass
class AMQPClientEvents(ObjectEvents): class RabbitMQClientEvents(ObjectEvents):
"""Events class for `on`""" """Events class for `on`"""
has_amqp_clients = EventSource(HasAMQPClientsEvent) has_amqp_clients = EventSource(HasRabbitMQClientsEvent)
ready_amqp_clients = EventSource(ReadyAMQPClientsEvent) ready_amqp_clients = EventSource(ReadyRabbitMQClientsEvent)
class AMQPProvides(Object): class RabbitMQProvides(Object):
""" """
AMQPProvides class RabbitMQProvides class
""" """
on = AMQPClientEvents() on = RabbitMQClientEvents()
_stored = StoredState()
def __init__(self, charm, relation_name, callback): def __init__(self, charm, relation_name, callback):
super().__init__(charm, relation_name) super().__init__(charm, relation_name)
@ -255,35 +252,35 @@ class AMQPProvides(Object):
) )
def _on_amqp_relation_joined(self, event): def _on_amqp_relation_joined(self, event):
"""Handle AMQP joined.""" """Handle RabbitMQ joined."""
logging.debug("RabbitMQAMQPProvides on_joined data={}" logging.debug("RabbitMQRabbitMQProvides on_joined data={}"
.format(event.relation.data)) .format(event.relation.data[event.relation.app]))
self.on.has_amqp_clients.emit() self.on.has_amqp_clients.emit()
def _on_amqp_relation_changed(self, event): def _on_amqp_relation_changed(self, event):
"""Handle AMQP changed.""" """Handle RabbitMQ changed."""
logging.debug("RabbitMQAMQPProvides on_changed data={}" logging.debug("RabbitMQRabbitMQProvides on_changed data={}"
.format(event.relation.data)) .format(event.relation.data[event.relation.app]))
# Validate data on the relation # Validate data on the relation
if self.username(event) and self.vhost(event): if self.username(event) and self.vhost(event):
self.on.ready_amqp_clients.emit() self.on.ready_amqp_clients.emit()
if self.charm.unit.is_leader(): if self.charm.unit.is_leader():
self.callback(event, self.username(event), self.vhost(event)) self.callback(event, self.username(event), self.vhost(event))
else: else:
logging.warning("Received AMQP changed event without the " logging.warning("Received RabbitMQ changed event without the "
"expected keys ('username', 'vhost') in the " "expected keys ('username', 'vhost') in the "
"application data bag. Incompatible charm in " "application data bag. Incompatible charm in "
"other end of relation?") "other end of relation?")
def _on_amqp_relation_broken(self, event): def _on_amqp_relation_broken(self, event):
"""Handle AMQP broken.""" """Handle RabbitMQ broken."""
logging.debug("RabbitMQAMQPProvides on_departed") logging.debug("RabbitMQRabbitMQProvides on_departed")
# TODO clear data on the relation # TODO clear data on the relation
def username(self, event): def username(self, event):
"""Return the AMQP username from the client side of the relation.""" """Return the RabbitMQ username from the client side of the relation."""
return event.relation.data[event.relation.app].get("username") return event.relation.data[event.relation.app].get("username")
def vhost(self, event): def vhost(self, event):
"""Return the AMQP vhost from the client side of the relation.""" """Return the RabbitMQ vhost from the client side of the relation."""
return event.relation.data[event.relation.app].get("vhost") return event.relation.data[event.relation.app].get("vhost")