-
Notifications
You must be signed in to change notification settings - Fork 897
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
171 additions
and
145 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
145 changes: 145 additions & 0 deletions
145
app/models/transformation_mapping/vm_migration_validator.rb
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,145 @@ | ||
class TransformationMapping::VmMigrationValidator | ||
require 'miq-hash_struct' | ||
|
||
VM_CONFLICT = "conflict".freeze | ||
VM_EMPTY_NAME = "empty_name".freeze | ||
VM_IN_OTHER_PLAN = "in_other_plan".freeze | ||
VM_INVALID = "invalid".freeze | ||
VM_MIGRATED = "migrated".freeze | ||
VM_NOT_EXIST = "not_exist".freeze | ||
VM_VALID = "ok".freeze | ||
|
||
def initialize(mapping, vm_list = nil) | ||
@mapping = mapping | ||
@vm_list = vm_list | ||
end | ||
|
||
def validate | ||
@vm_list.present? ? identify_vms : select_vms | ||
end | ||
|
||
def select_vms | ||
valid_list = [] | ||
|
||
@mapping.transformation_mapping_items.includes(:source => :vms).where(:source_type => EmsCluster).collect(&:source).flat_map(&:vms).each do |vm| | ||
reason = validate_vm(vm, true) | ||
valid_list << VmMigrateStruct.new(vm.name, vm, VM_VALID, reason) if reason == VM_VALID | ||
end | ||
|
||
{"valid" => valid_list} | ||
end | ||
|
||
def identify_vms | ||
valid_list = [] | ||
invalid_list = [] | ||
conflict_list = [] | ||
|
||
@vm_list.each do |row| | ||
vm_name = row['name'] | ||
|
||
if vm_name.blank? | ||
invalid_list << VmMigrateStruct.new('', nil, VM_INVALID, VM_EMPTY_NAME) | ||
next | ||
end | ||
|
||
query = Vm.where(:name => vm_name, :ems_cluster => valid_clusters) | ||
query = query.where(:uid_ems => row['uid_ems']) if row['uid_ems'].present? | ||
query = query.joins(:host).where(:hosts => {:name => row['host']}) if row['host'].present? | ||
query = query.joins(:ext_management_system).where(:ext_management_systems => {:name => row['provider']}) if row['provider'].present? | ||
|
||
vms = query.to_a | ||
if vms.size.zero? | ||
invalid_list << VmMigrateStruct.new(vm_name, nil, VM_INVALID, VM_NOT_EXIST) | ||
elsif vms.size == 1 | ||
vm = vms.first | ||
reason = validate_vm(vm, false) | ||
if reason == VM_VALID | ||
valid_list << VmMigrateStruct.new(vm.name, vm, VM_VALID, reason) | ||
else | ||
invalid_list << VmMigrateStruct.new(vm.name, vm, VM_INVALID, reason) | ||
end | ||
else | ||
vms.each { |v| conflict_list << VmMigrateStruct.new(v.name, v, VM_CONFLICT, VM_CONFLICT) } | ||
end | ||
end | ||
|
||
{ | ||
"valid" => valid_list, | ||
"invalid" => invalid_list, | ||
"conflicted" => conflict_list | ||
} | ||
end | ||
|
||
def validate_vm(vm, quick = true) | ||
# a valid vm must find all resources in the mapping and has never been migrated | ||
invalid_list = [] | ||
|
||
invalid_storages = unmapped_storages(vm) | ||
if invalid_storages.present? | ||
invalid_list << "storages: %{list}" % {:list => invalid_storages.collect(&:name).join(", ")} | ||
return no_mapping_msg(invalid_list) if quick | ||
end | ||
|
||
invalid_lans = unmapped_lans(vm) | ||
if invalid_lans.present? | ||
invalid_list << "lans: %{list}" % {:list => invalid_lans.collect(&:name).join(', ')} | ||
return no_mapping_msg(invalid_list) if quick | ||
end | ||
|
||
return no_mapping_msg(invalid_list) if invalid_list.present? | ||
vm_migration_status(vm) | ||
end | ||
|
||
def vm_migration_status(vm) | ||
vm_as_resources = ServiceResource.joins(:service_template).where(:resource => vm, :service_templates => {:type => "ServiceTemplateTransformationPlan"}) | ||
|
||
# VM has not been migrated before | ||
return VM_VALID if vm_as_resources.empty? | ||
|
||
return VM_MIGRATED unless vm_as_resources.where(:status => ServiceResource::STATUS_COMPLETED).empty? | ||
|
||
# VM failed in previous migration | ||
vm_as_resources.all? { |rsc| rsc.status == ServiceResource::STATUS_FAILED } ? VM_VALID : VM_IN_OTHER_PLAN | ||
end | ||
|
||
def no_mapping_msg(list) | ||
"Mapping source not found - %{list}" % {:list => list.join('. ')} | ||
end | ||
|
||
def valid_cluster?(vm) | ||
@mapping.transformation_mapping_items.where(:source => vm.ems_cluster).exists? | ||
end | ||
|
||
def valid_clusters | ||
@mapping.transformation_mapping_items.where(:source_type => EmsCluster).collect(&:source) | ||
end | ||
|
||
# return an empty array if all storages are valid for transformation | ||
# otherwise return an array of invalid datastores | ||
def unmapped_storages(vm) | ||
vm.datastores - @mapping.transformation_mapping_items.where(:source => vm.datastores).collect(&:source) | ||
end | ||
|
||
# return an empty array if all lans are valid for transformation | ||
# otherwise return an array of invalid lans | ||
def unmapped_lans(vm) | ||
vm.lans - @mapping.transformation_mapping_items.where(:source => vm.lans).collect(&:source) | ||
end | ||
|
||
class VmMigrateStruct < MiqHashStruct | ||
def initialize(vm_name, vm, status, reason) | ||
options = {"name" => vm_name, "status" => status, "reason" => reason} | ||
|
||
if vm.present? | ||
options.merge!( | ||
"cluster" => vm.ems_cluster.try(:name), | ||
"path" => "#{vm.ext_management_system.name}/#{vm.parent_blue_folder_path(:exclude_non_display_folders => true)}", | ||
"allocated_size" => vm.allocated_disk_storage, | ||
"id" => vm.id | ||
) | ||
end | ||
|
||
super(options) | ||
end | ||
end | ||
end |
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