From 6e6eb580a3d79f1077961282a3c95f55ff470a53 Mon Sep 17 00:00:00 2001 From: Andrew Becker Date: Thu, 3 Oct 2019 12:13:49 -0400 Subject: [PATCH] Supporting CFME 5.10 Retirement tasks (#160) + Converting more things to class style + Misc bug fixes/error handling/enhancements --- .../__methods__/add_host_to_inventory.rb | 8 +- .../__methods__/acquire_ip_address.rb | 315 ++++++----------- .../__methods__/acquire_ip_address.yaml | 2 + .../__methods__/release_ip_address.rb | 322 ++++++------------ .../__methods__/release_ip_address.yaml | 2 + .../__methods__/miqprovision_update.rb | 55 +-- .../__methods__/ansibletowerbase.rb | 11 +- .../StdLib/Core.class/__methods__/core.rb | 21 +- 8 files changed, 262 insertions(+), 474 deletions(-) diff --git a/Automate/RedHatConsulting_Utilities/AutomationManagement/AnsibleTower/Operations/Methods.class/__methods__/add_host_to_inventory.rb b/Automate/RedHatConsulting_Utilities/AutomationManagement/AnsibleTower/Operations/Methods.class/__methods__/add_host_to_inventory.rb index 1eed075..d2cd8d6 100644 --- a/Automate/RedHatConsulting_Utilities/AutomationManagement/AnsibleTower/Operations/Methods.class/__methods__/add_host_to_inventory.rb +++ b/Automate/RedHatConsulting_Utilities/AutomationManagement/AnsibleTower/Operations/Methods.class/__methods__/add_host_to_inventory.rb @@ -46,7 +46,7 @@ def main begin host_id = tower_host_id(vm) rescue => e - log(:error, "Unable to determine if host is in Ansible Tower Inventory [ #{@tower_inventory_name} ]") + log(:error, "Unable to determine if host is in Ansible Tower Inventory [ #{@tower_inventory_name} ]. #{e.to_s}") automate_retry(10, "Error making Ansible Tower API Call. #{e.to_s}") end @@ -72,7 +72,7 @@ def main begin tower_request(host_management_action, api_path, payload) rescue => e - log(:error, "Unable to add host [ #{vm_inventory_hostname} ] to Ansible Tower inventory [ #{@tower_inventory_name} ]") + log(:error, "Unable to add host [ #{vm_inventory_hostname} ] to Ansible Tower inventory [ #{@tower_inventory_name} ]. #{e.to_s}") automate_retry(10, "Error making Ansible Tower API Call: #{e.to_s}") end @@ -80,14 +80,14 @@ def main begin host_present_in_inventory = vm_in_inventory?(vm) rescue => e - log(:error, "Unable to determine if host [ #{vm_inventory_hostname} ] is in Ansible Tower Inventory [ #{@tower_inventory_name} ]") + log(:error, "Unable to determine if host [ #{vm_inventory_hostname} ] is in Ansible Tower Inventory [ #{@tower_inventory_name} ]. #{e.to_s}") automate_retry(10, "Error making Ansible Tower API Call: #{e.to_s}") end if !host_present_in_inventory error("Failed to add #{vm_inventory_hostname} to Ansible Inventory [ #{@tower_inventory_name} ].") end - @handle.log(:info, "VM #{vm_inventory_hostname} with IP address #{vm_ip_address} successfully added to Ansible Tower inventory [ #{@tower_inventory_name} ]") + @handle.log(:info, "VM #{vm_inventory_hostname} with IP address #{vm_ip_address} successfully added to Ansible Tower inventory [ #{@tower_inventory_name} ].") exit MIQ_OK end diff --git a/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/acquire_ip_address.rb b/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/acquire_ip_address.rb index b57dd6d..c6fdcc2 100644 --- a/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/acquire_ip_address.rb +++ b/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/acquire_ip_address.rb @@ -3,234 +3,117 @@ # @param network_name_parameter_name String Name of the parameter that contains the network name to get an IP address for. # # @set aquired_ip_address String IP address aquired fomr the DDI provider for the given network. -# -@DEBUG = false -DDI_PROVIDERS_URI = 'Infrastructure/Network/DDIProviders'.freeze +#/ Infrastructure / Network / Operations / Methods / acquire_ip_address +module RedHatConsulting_Utilities + module Infrastructure + module Network + module Operations + module Methods + class AcquireIpAddress -def dump_object(object_string, object) - $evm.log("info", "Listing #{object_string} Attributes:") - object.attributes.sort.each { |k, v| $evm.log("info", "\t#{k}: #{v}") } - $evm.log("info", "===========================================") -end + include RedHatConsulting_Utilities::StdLib::Core + DDI_PROVIDERS_URI = 'Infrastructure/Network/DDIProviders'.freeze -def dump_current - $evm.log("info", "Listing Current Object Attributes:") - $evm.current.attributes.sort.each { |k, v| $evm.log("info", "\t#{k}: #{v}") } - $evm.log("info", "===========================================") -end + def initialize(handle = $evm) + @handle = handle + @network_configurations = {} + @missing_network_configurations = {} + @DEBUG = true + end -def dump_root - $evm.log("info", "Listing Root Object Attributes:") - $evm.root.attributes.sort.each { |k, v| $evm.log("info", "\t#{k}: #{v}") } - $evm.log("info", "===========================================") -end + def main + begin + vm,options = get_vm_and_options() -# Notify and log a message. -# -# @param level Symbol Level of the notification and log message -# @param message String Message to notify and log -# @param subject ActiveRecord::Base Subject of the notification -def notify(level, message, subject) - $evm.create_notification(:level => level, :message => message, :subject => subject) - log_level = case level - when :warning - :warn - else - level - end - $evm.log(log_level, message) -end + network_name_parameter_name = get_param(:network_name_parameter_name) + log(:info, "network_name_parameter_name => #{network_name_parameter_name}") + network_name = get_param(network_name_parameter_name) || get_param("dialog_#{network_name_parameter_name}") || options[network_name_parameter_name.to_sym] || options["dialog_#{network_name_parameter_name}".to_sym] -# Log an error and exit. -# -# @param msg Message to error with -def error(msg) - $evm.log(:error, msg) - $evm.root['ae_result'] = 'error' - $evm.root['ae_reason'] = msg.to_s - exit MIQ_STOP -end + if !network_name.blank? + network_configuration = get_network_configuration(network_name) + log(:info, "network_name_parameter_name => #{network_name_parameter_name}") if @DEBUG + log(:info, "network_name => #{network_name}") if @DEBUG + log(:info, "network_configuration => #{network_configuration}") if @DEBUG -# There are many ways to attempt to pass parameters in Automate. -# This function checks all of them in priorty order as well as checking for symbol or string. -# -# Order: -# 1. Inputs -# 2. Current -# 3. Object -# 4. Root -# 5. State -# -# @return Value for the given parameter or nil if none is found -def get_param(param) - # check if inputs has been set for given param - param_value ||= $evm.inputs[param.to_sym] - param_value ||= $evm.inputs[param.to_s] - - # else check if current has been set for given param - param_value ||= $evm.current[param.to_sym] - param_value ||= $evm.current[param.to_s] - - # else cehck if current has been set for given param - param_value ||= $evm.object[param.to_sym] - param_value ||= $evm.object[param.to_s] - - # else check if param on root has been set for given param - param_value ||= $evm.root[param.to_sym] - param_value ||= $evm.root[param.to_s] - - # check if state has been set for given param - param_value ||= $evm.get_state_var(param.to_sym) - param_value ||= $evm.get_state_var(param.to_s) - - $evm.log(:info, "{ '#{param}' => '#{param_value}' }") if @DEBUG - return param_value -end + # determine the DDI provider + ddi_provider = network_configuration['network_ddi_provider'] + log(:info, "ddi_provider => #{ddi_provider}") if @DEBUG -# Function for getting the current VM and associated options based on the vmdb_object_type. -# -# Supported vmdb_object_types -# * miq_provision -# * vm -# * automation_task -# -# @return vm,options -def get_vm_and_options() - $evm.log(:info, "$evm.root['vmdb_object_type'] => '#{$evm.root['vmdb_object_type']}'.") - case $evm.root['vmdb_object_type'] - when 'miq_provision' - # get root object - $evm.log(:info, "Get VM and dialog attributes from $evm.root['miq_provision']") if @DEBUG - miq_provision = $evm.root['miq_provision'] - dump_object('miq_provision', miq_provision) if @DEBUG - - # get VM - vm = miq_provision.vm - - # get options - options = miq_provision.options - #merge the ws_values, dialog, top level options into one list to make it easier to search - options = options.merge(options[:ws_values]) if options[:ws_values] - options = options.merge(options[:dialog]) if options[:dialog] - when 'vm' - # get root objet & VM - $evm.log(:info, "Get VM from paramater and dialog attributes form $evm.root") if @DEBUG - vm = get_param(:vm) - dump_object('vm', vm) if @DEBUG - - # get options - options = $evm.root.attributes - #merge the ws_values, dialog, top level options into one list to make it easier to search - options = options.merge(options[:ws_values]) if options[:ws_values] - options = options.merge(options[:dialog]) if options[:dialog] - when 'automation_task' - # get root objet - $evm.log(:info, "Get VM from paramater and dialog attributes form $evm.root") if @DEBUG - automation_task = $evm.root['automation_task'] - dump_object('automation_task', automation_task) if @DEBUG - - # get VM - vm = get_param(:vm) - - # get options - options = get_param(:options) - options = JSON.load(options) if options && options.class == String - options = options.symbolize_keys if options - #merge the ws_values, dialog, top level options into one list to make it easier to search - options = options.merge(options[:ws_values]) if options[:ws_values] - options = options.merge(options[:dialog]) if options[:dialog] - else - error("Can not handle vmdb_object_type: #{$evm.root['vmdb_object_type']}") - end - - # standerdize the option keys - options = options.symbolize_keys() - - $evm.log(:info, "vm => #{vm}") if @DEBUG - $evm.log(:info, "options => #{options}") if @DEBUG - return vm,options -end + # instantiate instance to acquire IP + begin + log(:info, "Acquire IP address using DDI Provider <#{ddi_provider}>") if @DEBUG -# Get the network configuration for a given network -# -# @param network_name Name of the network to get the configuraiton for -# @return Hash Configuration information about the given network -# network_purpose -# network_address_space -# network_gateway -# network_nameservers -# network_ddi_provider -@network_configurations = {} -@missing_network_configurations = {} -NETWORK_CONFIGURATION_URI = 'Infrastructure/Network/Configuration'.freeze -def get_network_configuration(network_name) - if @network_configurations[network_name].blank? && @missing_network_configurations[network_name].blank? - begin - escaped_network_name = network_name.gsub(/[^a-zA-Z0-9_\.\-]/, '_') - @network_configurations[network_name] = $evm.instantiate("#{NETWORK_CONFIGURATION_URI}/#{escaped_network_name}") - - if escaped_network_name =~ /^dvs_/ && @network_configurations[network_name]['network_address_space'].blank? - escaped_network_name = escaped_network_name[/^dvs_(.*)/, 1] - @network_configurations[network_name] = $evm.instantiate("#{NETWORK_CONFIGURATION_URI}/#{escaped_network_name}") + @handle.root['network_name'] = network_name + @handle.instantiate("#{DDI_PROVIDERS_URI}/#{ddi_provider}#acquire_ip_address") + acquired_ip_address = get_param(:acquired_ip_address) + log(:info, "Acquired IP address <#{acquired_ip_address}> using DDI Provider <#{ddi_provider}>") + + ensure + + success = @handle.root['ae_result'] == nil || @handle.root['ae_result'] == 'ok' + reason = @handle.root['ae_reason'] if !success + + # clean up root + @handle.root['ae_result'] = 'ok' + @handle.root['ae_reason'] = "Acquired IP address <#{acquired_ip_address}> for VM <#{vm.name}>" + + # clean up after call + @handle.root['network_name'] = nil + @handle.root['acquired_ip_address'] = nil + end + error("Error acquiring IP address using DDI Provider <#{ddi_provider}>: #{reason}") if !success + else + log(:warn, "No value for the expected network name parameter <#{network_name_parameter_name}> was given. Skipping aquiring IP address.") + end + + # set the acquired IP + @handle.object['acquired_ip_address'] = acquired_ip_address + @handle.set_state_var(:acquired_ip_address, acquired_ip_address) + + # set destination IP address to acquired IP address + @handle.object['destination_ip_address'] = acquired_ip_address + @handle.set_state_var(:destination_ip_address, acquired_ip_address) + + @handle.log(:info, "$evm.object['acquired_ip_address'] => #{@handle.object['acquired_ip_address']}") if @DEBUG + end + end + + # Get the network configuration for a given network + # + # @param network_name Name of the network to get the configuraiton for + # @return Hash Configuration information about the given network + # network_purpose + # network_address_space + # network_gateway + # network_nameservers + # network_ddi_provider + NETWORK_CONFIGURATION_URI = 'Infrastructure/Network/Configuration'.freeze + def get_network_configuration(network_name) + if @network_configurations[network_name].blank? && @missing_network_configurations[network_name].blank? + begin + escaped_network_name = network_name.gsub(/[^a-zA-Z0-9_\.\-]/, '_') + @network_configurations[network_name] = @handle.instantiate("#{NETWORK_CONFIGURATION_URI}/#{escaped_network_name}") + + if escaped_network_name =~ /^dvs_/ && @network_configurations[network_name]['network_address_space'].blank? + escaped_network_name = escaped_network_name[/^dvs_(.*)/, 1] + @network_configurations[network_name] = @handle.instantiate("#{NETWORK_CONFIGURATION_URI}/#{escaped_network_name}") + end + rescue + @missing_network_configurations[network_name] = "WARN: No network configuration exists" + log(:warn, "No network configuration for Network <#{network_name}> (escaped <#{escaped_network_name}>) exists") + end + end + return @network_configurations[network_name] + end + + end + end end - rescue - @missing_network_configurations[network_name] = "WARN: No network configuration exists" - $evm.log(:warn, "No network configuration for Network <#{network_name}> (escaped <#{escaped_network_name}>) exists") end end - return @network_configurations[network_name] end -begin - vm,options = get_vm_and_options() - - network_name_parameter_name = get_param(:network_name_parameter_name) - network_name = get_param(network_name_parameter_name) || get_param("dialog_#{network_name_parameter_name}") || options[network_name_parameter_name.to_sym] || options["dialog_#{network_name_parameter_name}".to_sym] - - if !network_name.blank? - network_configuration = get_network_configuration(network_name) - $evm.log(:info, "network_name_parameter_name => #{network_name_parameter_name}") if @DEBUG - $evm.log(:info, "network_name => #{network_name}") if @DEBUG - $evm.log(:info, "network_configuration => #{network_configuration}") if @DEBUG - - # determine the DDI provider - ddi_provider = network_configuration['network_ddi_provider'] - $evm.log(:info, "ddi_provider => #{ddi_provider}") if @DEBUG - - # instantiate instance to acquire IP - begin - $evm.log(:info, "Acquire IP address using DDI Provider <#{ddi_provider}>") if @DEBUG - - $evm.root['network_name'] = network_name - $evm.instantiate("#{DDI_PROVIDERS_URI}/#{ddi_provider}#acquire_ip_address") - acquired_ip_address = get_param(:acquired_ip_address) - - $evm.log(:info, "Acquired IP address <#{acquired_ip_address}> using DDI Provider <#{ddi_provider}>") if @DEBUG - ensure - success = $evm.root['ae_result'] == nil || $evm.root['ae_result'] == 'ok' - reason = $evm.root['ae_reason'] if !success - - # clean up root - $evm.root['ae_result'] = 'ok' - $evm.root['ae_reason'] = "Acquired IP address <#{acquired_ip_address}> for VM <#{vm.name}>" - - # clean up after call - $evm.root['network_name'] = nil - $evm.root['acquired_ip_address'] = nil - end - error("Error acquiring IP address using DDI Provider <#{ddi_provider}>: #{reason}") if !success - else - $evm.log(:warn, "No value for the expected network name parameter <#{network_name_parameter_name}> was given. Skipping aquiring IP address.") - end - - # set the acquired IP - $evm.object['acquired_ip_address'] = acquired_ip_address - $evm.set_state_var(:acquired_ip_address, acquired_ip_address) - - # set destination IP address to acquired IP address - $evm.object['destination_ip_address'] = acquired_ip_address - $evm.set_state_var(:destination_ip_address, acquired_ip_address) - - $evm.log(:info, "$evm.object['acquired_ip_address'] => #{$evm.object['acquired_ip_address']}") if @DEBUG +if __FILE__ == $PROGRAM_NAME + RedHatConsulting_Utilities::Infrastructure::Network::Operations::Methods::AcquireIpAddress.new.main end diff --git a/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/acquire_ip_address.yaml b/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/acquire_ip_address.yaml index b480816..ecdf716 100644 --- a/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/acquire_ip_address.yaml +++ b/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/acquire_ip_address.yaml @@ -9,5 +9,7 @@ object: scope: instance language: ruby location: inline + embedded_methods: + - "/StdLib/Core/Core" options: {} inputs: [] diff --git a/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/release_ip_address.rb b/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/release_ip_address.rb index 6b2ea00..7817b99 100644 --- a/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/release_ip_address.rb +++ b/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/release_ip_address.rb @@ -2,239 +2,115 @@ # # @set retired_ip_address String IP address retired from the DDI provider for the network of the provided VM. # -@DEBUG = false -DDI_PROVIDERS_URI = 'Infrastructure/Network/DDIProviders'.freeze +module RedHatConsulting_Utilities + module Infrastructure + module Network + module Operations + module Methods + class ReleaseIPAddress -def dump_object(object_string, object) - $evm.log("info", "Listing #{object_string} Attributes:") - object.attributes.sort.each { |k, v| $evm.log("info", "\t#{k}: #{v}") } - $evm.log("info", "===========================================") -end + include RedHatConsulting_Utilities::StdLib::Core + DDI_PROVIDERS_URI = 'Infrastructure/Network/DDIProviders'.freeze -def dump_current - $evm.log("info", "Listing Current Object Attributes:") - $evm.current.attributes.sort.each { |k, v| $evm.log("info", "\t#{k}: #{v}") } - $evm.log("info", "===========================================") -end + def initialize(handle = $evm) + @handle = handle + @DEBUG = false + end -def dump_root - $evm.log("info", "Listing Root Object Attributes:") - $evm.root.attributes.sort.each { |k, v| $evm.log("info", "\t#{k}: #{v}") } - $evm.log("info", "===========================================") -end + def main + begin + dump_root if @DEBUG -# Log an error and exit. -# -# @param msg Message to error with -def error(msg) - $evm.log(:error, msg) - $evm.root['ae_result'] = 'error' - $evm.root['ae_reason'] = msg.to_s - exit MIQ_STOP -end + vm,options = get_vm_and_options() -# Notify and log a message. -# -# @param level Symbol Level of the notification and log message -# @param message String Message to notify and log -# @param subject ActiveRecord::Base Subject of the notification -def notify(level, message, subject) - $evm.create_notification(:level => level, :message => message, :subject => subject) - log_level = case level - when :warning - :warn - else - level - end - $evm.log(log_level, message) -end + # NOTE: this is hard coded to the first network interface because can't + # decide how to determine which network interfaces to release the IPs for... + # + # TODO: don't hard code this to first interface + network = vm.hardware.nics[0].lan + log(:info, "Releaseing IP Address on network <#{network}> for VM <#{vm.name}>") if @DEBUG -# There are many ways to attempt to pass parameters in Automate. -# This function checks all of them in priorty order as well as checking for symbol or string. -# -# Order: -# 1. Inputs -# 2. Current -# 3. Object -# 4. Root -# 5. State -# -# @return Value for the given parameter or nil if none is found -def get_param(param) - # check if inputs has been set for given param - param_value ||= $evm.inputs[param.to_sym] - param_value ||= $evm.inputs[param.to_s] - - # else check if current has been set for given param - param_value ||= $evm.current[param.to_sym] - param_value ||= $evm.current[param.to_s] - - # else cehck if current has been set for given param - param_value ||= $evm.object[param.to_sym] - param_value ||= $evm.object[param.to_s] - - # else check if param on root has been set for given param - param_value ||= $evm.root[param.to_sym] - param_value ||= $evm.root[param.to_s] - - # check if state has been set for given param - param_value ||= $evm.get_state_var(param.to_sym) - param_value ||= $evm.get_state_var(param.to_s) - - $evm.log(:info, "{ '#{param}' => '#{param_value}' }") if @DEBUG - return param_value -end + # TODO: figure out some workaround to this issue or do something else here. + # deal with https://bugzilla.redhat.com/show_bug.cgi?id=1572917 + if network.nil? + log( + :warn, + "Could not determine Network for VM <#{vm.name} to release IP address due to " + + "https://bugzilla.redhat.com/show_bug.cgi?id=1572917. IP address will need to be manually released. " + + "Ignoring & Skipping." + ) + exit MIQ_OK + end -# Function for getting the current VM and associated options based on the vmdb_object_type. -# -# Supported vmdb_object_types -# * miq_provision -# * vm -# * automation_task -# -# @return vm,options -def get_vm_and_options() - $evm.log(:info, "$evm.root['vmdb_object_type'] => '#{$evm.root['vmdb_object_type']}'.") - case $evm.root['vmdb_object_type'] - when 'miq_provision' - # get root object - $evm.log(:info, "Get VM and dialog attributes from $evm.root['miq_provision']") if @DEBUG - miq_provision = $evm.root['miq_provision'] - dump_object('miq_provision', miq_provision) if @DEBUG - - # get VM - vm = miq_provision.vm - - # get options - options = miq_provision.options - #merge the ws_values, dialog, top level options into one list to make it easier to search - options = options.merge(options[:ws_values]) if options[:ws_values] - options = options.merge(options[:dialog]) if options[:dialog] - when 'vm' - # get root objet & VM - $evm.log(:info, "Get VM from paramater and dialog attributes form $evm.root") if @DEBUG - vm = get_param(:vm) - dump_object('vm', vm) if @DEBUG - - # get options - options = $evm.root.attributes - #merge the ws_values, dialog, top level options into one list to make it easier to search - options = options.merge(options[:ws_values]) if options[:ws_values] - options = options.merge(options[:dialog]) if options[:dialog] - when 'automation_task' - # get root objet - $evm.log(:info, "Get VM from paramater and dialog attributes form $evm.root") if @DEBUG - automation_task = $evm.root['automation_task'] - dump_object('automation_task', automation_task) if @DEBUG - - # get VM - vm = get_param(:vm) - - # get options - options = get_param(:options) - options = JSON.load(options) if options && options.class == String - options = options.symbolize_keys if options - #merge the ws_values, dialog, top level options into one list to make it easier to search - options = options.merge(options[:ws_values]) if options[:ws_values] - options = options.merge(options[:dialog]) if options[:dialog] - else - error("Can not handle vmdb_object_type: #{$evm.root['vmdb_object_type']}") - end - - # standerdize the option keys - options = options.symbolize_keys() - - return vm,options -end + # find matching network configuration + vm_network_name = network.name + network_configurations = get_network_configurations() + network_configuration = nil + network_configuration_name = nil + log(:info, "network_configurations => #{network_configurations}") if @DEBUG + network_configurations.each do |configuration_name, configuraiton| + if vm_network_name =~ /#{configuration_name}/ + network_configuration_name = configuration_name + network_configuration = configuraiton + break + end + end + log(:info, "vm_network_name => #{vm_network_name}") if @DEBUG + log(:info, "network_configuration_name => #{network_configuration_name}") if @DEBUG + log(:info, "network_configuration => #{network_configuration}") if @DEBUG -# Get all of the network configuration instances. -# -# @return Array of all of the network configuration instances -NETWORK_CONFIGURATION_URI = 'Infrastructure/Network/Configuration'.freeze -def get_network_configurations() - network_instances = $evm.vmdb("MiqAeDomain").all.collect { |domain| $evm.instance_find("/#{domain.name}/#{NETWORK_CONFIGURATION_URI}/*") } - network_instances = Hash[*network_instances.collect{|h| h.to_a}.flatten] - - return network_instances -end + log(:warn, "Could not find network configuration for VM network <#{vm_network_name}>. Skipping release IP.") if network_configuration.nil? -begin - vm,options = get_vm_and_options() - - # NOTE: this is hard coded to the first network interface because can't - # decide how to determine which network interfaces to release the IPs for... - # - # TODO: don't hard code this to first interface - network = vm.hardware.nics[0].lan - - # TODO: figure out some workaround to this issue or do something else here. - # deal with https://bugzilla.redhat.com/show_bug.cgi?id=1572917 - if network.nil? - $evm.log( - :warn, - "Could not determine Network for VM <#{vm.name} to release IP address due to " + - "https://bugzilla.redhat.com/show_bug.cgi?id=1572917. IP address will need to be manually released. " + - "Ignoring & Skipping." - ) - exit MIQ_OK - end - - # find matching network configuration - vm_network_name = network.name - network_configurations = get_network_configurations() - network_configuration = nil - network_configuration_name = nil - $evm.log(:info, "network_configurations => #{network_configurations}") if @DEBUG - network_configurations.each do |configuration_name, configuraiton| - if vm_network_name =~ /#{configuration_name}/ - network_configuration_name = configuration_name - network_configuration = configuraiton - break - end - end - $evm.log(:info, "vm_network_name => #{vm_network_name}") if @DEBUG - $evm.log(:info, "network_configuration_name => #{network_configuration_name}") if @DEBUG - $evm.log(:info, "network_configuration => #{network_configuration}") if @DEBUG - - $evm.log(:warn, "Could not find network configuration for VM network <#{vm_network_name}>. Skipping release IP.") if network_configuration.nil? - - # determine the DDI provider - ddi_provider = network_configuration['network_ddi_provider'] if network_configuration - $evm.log(:info, "ddi_provider => #{ddi_provider}") if @DEBUG - - if !ddi_provider.blank? - # instantiate instance to aquire IP - begin - $evm.log(:info, "Release IP address using DDI Provider <#{ddi_provider}>") if @DEBUG - - $evm.root['network_name'] = vm_network_name - $evm.root['network_configuration_name'] = network_configuration_name - $evm.instantiate("#{DDI_PROVIDERS_URI}/#{ddi_provider}#release_ip_address") - released_ip_address = get_param(:released_ip_address) - - $evm.log(:info, "Released IP address <#{released_ip_address}> using DDI Provider <#{ddi_provider}>") if @DEBUG - ensure - success = $evm.root['ae_result'] == nil || $evm.root['ae_result'] == 'ok' - reason = $evm.root['ae_reason'] if !success - - # clean up root - $evm.root['ae_result'] = nil - $evm.root['ae_reason'] = nil - - # clean up after call - $evm.root['network_name'] = nil - $evm.root['network_configuration_name'] = nil - $evm.root['released_ip_address'] = nil - - $evm.root['ae_reason'] = "Released IP address <#{released_ip_address}>" + # determine the DDI provider + ddi_provider = network_configuration['network_ddi_provider'] if network_configuration + log(:info, "ddi_provider => #{ddi_provider}") if @DEBUG + + if !ddi_provider.blank? + # instantiate instance to aquire IP + begin + log(:info, "Release IP address using DDI Provider <#{ddi_provider}>") if @DEBUG + + @handle.root['network_name'] = vm_network_name + @handle.root['network_configuration_name'] = network_configuration_name + @handle.instantiate("#{DDI_PROVIDERS_URI}/#{ddi_provider}#release_ip_address") + released_ip_address = get_param(:released_ip_address) + + log(:info, "Released IP address <#{released_ip_address}> using DDI Provider <#{ddi_provider}>") if @DEBUG + ensure + success = @handle.root['ae_result'] == nil || $evm.root['ae_result'] == 'ok' + reason = @handle.root['ae_reason'] if !success + + # clean up root + @handle.root['ae_result'] = nil + @handle.root['ae_reason'] = nil + + # clean up after call + @handle.root['network_name'] = nil + @handle.root['network_configuration_name'] = nil + @handle.root['released_ip_address'] = nil + + @handle.root['ae_reason'] = "Released IP address <#{released_ip_address}>" + end + else + @handle.root['ae_reason'] = "Can not retire IP for VM <#{vm.name}>, no DDI Provider found for Network <#{vm_network_name}>." + @handle.root['ae_level'] = :warning + end + + # set the released IP + @handle.object['released_ip_address'] = released_ip_address + @handle.set_state_var(:released_ip_address, released_ip_address) + @handle.root['ae_result'] = 'ok' + end + end + + end + end + end end - else - $evm.root['ae_reason'] = "Can not retire IP for VM <#{vm.name}>, no DDI Provider found for Network <#{vm_network_name}>." - $evm.root['ae_level'] = :warning end - - # set the released IP - $evm.object['released_ip_address'] = released_ip_address - $evm.root['ae_result'] = 'ok' +end + +if __FILE__ == $PROGRAM_NAME + RedHatConsulting_Utilities::Infrastructure::Network::Operations::Methods::ReleaseIPAddress.new.main() end diff --git a/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/release_ip_address.yaml b/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/release_ip_address.yaml index 2591046..108feac 100644 --- a/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/release_ip_address.yaml +++ b/Automate/RedHatConsulting_Utilities/Infrastructure/Network/Operations/Methods.class/__methods__/release_ip_address.yaml @@ -9,5 +9,7 @@ object: scope: instance language: ruby location: inline + embedded_methods: + - "/StdLib/Core/Core" options: {} inputs: [] diff --git a/Automate/RedHatConsulting_Utilities/Infrastructure/VM/Provisioning/Email.class/__methods__/miqprovision_update.rb b/Automate/RedHatConsulting_Utilities/Infrastructure/VM/Provisioning/Email.class/__methods__/miqprovision_update.rb index 9d96c14..c6369ee 100644 --- a/Automate/RedHatConsulting_Utilities/Infrastructure/VM/Provisioning/Email.class/__methods__/miqprovision_update.rb +++ b/Automate/RedHatConsulting_Utilities/Infrastructure/VM/Provisioning/Email.class/__methods__/miqprovision_update.rb @@ -21,37 +21,44 @@ def initialize(handle = $evm) end def main - # get the miq_provision task - prov = @handle.root['miq_provision_request'] || @handle.root['miq_provision'] + begin + # get the miq_provision task + prov = @handle.root['miq_provision_request'] || @handle.root['miq_provision'] - error("miq_provision object not provided") unless prov + error("miq_provision object not provided") unless prov - # determine to email addresses - to_email_addresses = determine_to_email_addresses(prov) - to_email_addresses = to_email_addresses.join(';') + # determine to email addresses + to_email_addresses = determine_to_email_addresses(prov) + to_email_addresses = to_email_addresses.join(';') - # determine the CFME/ManageIQ hostname - cfme_hostname = determine_cfme_hostname() + # determine the CFME/ManageIQ hostname + cfme_hostname = determine_cfme_hostname() - # determine from email address - from_email_address = determine_from_email_address(cfme_hostname) + # determine from email address + from_email_address = determine_from_email_address(cfme_hostname) - # get the VM provision update message - update_message = get_param(:vm_provision_update_message) - update_message ||= prov.miq_request.try(:user_message) - update_message ||= 'None' + # get the VM provision update message + update_message = get_param(:vm_provision_update_message) + update_message ||= prov.miq_request.try(:user_message) + update_message ||= 'None' - # get current VM provisioning status - vm_current_provision_ae_result = get_param(:vm_current_provision_ae_result) + # get current VM provisioning status + vm_current_provision_ae_result = get_param(:vm_current_provision_ae_result) - # send the email - unless to_email_addresses.blank? - send_vm_provision_update_email(prov, to_email_addresses, from_email_address, update_message, vm_current_provision_ae_result, cfme_hostname) - else - warn_message = "No one to send VM Provision Update email to. Request: #{prov.miq_provision_request.id}" - log(:warn, warn_message) + # send the email + unless to_email_addresses.blank? + send_vm_provision_update_email(prov, to_email_addresses, from_email_address, update_message, vm_current_provision_ae_result, cfme_hostname) + else + warn_message = "No one to send VM Provision Update email to. Request: #{prov.miq_provision_request.id}" + log(:warn, warn_message) + @handle.create_notification(:level => 'warning', + :message => warn_message) + end + rescue => err + log(:error, "Unable to send email: [#{err}]\n#{err.backtrace.join('\n')}" ) @handle.create_notification(:level => 'warning', - :message => warn_message) + :message => "Error sending provisioning update email. See automation logs for details.") + exit MIQ_WARN end end @@ -241,4 +248,4 @@ def send_vm_provision_update_email(prov, to, from, update_message, vm_current_pr if __FILE__ == $PROGRAM_NAME RedHatConsulting_Utilities::Automate::VM::Provisioning::Email::MIQProvision_Update.new.main -end \ No newline at end of file +end diff --git a/Automate/RedHatConsulting_Utilities/Integration/AnsibleTower/AnsibleTowerBase.class/__methods__/ansibletowerbase.rb b/Automate/RedHatConsulting_Utilities/Integration/AnsibleTower/AnsibleTowerBase.class/__methods__/ansibletowerbase.rb index 5b653dd..db3d082 100644 --- a/Automate/RedHatConsulting_Utilities/Integration/AnsibleTower/AnsibleTowerBase.class/__methods__/ansibletowerbase.rb +++ b/Automate/RedHatConsulting_Utilities/Integration/AnsibleTower/AnsibleTowerBase.class/__methods__/ansibletowerbase.rb @@ -26,7 +26,7 @@ def initialize( handle = $evm ) validate_tower_configuration log(:info, "Resolved Ansible Tower Configuration URI: #{@tower_config.name}") if @DEBUG @tower_inventory_name = @tower_config['tower_inventory_name'] - @tower_inventory_id = determine_tower_inventory_id + @tower_inventory_id = nil end def validate_tower_configuration @@ -100,11 +100,12 @@ def inventory_hostname( vm ) # Determine Internal Ansible Tower Inventory ID based on Tower Inventory Name def determine_tower_inventory_id + return @tower_inventory_id if @tower_inventory_id.present? api_path = "inventories?name=#{CGI.escape(@tower_inventory_name)}" inventory_result = tower_request(:get, api_path) inventory_id = inventory_result['results'].first['id'] rescue nil error( "Unable to determine Ansible Tower Inventory ID from Inventory Name [ #{@tower_inventory_name} ]") if inventory_id.nil? - log(:info, "Inventory ID determined from Inventory name: [ #{@tower_inventory_name} ] --> ID: [ #{@tower_inventory_id} ]") if @DEBUG + log(:info, "Inventory ID determined from Inventory name: [ #{@tower_inventory_name} ] --> ID: [ #{inventory_id} ]") if @DEBUG return inventory_id end @@ -113,6 +114,7 @@ def determine_tower_inventory_id # # @param vm object def vm_in_inventory?( vm ) + @tower_inventory_id = determine_tower_inventory_id api_path = "inventories/#{@tower_inventory_id}/hosts?name=#{inventory_hostname( vm )}" result = tower_request(:get, api_path) return result['count'] != 0 @@ -123,8 +125,9 @@ def vm_in_inventory?( vm ) # # @param vm object def tower_host_id( vm ) - api_path = "inventories/#{@tower_inventory_id}/hosts?name=#{inventory_hostname( vm )}" - result = tower_request(:get, api_path) + @tower_inventory_id = determine_tower_inventory_id + api_path = "inventories/#{@tower_inventory_id}/hosts?name=#{inventory_hostname( vm )}" + result = tower_request(:get, api_path) result['count'] != 0 ? result['results'].first['id'] : nil end diff --git a/Automate/RedHatConsulting_Utilities/StdLib/Core.class/__methods__/core.rb b/Automate/RedHatConsulting_Utilities/StdLib/Core.class/__methods__/core.rb index e2e0381..6cd2958 100644 --- a/Automate/RedHatConsulting_Utilities/StdLib/Core.class/__methods__/core.rb +++ b/Automate/RedHatConsulting_Utilities/StdLib/Core.class/__methods__/core.rb @@ -299,7 +299,12 @@ def get_vm_and_options() options = @handle.root.attributes #merge the ws_values, dialog, top level options into one list to make it easier to search options = options.merge(options[:ws_values]) if options[:ws_values] - options = options.merge(options[:dialog]) if options[:dialog] + options = options.merge(options[:dialog]) if options[:dialog] + when 'vm_retire_task' + vm_retire_task = $evm.root['vm_retire_task'] + dump_object('vm_retire_task', vm_retire_task) if @DEBUG + vm = get_param(:vm) + options = vm_retire_task['options'] when 'automation_task' # get root objet automation_task = @handle.root['automation_task'] @@ -313,7 +318,7 @@ def get_vm_and_options() options = options.symbolize_keys if options #merge the ws_values, dialog, top level options into one list to make it easier to search options = options.merge(options[:ws_values]) if options[:ws_values] - options = options.merge(options[:dialog]) if options[:dialog] + options = options.merge(options[:dialog]) if options[:dialog] when 'service_template_provision_task' task = @handle.root['service_template_provision_task'] @@ -328,11 +333,21 @@ def get_vm_and_options() end # standerdize the option keys - options = options.symbolize_keys() + options = options.symbolize_keys() if options.present? return vm, options end + # Get all of the network configuration instances. + # + # @return Array of all of the network configuration instances + NETWORK_CONFIGURATION_URI = 'Infrastructure/Network/Configuration'.freeze + def get_network_configurations() + network_instances = @handle.vmdb("MiqAeDomain").all.collect { |domain| $evm.instance_find("/#{domain.name}/#{NETWORK_CONFIGURATION_URI}/*") } + network_instances = Hash[*network_instances.collect{|h| h.to_a}.flatten] + return network_instances + end + # Create a Tag Category if it does not already exist # # @param category Tag Category to create