mirror of
https://github.com/gryf/mistral-evacuate.git
synced 2026-02-07 16:55:52 +01:00
Separate geting flavors and filtering into separe tasks
Also minimalize numbers of calls to nova API Signed-off-by: Dawid Deja <dawid.deja@intel.com>
This commit is contained in:
@@ -18,7 +18,7 @@ Installation
|
||||
mistral.actions =
|
||||
…
|
||||
custom.filter_vm = filter_vm_action:FilterVmAction
|
||||
custom.evacuate = evacuate_vm_action:EvacuateVmAction
|
||||
custom.find_flavors = find_flavors_by_extra_spec:FindFlavorsByExtraSpecs
|
||||
|
||||
to ``setup.cfg`` file under Mistral repository
|
||||
#. Run db-sync tool via either
|
||||
@@ -47,7 +47,10 @@ Installation
|
||||
"search_opts": {
|
||||
"host": "compute-hostanme"
|
||||
},
|
||||
"on_shared_storage": false
|
||||
"on_shared_storage": false,
|
||||
"flavor_extra_specs": {
|
||||
"evacuation:evacuate": true
|
||||
}
|
||||
}
|
||||
|
||||
#. Trigger the action via:
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
from mistral.actions.openstack.actions import NovaAction
|
||||
from mistral.workflow.utils import Result
|
||||
|
||||
|
||||
class EvacuateVmAction(NovaAction):
|
||||
|
||||
def __init__(self, uuid, on_shared_storage, evacuate):
|
||||
self._uuid = uuid
|
||||
self._on_shared_storage = on_shared_storage
|
||||
self._evacuate = evacuate
|
||||
|
||||
def run(self):
|
||||
client = self._get_client()
|
||||
|
||||
if self._evacuate:
|
||||
client.servers.evacuate(self._uuid,
|
||||
on_shared_storage=self._on_shared_storage)
|
||||
@@ -4,52 +4,28 @@ FilterVmAction - custom action.
|
||||
Simple action for filtering VM on the presence of metadata/extra spec
|
||||
"evacuate" flag
|
||||
"""
|
||||
from mistral.actions.openstack.actions import NovaAction
|
||||
from mistral.workflow.utils import Result
|
||||
from mistral.actions import base
|
||||
|
||||
|
||||
class FilterVmException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class FilterVmAction(NovaAction):
|
||||
class FilterVmAction(base.Action):
|
||||
"""
|
||||
Filter and return VMs whith the flag 'evacuate' either on vm metadtata
|
||||
or flavor extra spec.
|
||||
"""
|
||||
|
||||
def __init__(self, metadata, flavor, uuid):
|
||||
def __init__(self, flavors, vms):
|
||||
"""init."""
|
||||
self._metadata = metadata
|
||||
self._flavor = flavor
|
||||
self._uuid = uuid
|
||||
self._flavors = flavors
|
||||
self._vms = vms
|
||||
|
||||
def run(self):
|
||||
"""Entry point for the action execution."""
|
||||
client = self._get_client()
|
||||
metadata = self._metadata
|
||||
result = []
|
||||
|
||||
if str(metadata.get('evacuate')).upper() == 'TRUE':
|
||||
return Result(data={'evacuate': True, 'uuid': self._uuid})
|
||||
elif str(metadata.get('evacuate')).upper() == 'FALSE':
|
||||
return Result(data={'evacuate': False, 'uuid': self._uuid})
|
||||
for vm in self._vms:
|
||||
if str(vm['metadata'].get('evacuate')).upper() == 'TRUE'\
|
||||
or (str(vm['metadata'].get('evacuate')).upper() != 'FALSE'
|
||||
and vm['flavor']['id'] in self._flavors):
|
||||
result.append(vm['id'])
|
||||
|
||||
# Ether is no metadata for vm - check flavor.
|
||||
try:
|
||||
# Maybe this should be done in different action
|
||||
# only once per whole workflow.
|
||||
# In case there is ~100 VMs to evacuate, there will be
|
||||
# the same amount of calls to nova API.
|
||||
flavor = filter(
|
||||
lambda f: f.id == self._flavor,
|
||||
client.flavors.list()
|
||||
)[0]
|
||||
except IndexError:
|
||||
raise FilterVmException('Flavor not found')
|
||||
|
||||
evacuate = flavor.get_keys().get('evacuation:evacuate')
|
||||
|
||||
if str(evacuate).upper() == 'TRUE':
|
||||
return Result(data={'evacuate': True, 'uuid': self._uuid})
|
||||
|
||||
return Result(data={'evacuate': False, 'uuid': self._uuid})
|
||||
return result
|
||||
32
find_flavors_by_extra_spec.py
Normal file
32
find_flavors_by_extra_spec.py
Normal file
@@ -0,0 +1,32 @@
|
||||
"""
|
||||
FindFlavorsByExtraSpecs - custom action.
|
||||
|
||||
It works pretty similar to nova.flavors_findall, but it looks for items in
|
||||
flavors extra spec
|
||||
"""
|
||||
|
||||
from mistral.actions.openstack.actions import NovaAction
|
||||
|
||||
|
||||
class FindFlavorsByExtraSpecs(NovaAction):
|
||||
|
||||
def __init__(self, extra_specs):
|
||||
if type(extra_specs) is dict:
|
||||
self._extra_specs = extra_specs
|
||||
else:
|
||||
raise TypeError("Extra spec must be a dictionary")
|
||||
|
||||
def run(self):
|
||||
client = self._get_client()
|
||||
flavors = client.flavors.list()
|
||||
result = []
|
||||
|
||||
for flavor in flavors:
|
||||
flavor_extra_specs = flavor.get_keys().items()
|
||||
if all(
|
||||
item in flavor_extra_specs
|
||||
for item in self._extra_specs.items()
|
||||
):
|
||||
result.append(flavor.id)
|
||||
|
||||
return result
|
||||
@@ -2,27 +2,33 @@
|
||||
version: '2.0'
|
||||
|
||||
host-evacuate:
|
||||
description: Evacuate VMs from given host
|
||||
type: direct
|
||||
description: Evacuate VMs from given host
|
||||
type: direct
|
||||
input:
|
||||
- search_opts
|
||||
- on_shared_storage
|
||||
- flavor_extra_specs
|
||||
|
||||
input:
|
||||
- search_opts
|
||||
- on_shared_storage
|
||||
tasks:
|
||||
list_vms:
|
||||
action: nova.servers_list search_opts=<% $.search_opts %>
|
||||
publish:
|
||||
vms: <% $.list_vms %>
|
||||
on-success: filter_vms
|
||||
|
||||
tasks:
|
||||
list_vms:
|
||||
action: nova.servers_list search_opts=<% $.search_opts %>
|
||||
publish:
|
||||
vms: <% $.list_vms %>
|
||||
on-success: filter_vms
|
||||
list_flavors:
|
||||
action: custom.find_flavors extra_specs=<% $.flavor_extra_specs %>
|
||||
publish:
|
||||
flavors: <% $.list_flavors %>
|
||||
on-success: filter_vms
|
||||
|
||||
filter_vms:
|
||||
with-items: vm in <% $.vms %>
|
||||
action: custom.filter flavor=<% $.vm.flavor.id %> metadata=<% $.vm.metadata %> uuid=<% $.vm.id %>
|
||||
publish:
|
||||
filtered_vms: <% $.filter_vms %>
|
||||
on-success: evacuate_vms
|
||||
filter_vms:
|
||||
join: all
|
||||
action: custom.filter flavors=<% $.flavors %> vms=<% $.vms %>
|
||||
publish:
|
||||
filtered_vms: <% $.filter_vms %>
|
||||
on-success: evacuate_vms
|
||||
|
||||
evacuate_vms:
|
||||
with-items: vm in <% $.filtered_vms %>
|
||||
action: custom.evacuate uuid=<% $.vm.uuid %> evacuate=<% $.vm.evacuate %> on_shared_storage=<% $.on_shared_storage %>
|
||||
evacuate_vms:
|
||||
with-items: vm in <% $.filtered_vms %>
|
||||
action: nova.servers_evacuate server=<% $.vm %> on_shared_storage=<% $.on_shared_storage %>
|
||||
|
||||
@@ -2,5 +2,8 @@
|
||||
"search_opts": {
|
||||
"host": "compute1"
|
||||
},
|
||||
"on_shared_storage": false
|
||||
"on_shared_storage": false,
|
||||
"flavor_extra_specs": {
|
||||
"evacuation:evacuate": true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user