Enable notifications
Currently the notifications are not sent by the service. Add configuration parameter enable-telemetry-notifications to toggle notifications. Set notification driver to messagingv2 when the parameter is set to True. Update metadata.yaml to include amqp as an optional interface. Change-Id: Ia77fa388e238ca13a7194a3d38de33a42f57538b
This commit is contained in:
parent
cdfa393ec3
commit
8787171492
@ -64,3 +64,7 @@ options:
|
|||||||
description: |
|
description: |
|
||||||
Keystone identity backend, valid options are sql and pam
|
Keystone identity backend, valid options are sql and pam
|
||||||
|
|
||||||
|
enable-telemetry-notifications:
|
||||||
|
type: boolean
|
||||||
|
default: False
|
||||||
|
description: Enable notifications to send to telemetry.
|
||||||
|
@ -5,5 +5,5 @@ 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.v1.identity_service
|
#charmcraft fetch-lib charms.sunbeam_keystone_operator.v1.identity_service
|
||||||
#charmcraft fetch-lib charms.sunbeam_keystone_operator.v0.identity_credentials
|
#charmcraft fetch-lib charms.sunbeam_keystone_operator.v0.identity_credentials
|
||||||
charmcraft fetch-lib charms.sunbeam_rabbitmq_operator.v0.amqp
|
charmcraft fetch-lib charms.rabbitmq_k8s.v0.rabbitmq
|
||||||
charmcraft fetch-lib charms.traefik_k8s.v1.ingress
|
charmcraft fetch-lib charms.traefik_k8s.v1.ingress
|
||||||
|
@ -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")
|
@ -41,6 +41,9 @@ requires:
|
|||||||
ingress-public:
|
ingress-public:
|
||||||
interface: ingress
|
interface: ingress
|
||||||
limit: 1
|
limit: 1
|
||||||
|
amqp:
|
||||||
|
interface: rabbitmq
|
||||||
|
optional: true
|
||||||
|
|
||||||
peers:
|
peers:
|
||||||
peers:
|
peers:
|
||||||
|
@ -729,12 +729,14 @@ export OS_AUTH_VERSION=3
|
|||||||
@property
|
@property
|
||||||
def config_contexts(self) -> List[sunbeam_contexts.ConfigContext]:
|
def config_contexts(self) -> List[sunbeam_contexts.ConfigContext]:
|
||||||
"""Configuration adapters for the operator."""
|
"""Configuration adapters for the operator."""
|
||||||
return [
|
contexts = super().config_contexts
|
||||||
KeystoneConfigAdapter(self, "ks_config"),
|
contexts.extend(
|
||||||
KeystoneLoggingAdapter(self, "ks_logging"),
|
[
|
||||||
sunbeam_contexts.WSGIWorkerConfigContext(self, "wsgi_config"),
|
KeystoneConfigAdapter(self, "ks_config"),
|
||||||
sunbeam_contexts.CharmConfigContext(self, "options"),
|
KeystoneLoggingAdapter(self, "ks_logging"),
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
return contexts
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def container_configs(self):
|
def container_configs(self):
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
log_config_append = /etc/keystone/logging.conf
|
log_config_append = /etc/keystone/logging.conf
|
||||||
debug = {{ options.debug }}
|
debug = {{ options.debug }}
|
||||||
|
|
||||||
|
{% if amqp -%}
|
||||||
|
transport_url = {{ amqp.transport_url }}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
[identity]
|
[identity]
|
||||||
driver = {{ ks_config.identity_backend }}
|
driver = {{ ks_config.identity_backend }}
|
||||||
{% if ks_config.default_domain_id -%}
|
{% if ks_config.default_domain_id -%}
|
||||||
@ -106,3 +110,5 @@ admin_project_name = admin
|
|||||||
# This goes in the section above, selectively
|
# This goes in the section above, selectively
|
||||||
# Bug #1819134
|
# Bug #1819134
|
||||||
max_request_body_size = 114688
|
max_request_body_size = 114688
|
||||||
|
|
||||||
|
{% include "parts/section-oslo-notifications" %}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
{% if options.enable_telemetry_notifications -%}
|
||||||
|
[oslo_messaging_notifications]
|
||||||
|
driver = messagingv2
|
||||||
|
{%- endif %}
|
@ -54,6 +54,9 @@ relations:
|
|||||||
- - traefik:ingress
|
- - traefik:ingress
|
||||||
- glance:ingress-public
|
- glance:ingress-public
|
||||||
|
|
||||||
|
- - rabbitmq:amqp
|
||||||
|
- keystone:amqp
|
||||||
|
|
||||||
- - mysql:database
|
- - mysql:database
|
||||||
- keystone:database
|
- keystone:database
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user