Skip to content

Commit

Permalink
Supporting CFME 5.10 Retirement tasks (#160)
Browse files Browse the repository at this point in the history
+ Converting more things to class style
+ Misc bug fixes/error handling/enhancements
  • Loading branch information
A-Beck authored Oct 3, 2019
1 parent 3abeb57 commit 6e6eb58
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 474 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -72,22 +72,22 @@ 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

# Verify if the name is in the inventory
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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ object:
scope: instance
language: ruby
location: inline
embedded_methods:
- "/StdLib/Core/Core"
options: {}
inputs: []
Loading

0 comments on commit 6e6eb58

Please sign in to comment.