Embedded Method Example
Embedded methods are particularly useful if a set of reusable library methods each need several supporting methods to implement their functionality. The supporting methods do not need to be made visible to the caller Automate method.
The following is an example of such an embedded method definition. It has only two callable public methods, vnic_profile and vnic_profiles, however these both use the functionality of the ovirtsdk4 gem to communicate with a RHV Manager, and therefore require several private methods to setup the connection and manage the ovirtsdk services.
The embedded class is written with an initializer to allow the caller to pass in the object or ID identifying the RHV provider with which to communicate (there could be multiple RHV providers in a system).
The embedded method is as follows:
1
#
2
# Utility library for Red Hat Virtualization
3
#
4
require 'ovirtsdk4'
5
6
module Automation
7
module Infrastructure
8
module VM
9
module RedHat
10
class Utils
11
12
def initialize(ems, handle = $evm)
13
@handle = handle
14
@ems = ems_to_service_model(ems)
15
@connection = connection(@ems)
16
end
17
18
def vnic_profile(profile_name, network_name, dc_name)
19
vnic_profile = vnic_profiles_service.list.select { |profile|
20
(profile.name == profile_name) &&
21
(profile.network.id == network_by_name(network_name, dc_name).id)
22
}.first
23
vnic_profile
24
end
25
26
def vnic_profiles(dc_name)
27
profiles = []
28
dc_networks = networks(dc_name).map {|network| network.id }
29
vnic_profiles_service.list.each do |vnic_profile|
30
next unless dc_networks.include?(vnic_profile.network.id)
31
network = network_by_id(vnic_profile.network.id, dc_name)
32
profiles << {:id => vnic_profile.id, :name => "#{vnic_profile.name} (#{network.name})"}
33
end
34
profiles
35
end
36
37
private
38
39
def ems_to_service_model(ems)
40
raise "Invalid EMS" if ems.nil?
41
# ems could be a numeric id or the ems object itself
42
unless ems.is_a?(DRb::DRbObject) && /Manager/.match(ems.type.demodulize)
43
if /^\d{1,13}$/.match(ems.to_s)
44
ems = @handle.vmdb(:ems, ems)
45
end
46
end
47
ems
48
end
49
50
def network_by_name(name, dc_name)
51
networks(dc_name).detect { |n| n.name == name }
52
end
53
54
def network_by_id(id, dc_name)
55
networks(dc_name).detect { |n| n.id == id }
56
end
57
58
def networks(dc_name)
59
@connection.follow_link(dc(dc_name).networks)
60
end
61
62
def dc(name)
63
dcs_service.list(search: "name=#{name}").first
64
end
65
66
def vnic_profiles_service
67
@connection.system_service.vnic_profiles_service
68
end
69
70
def dcs_service
71
@connection.system_service.data_centers_service
72
end
73
74
def connection(ems)
75
connection = OvirtSDK4::Connection.new(
76
url: "https://#{ems.hostname}/ovirt-engine/api",
77
username: ems.authentication_userid,
78
password: ems.authentication_password,
79
insecure: true)
80
connection if connection.test(true)
81
end
82
83
end
84
end
85
end
86
end
87
end
Copied!

Invoking the Embedded Methods

The embedded method path is first added to the definition of the Automate method that is to invoke the library methods (see screenshot Embedded Method).
Embedded Method
The two public methods are then available for use. The vnic_profiles method could be invoked from a dynamic dialog element method to list all vNIC Profiles, as follows:
1
begin
2
rhv_ems = $evm.vmdb(:ems).where(:name => 'RHV').first
3
values_hash = {}
4
values_hash['!'] = '** no vNIC profiles found **'
5
6
# Call the embedded method
7
rhv = Automation::Infrastructure::VM::RedHat::Utils.new(rhv_ems)
8
vnic_profiles = rhv.vnic_profiles('DefaultDC')
9
10
unless vnic_profiles.empty?
11
values_hash['!'] = '-- select from list --'
12
vnic_profiles.each do | profile |
13
values_hash[profile[:id]] = profile[:name]
14
end
15
end
16
17
list_values = {
18
'sort_by' => :value,
19
'data_type' => :string,
20
'required' => true,
21
'values' => values_hash
22
}
23
list_values.each { |key, value| $evm.object[key] = value }
24
25
rescue => err
26
$evm.log(:error, "[#{err}]\n#{err.backtrace.join("\n")}")
27
exit MIQ_STOP
28
29
end
Copied!
The vnic_profile method could be invoked to retrieve a vNIC Profile to subsequently use in a call to create_provision_request, as follows:
1
rhv_ems = $evm.vmdb(:ems).where(:name => 'RHV').first
2
3
# Call the embedded method
4
rhv = Automation::Infrastructure::VM::RedHat::Utils.new(rhv_ems)
5
vnic_profile_id = rhv.vnic_profile('ovirtmgmt', 'rhevm', 'DefaultDC').id
6
7
# arg1 = version
8
args = ['1.1']
9
# arg2 = templateFields
10
args << {'name' => 'rhel72-generic',
11
'request_type' => 'template'}
12
# arg3 = vmFields
13
args << {'vm_name' => vm_name,
14
'number_of_vms' => '1',
15
'vlan' => vnic_profile_id}
16
# arg4 = requester
17
args << {'owner_email' => '[email protected]',
18
'owner_first_name' => 'Peter',
19
'owner_last_name' => 'McGowan'}
20
# arg5 = tags
21
args << nil
22
# arg6 = additionalValues (ws_values)
23
args << nil
24
# arg7 = emsCustomAttributes
25
args << nil
26
# arg8 = miqCustomAttributes
27
args << nil
28
request_id = $evm.execute('create_provision_request', *args)
Copied!

Summary

This chapter has shown how an embedded method can be used to encapsulate private or support code but still expose useful public library methods that can be invoked externally. Prior to the advent of embedded methods the connection and service methods would have needed to be defined in any Automate method that used the functionality of the ovirtsdk4 gem.