Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions components/nova/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ conf:
uwsgi:
processes: 2

# Enable oslo.messaging notifications for Argo Events integration
oslo_messaging_notifications:
driver: messagingv2

# Configure which state changes trigger notifications
notifications:
notify_on_state_change: vm_and_task_state

console:
# we are working with baremetal nodes and not QEMU so we don't need novnc or spice
# connected to QEMU
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
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'
# 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
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions components/site-workflows/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -24,6 +26,7 @@ resources:
- sensors/sensor-ironic-node-port.yaml
- sensors/sensor-ironic-node-portgroup.yaml
- sensors/sensor-ironic-oslo-event.yaml
- sensors/sensor-nova-oslo-event.yaml

helmCharts:
- name: nautobot-token
Expand Down
106 changes: 106 additions & 0 deletions components/site-workflows/sensors/sensor-nova-oslo-event.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
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 Ironic/Nova instance UUID)
- 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: check_mode
value: "false"
- - 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 auto_approve=false
- name: check_mode
value: "false"
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class NoEventHandlerError(Exception):
ironic_node.handle_provision_end,
nautobot_device_sync.handle_node_event,
],
# "compute.instance.delete.end" is now handled directly by the sensor with filters
# See: components/site-workflows/sensors/sensor-nova-oslo-event.yaml
"identity.project.created": keystone_project.handle_project_created,
"identity.project.updated": keystone_project.handle_project_updated,
"identity.project.deleted": keystone_project.handle_project_deleted,
Expand Down
52 changes: 50 additions & 2 deletions workflows/argo-events/workflowtemplates/ansible-run.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,64 @@ spec:
default: "var=default"
- name: inventory_file
default: inventory/in-cluster/01-nautobot.yaml
- name: check_mode
default: "false"
steps:
- - name: run-playbook
template: "{{= inputs.parameters.check_mode == 'true' ? 'ansible-run-debug' : 'ansible-run-normal' }}"
arguments:
parameters:
- name: playbook
value: "{{ inputs.parameters.playbook }}"
- name: extra_vars
value: "{{ inputs.parameters.extra_vars }}"
- name: inventory_file
value: "{{ inputs.parameters.inventory_file }}"

- name: ansible-run-normal
inputs:
parameters:
- name: playbook
- name: extra_vars
- name: inventory_file
container:
image: ghcr.io/rss-engineering/undercloud-nautobot/ansible:latest
command: [ansible-playbook]
args:
- "project/{{ inputs.parameters.playbook }}"
- --extra-vars
- "{{ inputs.parameters.extra_vars }}"
- "-i"
- "project/{{ inputs.parameters.inventory_file }}"
- "-vvv"
env:
- name: NAUTOBOT_TOKEN
valueFrom:
secretKeyRef:
key: token
name: nautobot-token
envFrom:
- configMapRef:
name: cluster-metadata
optional: false

- name: ansible-run-debug
inputs:
parameters:
- name: playbook
- name: extra_vars
- name: inventory_file
container:
image: ghcr.io/rss-engineering/undercloud-nautobot/ansible:latest
command: [ansible-playbook]
args:
- "{{ inputs.parameters.playbook }}"
- "project/{{ inputs.parameters.playbook }}"
- --extra-vars
- "{{ inputs.parameters.extra_vars }}"
- "-i"
- "{{ inputs.parameters.inventory_file }}"
- "project/{{ inputs.parameters.inventory_file }}"
- "-vvv"
- --check
env:
- name: NAUTOBOT_TOKEN
valueFrom:
Expand Down
Loading