In VMware Cloud Director 10.1 (VCD) the organization users can subscribe to event and task push notifications which might be useful if the tenant needs to keep track of the activity in the cloud, connect CMDB or any other custom solution and does not want to permanently poll audit log via API.
Access to notifications was in the past only in the realm of service providers who needed to deploy RabbitMQ and connect their Cloud Director cells to it. They can still do so and in fact have to, if they need blocking taks or use VCD API extension (for example Container Service Extension, App Launch Pad or vRealize Operations Tenant App).
The new functionality is enabled by internal Artemis ActiveMQ bus that runs on every VCD cell. The MQTT client connects to the public https endpoint and uses WebSocket connnection to the bus. Authentication is provided via the JWT authentication token. The official documentation provides some detail here, but not enough to actually set this up.
Therefore I want to demonstrate here with very simple Python script how to set up connection and start utilizing this feature.
The Python 3 script leverages the Pyvcloud module (22.0 or newer is required) and Paho MQTT Python Client. Both can be installed simply with pip.
pip install pyvcloud paho-mqtt
In the example org admin credentials are used, which allows to subscription to all organization messages via publish/<org UUID>/* subscription string. It can also be used by system administrator while changing the subscription string to publish/*/*.
#!/usr/bin/python3 import paho.mqtt.client as mqtt import json import datetime import pyvcloud.vcd.client import pyvcloud.vcd.vdc vcdHost = 'vcloud.fojta.com' vcdPort = 443 path = "/messaging/mqtt" logFile = 'vcd_log.log' #org admin credentials user = 'acmeadmin' password = 'VMware1!' org = 'acme' credentials = pyvcloud.vcd.client.BasicLoginCredentials(user, org, password) vcdClient = pyvcloud.vcd.client.Client(vcdHost+":"+str(vcdPort),None,True,logFile) vcdClient.set_credentials(credentials) accessToken = vcdClient.get_access_token() headers = {"Authorization": "Bearer "+ accessToken} if max(vcdClient.get_supported_versions_list()) < "34.0": exit('VMware Cloud Director 10.1 or newer is required') org = vcdClient.get_org_list() orgId = (org[0].attrib).get('id').split('org:',1)[1] def on_message(client, userdata, message): event = message.payload.decode('utf-8') event = event.replace('\\','') eventPayload = event.split('payload":"',1)[1] eventPayload = eventPayload[:-2] event_json = json.loads(eventPayload) print(datetime.datetime.now()) print (event_json) # Enable for logging # def on_log(client, userdata, level, buf): # print("log: ",buf) client = mqtt.Client(client_id = "PythonMQTT",transport = "websockets") client.ws_set_options(path = path, headers = headers) client.tls_set_context(context=None) # client.tls_insecure_set(True) client.on_message=on_message # client.on_log=on_log #enable for logging client.connect(host = vcdHost, port = vcdPort , keepalive = 60) print('Connected') client.subscribe("publish/"+orgId+"/*") client.loop_forever()
Notice that the client needs to connect to the /messaging/mqtt path on the VCD endpoint and must provide valid JWT authentication token in the header. That rules some MQTT WebSocket clients that do not support custom headers (JavaScript).
The actual event is in JSON format with nested payload JSON providing the details. The code example prints the time when the event was received and just the nested payload JSON. The script runs forever until interrupted with Ctrl+C.
Note: The actual RabbitMQ extensibility configuration in VCD and the Non-blocking AMQP Notifications setting in the UI has no impact on this functionality and can be disabled if not used by the service provider.
RabbitMQ is still required for any use cases as most of the extensibility start supporting MQTT
Is RabbitMQ the only supported AMQP for Cloud Director? Our internal infrastructure group has asked if we could use Azure Service Bus instead, and I haven’t found the answer.