Messaging
Fedora uses many event-driven services triggered by messages. In the past, this was done with ZeroMQ and fedmsg. This has been replaced by an AMQP message broker and the fedora-messaging for Python applications. This documentation outlines the policies for sending and receiving messages. To learn how to send and receive messages, see the fedora-messaging documentation.
Broker URLs
The broker consists of multiple RabbitMQ nodes. They are available
through the proxies at amqps://rabbitmq.fedoraproject.org
for
production and amqps://rabbitmq.stg.fedoraproject.org
for staging.
Clients can connect using these URLs both inside and outside the Fedora
VPN, but users outside need to use a separate virtual host. Consult the
fedora-messaging
documentation for details on how to connect externally.
Identity
In order to help with debugging, clients must configure the
client_properties
option to include their application name under the app
key. Clients
should include the application version, if possible, in the
app_version
key.
Authentication
When applications are deployed, clients must authenticate with the message broker over a TLS connection using x509 certificates. There are configuration options for this in fedora-messaging.
Clients require certificates issued by Fedora Infrastructure. If you’re not using the external, read-only user, file a ticket requesting a certificate for the AMQP broker and be sure to provide the username you plan to use. This is placed in the Common Name of the client certificate and must match the name of the user you create in AMQP. Consult the Authorization section below for details on creating users, queues, and bindings.
Authorization
The message broker can use virtual
hosts to allow multiple applications to use the broker. The general
purpose publish-subscribe virtual host is called /pubsub
and has its
authorization policy outlined below. If your application is using a
different virtual host for private messaging (for example, your
application uses Celery), different authorization rules apply.
pubsub Virtual Host
AMQP clients do not have permission to create exchanges, queues, or bindings. However, they can and should declare the exchanges, queues, and bindings they expect to exist in their fedora-messaging configuration so that if they do not exist, the application will fail with a helpful error message about which resource is not available.
Because AMQP clients don’t have permission to create objects, you need to set passive_declares = true or you will get 403 Permission Denied errors. |
Users, exchanges, queues, bindings, and virtual hosts other objects are managed in the broker using the Fedora Infrastructure Ansible project and must be declared there.
To do so, you can use the rabbit/queue
role in the Ansible repository.
An example usage in your deployment playbook would be:
roles: - role: rabbit/queue username: bodhi queue_name: bodhi_masher routing_keys: - "routing_key1" - "routing_key2"
Note that users only have permissions to read from queues prefixed with their name so if your username is "bodhi", all queues must start with "bodhi". The username must also match the common name in the x509 certificate used for authentication.
If you want to create a user that will only need to publish messages,
and not consume them, you can use the rabbit/user
role in the Ansible
repository. An example usage in your deployment playbook would be:
roles: - role: rabbit/user username: bodhi
Please note that the username must match the TLS certificate’s Common Name, and they were created with the environment suffix. As a result, if you want the username to match in staging too, you should use:
username: "bodhi{{ env_suffix}}"
Bindings
Messages from AMQP publishers are sent to the amq.topic
exchange.
Messages from ZeroMQ publishers are sent to the zmq.topic
exchange. In
order to receive all messages during the transition period from ZeroMQ
to AMQP, be sure to bind your consumers to both exchanges:
[[bindings]] queue = "your queue" exchange = "amq.topic" routing_keys = ["key1", "key2"] [[bindings]] queue = "your queue" exchange = "zmq.topic" routing_keys = ["key1", "key2"]
Want to help? Learn how to contribute to Fedora Docs ›