diff --git a/components/nova/values.yaml b/components/nova/values.yaml index bb11bff25..75006c117 100644 --- a/components/nova/values.yaml +++ b/components/nova/values.yaml @@ -93,6 +93,10 @@ conf: uwsgi: processes: 2 + # Enable oslo.messaging notifications for Argo Events integration + oslo_messaging_notifications: + driver: messagingv2 + console: # we are working with baremetal nodes and not QEMU so we don't need novnc or spice # connected to QEMU diff --git a/components/site-workflows/eventsources/eventsource-openstack-nova.yaml b/components/site-workflows/eventsources/eventsource-openstack-nova.yaml new file mode 100644 index 000000000..4a1956074 --- /dev/null +++ b/components/site-workflows/eventsources/eventsource-openstack-nova.yaml @@ -0,0 +1,44 @@ +apiVersion: argoproj.io/v1alpha1 +kind: EventSource +metadata: + name: openstack-nova +spec: + amqp: + # this is our eventName + notifications: + # amqp server url + url: amqp://rabbitmq-server-0.rabbitmq-nodes.openstack.svc.cluster.local:5672/nova + # jsonBody specifies that all event body payload coming from this + # source will be JSON + jsonBody: true + # name of the exchange. + exchangeName: nova + exchangeType: topic + exchangeDeclare: + durable: true + # routing key for messages within the exchange + routingKey: 'notifications.info' + # queue settings, if not provided defaults are used + queueDeclare: + name: argo_notifications + durable: true + exclusive: false + autoDelete: false + noWait: true + + # optional consume settings + # if not provided, default values will be used + consume: + consumerTag: "argo-events" + autoAck: true + exclusive: false + noLocal: false + # username and password for authentication + # use secret selectors + auth: + username: + name: argo-nova-user-credentials + key: username + password: + name: argo-nova-user-credentials + key: password diff --git a/components/site-workflows/eventsources/rabbitmq-user-argo-nova.yaml b/components/site-workflows/eventsources/rabbitmq-user-argo-nova.yaml new file mode 100644 index 000000000..fb8be5818 --- /dev/null +++ b/components/site-workflows/eventsources/rabbitmq-user-argo-nova.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: rabbitmq.com/v1beta1 +kind: User +metadata: + name: argo-nova +spec: + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Permission +metadata: + name: argo-nova +spec: + vhost: "nova" + userReference: + name: "argo-nova" # name of a user.rabbitmq.com in the same namespace; must specify either spec.userReference or spec.user + permissions: + write: ".*" + configure: ".*" + read: ".*" + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack diff --git a/components/site-workflows/kustomization.yaml b/components/site-workflows/kustomization.yaml index 686a6844c..33256fbcb 100644 --- a/components/site-workflows/kustomization.yaml +++ b/components/site-workflows/kustomization.yaml @@ -5,9 +5,11 @@ resources: - eventbus/eventbus-default.yaml - eventbus/poddisruptionbudget-eventbus-default-pdb.yaml - eventsources/eventsource-openstack-ironic.yaml + - eventsources/eventsource-openstack-nova.yaml - eventsources/eventsource-openstack-keystone.yaml - eventsources/eventsource-openstack-neutron.yaml - eventsources/rabbitmq-user-argo-ironic.yaml + - eventsources/rabbitmq-user-argo-nova.yaml - eventsources/rabbitmq-user-argo-keystone.yaml - eventsources/rabbitmq-user-argo-neutron.yaml - eventsources/eventsource-k8s-openstack-secrets.yaml @@ -26,6 +28,7 @@ resources: - sensors/sensor-ironic-oslo-event.yaml # CronWorkflows - cronworkflows/resync-ironic-nautobot.yaml + - sensors/sensor-nova-oslo-event.yaml helmCharts: - name: nautobot-token diff --git a/components/site-workflows/sensors/sensor-nova-oslo-event.yaml b/components/site-workflows/sensors/sensor-nova-oslo-event.yaml new file mode 100644 index 000000000..0920bce08 --- /dev/null +++ b/components/site-workflows/sensors/sensor-nova-oslo-event.yaml @@ -0,0 +1,102 @@ +--- +apiVersion: argoproj.io/v1alpha1 +kind: Sensor +metadata: + name: nova-oslo-event + annotations: + workflows.argoproj.io/title: Process oslo_events for nova compute + workflows.argoproj.io/description: |+ + Triggers on the following Nova Events: + + - compute.instance.delete.end which happens when a server is deleted + AND the server has metadata.storage == "wanted" + + This sensor uses data filters to check the storage metadata and directly + triggers the ansible playbook without requiring a Python handler. + + The sensor extracts the following parameters from the event: + - device_id: from payload.node (the Baremetal Node ID) + - project_id: from payload.tenant_id (UUID without dashes) + + These are passed directly to the storage_on_server_delete.yml ansible playbook. + + Defined in `components/site-workflows/sensors/sensor-nova-oslo-event.yaml` +spec: + dependencies: + - eventName: notifications + eventSourceName: openstack-nova + name: nova-dep + transform: + # the event is a string-ified JSON so we need to decode it + # replace the whole event body and add a storage_wanted flag + jq: | + .body = (.body["oslo.message"] | fromjson) | + .body.storage_wanted = (.body.payload.metadata.storage // "none") + filters: + # applies each of the items in data with 'and' + dataLogicalOperator: "and" + data: + - path: "body.event_type" + type: "string" + value: + - "compute.instance.delete.end" + # Only process if storage was wanted + - path: "body.storage_wanted" + type: "string" + value: + - "wanted" + template: + serviceAccountName: sensor-submit-workflow + triggers: + - template: + name: nova-instance-delete + k8s: + operation: create + parameters: + - dest: spec.arguments.parameters.0.value + src: + dataKey: body.payload.node + dependencyName: nova-dep + - dest: spec.arguments.parameters.1.value + src: + dataKey: body.payload.tenant_id + dependencyName: nova-dep + source: + # create a workflow in argo-events prefixed with nova-delete- + resource: + apiVersion: argoproj.io/v1alpha1 + kind: Workflow + metadata: + generateName: nova-delete- + namespace: argo-events + spec: + serviceAccountName: workflow + entrypoint: main + # defines the parameters extracted from the event + arguments: + parameters: + - name: device_id + - name: project_id + templates: + - name: main + steps: + - - name: ansible-delete-server-storage + templateRef: + name: ansible-workflow-template + template: ansible-run + arguments: + parameters: + - name: playbook + value: storage_on_server_delete.yml + - name: extra_vars + value: device_id={{workflow.parameters.device_id}} project_id={{workflow.parameters.project_id}} + - - name: ansible-update-switches + templateRef: + name: ansible-workflow-template + template: ansible-run + arguments: + parameters: + - name: playbook + value: storage_update_switches.yml + - name: extra_vars + value: plan_mode=remediation