-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a hands on tutorial for using the operator (#172)
- Loading branch information
Showing
1 changed file
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
# Tutorial | ||
|
||
In this tutorial, we will use the Messaging Topology Operator to create and configure: | ||
1. a queue | ||
1. a user | ||
1. assign permission to the user | ||
1. publish and consume messages to the created queue | ||
|
||
### Prerequisites: | ||
Your Kubernetes cluster needs to have: | ||
1. Cluster Operator and Messaging Topology Operator installed | ||
1. a RabbitmqCluster deployed | ||
|
||
### Create a queue | ||
|
||
You can create a queue by creating a custom resource `queues.rabbitmq.com`. For example: | ||
```yaml | ||
apiVersion: rabbitmq.com/v1beta1 | ||
kind: Queue | ||
metadata: | ||
name: tutorial | ||
namespace: REPLACEME #same namespace as the deployed RabbitmqCluster | ||
spec: | ||
name: tutorial # this will be the name of the queue | ||
rabbitmqClusterReference: | ||
name: # name of the RabbitmqCluster | ||
``` | ||
|
||
This will create a classic queue named 'tutorial' in default '/' vhost. To check the queue is created | ||
successfully, you can ssh onto your RabbitmqCluster pod | ||
|
||
```bash | ||
kubectl exec -it NAME-OF-THE-RMQ-POD -- /bin/bash | ||
``` | ||
|
||
and run the following command to see if queue 'tutorial' is listed: | ||
|
||
```bash | ||
rabbitmqctl list_queues | ||
``` | ||
|
||
### Create a User | ||
|
||
You can create a RabbitMQ user with pre-defined username and password. | ||
Username and password are passed to the Operator through a Kubernetes secret object: | ||
```yaml | ||
apiVersion: v1 | ||
kind: Secret | ||
metadata: | ||
name: user-secret | ||
namespace: REPLACEME #same namespace as the deployed RabbitmqCluster | ||
type: Opaque | ||
stringData: | ||
username: test | ||
password: test | ||
``` | ||
|
||
Then, lets create a RabbitMQ user by creating a custom resource `users.rabbitmq.com`: | ||
```yaml | ||
apiVersion: rabbitmq.com/v1beta1 | ||
kind: User | ||
metadata: | ||
name: tutorial-user | ||
namespace: REPLACEME #same namespace as the deployed RabbitmqCluster | ||
spec: | ||
importCredentialsSecret: | ||
name: user-secret | ||
rabbitmqClusterReference: | ||
name: # name of the RabbitmqCluster | ||
``` | ||
|
||
This will create a RabbitMQ user with username 'test' and password 'test' (as specified in the Kubernetes secret). | ||
|
||
### Configure Permissions | ||
|
||
Before we can use the user 'test' to publish and consume messages, we need to grant it permissions. | ||
This can be achieved by create a custom resource `permissions.rabbitmq.com`: | ||
```yaml | ||
apiVersion: rabbitmq.com/v1beta1 | ||
kind: Permission | ||
metadata: | ||
name: tutorial-user-permission | ||
namespace: REPLACEME #same namespace as the deployed RabbitmqCluster | ||
spec: | ||
vhost: "/" | ||
user: "test" # name of the created user | ||
permissions: | ||
write: ".*" | ||
configure: ".*" | ||
read: ".*" | ||
rabbitmqClusterReference: | ||
name: # name of the RabbitmqCluster | ||
``` | ||
|
||
This is the equivalent of running `rabbitmqctl set_permissions -p "/" "test" ".*" ".*" ".*"`. | ||
|
||
To check user 'test' is created and configured with the right permissions, you can ssh onto your | ||
RabbitmqCluster pod, and run: | ||
```bash | ||
rabbitmqctl list_permissions | ||
``` | ||
This command will list all users that has access to the default vhost '/'. You should see user 'test' listed | ||
here with read, write, and configure permissions all set to '.*'. | ||
|
||
### Publish and consume messages | ||
|
||
We now have everything we need to be able to publish and consume messages. The following Golang example | ||
uses the created user 'test' to publish and consume messages from queue 'tutorial'. The example uses the [RabbitMQ | ||
Golang client](https://github.com/rabbitmq/amqp091-go): | ||
|
||
```golang | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
amqp "github.com/rabbitmq/amqp091-go" | ||
) | ||
|
||
func main() { | ||
rmqHostname := "" // please put in external ip or hostname for the deployed RabbitmqCluster | ||
conn, err := amqp.Dial(fmt.Sprintf("amqp://test:test@%s:5672/", rmqHostname)) // username 'test' and password 'test' | ||
if err != nil { | ||
log.Fatalf("%s: %s", "Failed to connect to RabbitMQ", err) | ||
} | ||
defer conn.Close() | ||
|
||
ch, err := conn.Channel() | ||
if err != nil { | ||
log.Fatalf("%s: %s", "Failed to open a channel", err) | ||
} | ||
defer ch.Close() | ||
|
||
// publish message | ||
msg := "Topology Operator Tutorial" // message body | ||
if err = ch.Publish( | ||
"", | ||
"tutorial", // name of the queue as routing key | ||
false, // mandatory | ||
false, // immediate | ||
amqp.Publishing{ | ||
ContentType: "text/plain", | ||
Body: []byte(msg), | ||
}); err != nil { | ||
log.Fatalf("%s: %s", "Failed to publish a message", err) | ||
} | ||
log.Printf("Message published: %s", msg) | ||
|
||
//consume and print message | ||
msgs, err := ch.Consume( | ||
"tutorial", // name of the queue | ||
"", | ||
true, // auto-ack | ||
false, // exclusive | ||
false, // no-local | ||
false, // no-wait | ||
nil, // args | ||
) | ||
if err != nil { | ||
log.Fatalf("%s: %s", "Failed to register a consumer", err) | ||
} | ||
|
||
for m := range msgs { | ||
log.Printf("Received message: %s", m.Body) | ||
m.Ack(false) | ||
} | ||
} | ||
``` | ||
|
||
### Useful Links | ||
|
||
Messaging Topology Operator [documentation](https://www.rabbitmq.com/kubernetes/operator/operator-overview.html#topology-operator), [API reference](https://github.com/rabbitmq/messaging-topology-operator/blob/main/docs/api/rabbitmq.com.ref.asciidoc), and [more examples](https://github.com/rabbitmq/messaging-topology-operator/tree/main/docs/examples). |