knife-vcenter 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  # Author:: Chef Partner Engineering (<partnereng@chef.io>)
4
- # Copyright:: Copyright (c) 2017 Chef Software, Inc.
4
+ # Copyright:: Copyright (c) 2017-2018 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,31 +17,36 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
- require 'chef/knife'
21
- require 'chef/knife/cloud/server/delete_options'
22
- require 'chef/knife/cloud/server/delete_command'
23
- require 'chef/knife/cloud/vcenter_service'
24
- require 'chef/knife/cloud/vcenter_service_helpers'
25
- require 'chef/knife/cloud/vcenter_service_options'
20
+ require "chef/knife"
21
+ require "chef/knife/cloud/server/delete_options"
22
+ require "chef/knife/cloud/server/delete_command"
23
+ require "chef/knife/cloud/vcenter_service"
24
+ require "chef/knife/cloud/vcenter_service_helpers"
25
+ require "chef/knife/cloud/vcenter_service_options"
26
26
 
27
27
  class Chef
28
28
  class Knife
29
29
  class Cloud
30
+ # Extends the SeverDeleteCommand for specifically vCenter
30
31
  class VcenterVmDelete < ServerDeleteCommand
31
32
  include ServerDeleteOptions
32
33
  include VcenterServiceOptions
33
34
  include VcenterServiceHelpers
34
35
 
35
- banner 'knife vcenter vm delete NAME [NAME] (options)'
36
+ banner "knife vcenter vm delete NAME [NAME] (options)"
36
37
 
37
38
  # rubocop:disable Style/GuardClause
39
+ # Validates the parameters to make sure we're good.
40
+ #
38
41
  def validate_params!
39
42
  if @name_args.empty?
40
- ui.error('You must supply the name of the virtual machine to delete.')
43
+ ui.error("You must supply the name of the virtual machine to delete.")
41
44
  exit(1) if @name_args.empty?
42
45
  end
43
46
  end
44
47
 
48
+ # Executes the command against vCenter and the Chef Server
49
+ #
45
50
  def execute_command
46
51
  @name_args.each do |name|
47
52
  service.delete_vm(name)
@@ -51,4 +56,4 @@ class Chef
51
56
  end
52
57
  end
53
58
  end
54
- end
59
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  # Author:: Chef Partner Engineering (<partnereng@chef.io>)
4
- # Copyright:: Copyright (c) 2017 Chef Software, Inc.
4
+ # Copyright:: Copyright (c) 2017-2018 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,50 +17,60 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
- require 'chef/knife'
21
- require 'chef/knife/cloud/server/list_command'
22
- require 'chef/knife/cloud/server/list_options'
23
- require 'chef/knife/cloud/vcenter_service'
24
- require 'chef/knife/cloud/vcenter_service_helpers'
25
- require 'chef/knife/cloud/vcenter_service_options'
20
+ require "chef/knife"
21
+ require "chef/knife/cloud/server/list_command"
22
+ require "chef/knife/cloud/server/list_options"
23
+ require "chef/knife/cloud/vcenter_service"
24
+ require "chef/knife/cloud/vcenter_service_helpers"
25
+ require "chef/knife/cloud/vcenter_service_options"
26
26
 
27
27
  class Chef
28
+ # The main knife class
28
29
  class Knife
30
+ # The main cloud class from knife-cloud
29
31
  class Cloud
32
+ # Extends the ServerListCommand for specific vCenter
30
33
  class VcenterVmList < Chef::Knife::Cloud::ServerListCommand
31
34
  include VcenterServiceHelpers
32
35
  include VcenterServiceOptions
33
36
 
34
- banner 'knife vcenter vm list'
37
+ banner "knife vcenter vm list"
35
38
 
39
+ # Sets up the columns for listing out and sorts by name
40
+ #
36
41
  def before_exec_command
37
42
  @columns_with_info = [
38
- { label: 'ID', key: 'vm' },
39
- { label: 'Name', key: 'name' },
40
- { label: 'Power State', key: 'power_state', value_callback: method(:format_power_status) },
41
- { label: 'CPU Count', key: 'cpu_count'},
42
- { label: 'RAM Size (MB)', key: 'memory_size_MiB', value_callback: method(:format_memory_value) },
43
+ { label: "ID", key: "vm" },
44
+ { label: "Name", key: "name" },
45
+ { label: "Power State", key: "power_state", value_callback: method(:format_power_status) },
46
+ { label: "CPU Count", key: "cpu_count" },
47
+ { label: "RAM Size (MB)", key: "memory_size_MiB", value_callback: method(:format_memory_value) }
43
48
  ]
44
49
 
45
- @sort_by_field = 'name'
50
+ @sort_by_field = "name"
46
51
  end
47
52
 
53
+ # Sets the color for the different status of the machines
54
+ #
48
55
  def format_power_status(status)
49
56
  status_check = status.value
50
57
  status_color = case status_check
51
- when 'POWERED_OFF'
52
- :red
53
- when 'POWERED_ON'
54
- :green
55
- when 'SUSPENDED'
56
- :yellow
58
+ when "POWERED_OFF"
59
+ :red
60
+ when "POWERED_ON"
61
+ :green
62
+ when "SUSPENDED"
63
+ :yellow
57
64
  end
58
65
 
59
66
  ui.color(status.value, status_color)
60
67
  end
61
68
 
69
+ # Formats the memory value
70
+ #
71
+ # @param [Object] value takes the number and formats it how you need it to
62
72
  def format_memory_value(value)
63
- value.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse
73
+ value.to_s.reverse.gsub(/...(?=.)/, '\&,').reverse
64
74
  end
65
75
  end
66
76
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  # Author:: Chef Partner Engineering (<partnereng@chef.io>)
4
- # Copyright:: Copyright (c) 2017 Chef Software, Inc.
4
+ # Copyright:: Copyright (c) 2017-2018 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,32 +17,31 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
- require 'chef/knife'
21
- require 'chef/knife/cloud/server/show_options'
22
- require 'chef/knife/cloud/server/show_command'
23
- require 'chef/knife/cloud/vcenter_service'
24
- require 'chef/knife/cloud/vcenter_service_helpers'
25
- require 'chef/knife/cloud/vcenter_service_options'
20
+ require "chef/knife"
21
+ require "chef/knife/cloud/server/show_options"
22
+ require "chef/knife/cloud/server/show_command"
23
+ require "chef/knife/cloud/vcenter_service"
24
+ require "chef/knife/cloud/vcenter_service_helpers"
25
+ require "chef/knife/cloud/vcenter_service_options"
26
26
 
27
27
  class Chef
28
28
  class Knife
29
29
  class Cloud
30
+ # Extends the SeverShowCommand to do specific things for vCenter
30
31
  class VcenterVmShow < ServerShowCommand
31
32
  include ServerShowOptions
32
33
  include VcenterServiceOptions
33
34
  include VcenterServiceHelpers
34
35
 
35
- banner 'knife vcenter vm show NAME (options)'
36
-
37
- # rubocop:disable Style/GuardClause
36
+ banner "knife vcenter vm show NAME (options)"
38
37
  def validate_params!
39
38
  if @name_args.empty?
40
- ui.error('You must supply the name of the virtual machine to display.')
39
+ ui.error("You must supply the name of the virtual machine to display.")
41
40
  exit(1) if @name_args.empty?
42
41
  end
43
42
 
44
43
  if @name_args.size > 1
45
- ui.error('You may only supply one virtual machine name')
44
+ ui.error("You may only supply one virtual machine name")
46
45
  exit 1
47
46
  end
48
47
 
@@ -51,4 +50,4 @@ class Chef
51
50
  end
52
51
  end
53
52
  end
54
- end
53
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  # Author:: Chef Partner Engineering (<partnereng@chef.io>)
4
- # Copyright:: Copyright (c) 2017 Chef Software, Inc.
4
+ # Copyright:: Copyright (c) 2017-2018 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,6 +17,8 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
+ # Provisions machines in vCenter
20
21
  module KnifeVcenter
21
- VERSION = '2.0.0'.freeze
22
+ # The version of this amazing Gem, you should <3 it.
23
+ VERSION = "2.0.1"
22
24
  end
@@ -1,463 +1,457 @@
1
1
  # Copyright 2014-2017 VMware, Inc. All Rights Reserved.
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
- require 'savon'
5
- require 'nokogiri'
6
- require 'base'
4
+ require "savon"
5
+ require "nokogiri"
6
+ require "base"
7
7
  # require 'sample/framework/sample_base'
8
8
 
9
9
  # Utility class that helps use the lookup service.
10
10
  class LookupServiceHelper
11
-
12
- attr_reader :sample, :wsdl_url, :soap_url
13
- attr_reader :serviceRegistration
14
-
15
- # Constructs a new instance.
16
- # @param sample [SampleBase] the associated sample, which provides access
17
- # to the configuration properties of the sample
18
- def initialize(host)
19
-
20
- @soap_url = format("https://%s/lookupservice/sdk", host)
21
- @wsdl_url = format("https://%s/lookupservice/wsdl/lookup.wsdl", host)
22
-
23
- end
24
-
25
- # Connects to the lookup service.
26
- def connect
27
- rsc = RetrieveServiceContent.new(client).invoke()
28
- @serviceRegistration = rsc.get_service_registration()
29
- Base.log.info "service registration = #{serviceRegistration}"
30
- end
31
-
32
- # Finds the SSO service URL.
33
- # In a MxN setup where there are more than one PSC nodes;
34
- # This method returns the first SSO service endpoint URL
35
- # as returned by the lookup service.
36
- #
37
- # @return [String] SSO Service endpoint URL.
38
- def find_sso_url
39
- result = find_service_url(product='com.vmware.cis',
40
- service='cs.identity',
41
- endpoint='com.vmware.cis.cs.identity.sso',
42
- protocol='wsTrust')
43
- raise 'SSO URL not found' unless result && result.size > 0
44
- return result.values[0]
45
- end
46
-
47
- # Finds all the vAPI service endpoint URLs.
48
- # In a MxN setup where there are more than one management node;
49
- # this method returns more than one URL
50
- #
51
- # @return [Hash] vapi service endpoint URLs in a dictionary
52
- # where the key is the node_id and the value is the service URL.
53
- def find_vapi_urls
54
- return find_service_url(product='com.vmware.cis',
55
- service='cs.vapi',
56
- endpoint='com.vmware.vapi.endpoint',
57
- protocol='vapi.json.https.public')
58
- end
59
-
60
- # Finds the vapi service endpoint URL of a management node.
61
- #
62
- # @param node_id [String] The UUID of the management node.
63
- # @return [String] vapi service endpoint URL of a management node or
64
- # nil if no vapi endpoint is found.
65
- def find_vapi_url(node_id)
66
- raise 'node_id is required' if node_id.nil?
67
- result = find_vapi_urls()
68
- raise 'VAPI URLs not found' unless result && result.size > 0
69
- return result[node_id]
70
- end
71
-
72
- # Finds all the vim service endpoint URLs
73
- # In a MxN setup where there are more than one management node;
74
- # this method returns more than one URL
75
- #
76
- # @return [Hash] vim service endpoint URLs in a dictionary where
77
- # the key is the node_id and the value is the service URL.
78
- def find_vim_urls
79
- return find_service_url(product='com.vmware.cis',
80
- service='vcenterserver',
81
- endpoint='com.vmware.vim',
82
- protocol='vmomi')
83
- end
84
-
85
- # Finds the vim service endpoint URL of a management node
86
- #
87
- # @param node_id [String] The UUID of the management node.
88
- # @return [String] vim service endpoint URL of a management node or
89
- # nil if no vim endpoint is found.
90
- def find_vim_url(node_id)
91
- raise 'node_id is required' if node_id.nil?
92
- result = find_vim_urls()
93
- raise 'VIM URLs not found' unless result && result.size > 0
94
- return result[node_id]
95
- end
96
-
97
- # Finds all the spbm service endpoint URLs
98
- # In a MxN setup where there are more than one management node;
99
- # this method returns more than one URL
100
- #
101
- # @return [Hash] spbm service endpoint URLs in a dictionary where
102
- # the key is the node_id and the value is the service URL.
103
- def find_vim_pbm_urls
104
- return find_service_url(product='com.vmware.vim.sms',
105
- service='sms',
106
- endpoint='com.vmware.vim.pbm',
107
- protocol='https')
108
- end
109
-
110
- # Finds the spbm service endpoint URL of a management node
111
- #
112
- # @param node_id [String] The UUID of the management node.
113
- # @return [String] spbm service endpoint URL of a management node or
114
- # nil if no spbm endpoint is found.
115
- def find_vim_pbm_url(node_id)
116
- raise 'node_id is required' if node_id.nil?
117
- result = find_vim_pbm_urls()
118
- raise 'PBM URLs not found' unless result && result.size > 0
119
- return result[node_id]
120
- end
121
-
122
- # Get the management node id from the instance name
123
- #
124
- # @param instance_name [String] The instance name of the management node
125
- # @return [String] The UUID of the management node or
126
- # nil is no management node is found by the given instance name
127
- def get_mgmt_node_id(instance_name)
128
- raise 'instance_name is required' if instance_name.nil?
129
- result = find_mgmt_nodes()
130
- raise 'Management nodes not found' unless result && result.size > 0
131
- return result[instance_name]
132
- end
133
-
134
- def get_mgmt_node_instance_name(node_id)
135
- raise 'node_id is required' if node_id.nil?
136
- result = find_mgmt_nodes()
137
- raise 'Management nodes not found' unless result && result.size > 0
138
- result.each { |k, v| return k if v == node_id }
139
- nil
140
- end
141
-
142
- # Finds the instance name and UUID of the management node for M1xN1 or
143
- # when the PSC and management services all reside on a single node.
144
- def get_default_mgmt_node
145
- result = find_mgmt_nodes()
146
- raise 'Management nodes not found' unless result && result.size > 0
147
- #WHY: raise MultipleManagementNodeException.new if result.size > 1
148
- return [result.keys[0], result.values[0]]
149
- end
150
-
151
- # Finds all the management nodes
152
- #
153
- # @return [Hash] management node instance name and node id (UUID) in a dictionary.
154
- def find_mgmt_nodes
155
- #assert self.serviceRegistration is not None
156
- list = List.new(client, 'com.vmware.cis', 'vcenterserver',
157
- 'vmomi', 'com.vmware.vim')
158
-
159
- list.invoke()
160
- list.get_instance_names()
161
- end
162
-
163
- private
164
-
165
- # Finds a service URL with the given attributes.
166
- def find_service_url(product, service, endpoint, protocol)
167
- #assert serviceRegistration is not None
168
- list = List.new(client, product, service, protocol, endpoint)
169
-
170
- list.invoke()
171
- list.get_service_endpoints()
172
- end
173
-
174
- # Gets or creates the Savon client instance.
175
- def client
176
- @client ||= Savon.client do |globals|
177
- # see: http://savonrb.com/version2/globals.html
178
- globals.wsdl wsdl_url
179
- globals.endpoint soap_url
180
-
181
- globals.strip_namespaces false
182
- globals.env_namespace :S
183
-
184
- # set like this so https connection does not fail
185
- # TODO: find an acceptable solution for production
186
- globals.ssl_verify_mode :none
187
-
188
- # dev/debug settings
189
- # globals.pretty_print_xml ENV['DEBUG_SOAP']
190
- # globals.log ENV['DEBUG_SOAP']
191
- end
11
+ attr_reader :sample, :wsdl_url, :soap_url
12
+ attr_reader :serviceRegistration
13
+
14
+ # Constructs a new instance.
15
+ # @param [Object] host the associated sample, which provides access
16
+ # to the configuration properties of the sample
17
+ def initialize(host)
18
+ @soap_url = format("https://%s/lookupservice/sdk", host)
19
+ @wsdl_url = format("https://%s/lookupservice/wsdl/lookup.wsdl", host)
20
+ end
21
+
22
+ # Connects to the lookup service.
23
+ def connect
24
+ rsc = RetrieveServiceContent.new(client).invoke
25
+ @serviceRegistration = rsc.get_service_registration
26
+ Base.log.info "service registration = #{serviceRegistration}"
27
+ end
28
+
29
+ # Finds the SSO service URL.
30
+ # In a MxN setup where there are more than one PSC nodes;
31
+ # This method returns the first SSO service endpoint URL
32
+ # as returned by the lookup service.
33
+ #
34
+ # @return [String] SSO Service endpoint URL.
35
+ def find_sso_url
36
+ result = find_service_url(product = "com.vmware.cis",
37
+ service = "cs.identity",
38
+ endpoint = "com.vmware.cis.cs.identity.sso",
39
+ protocol = "wsTrust")
40
+ raise "SSO URL not found" unless result && !result.empty?
41
+
42
+ result.values[0]
43
+ end
44
+
45
+ # Finds all the vAPI service endpoint URLs.
46
+ # In a MxN setup where there are more than one management node;
47
+ # this method returns more than one URL
48
+ #
49
+ # @return [Hash] vapi service endpoint URLs in a dictionary
50
+ # where the key is the node_id and the value is the service URL.
51
+ def find_vapi_urls
52
+ find_service_url(product = "com.vmware.cis",
53
+ service = "cs.vapi",
54
+ endpoint = "com.vmware.vapi.endpoint",
55
+ protocol = "vapi.json.https.public")
56
+ end
57
+
58
+ # Finds the vapi service endpoint URL of a management node.
59
+ #
60
+ # @param node_id [String] The UUID of the management node.
61
+ # @return [String] vapi service endpoint URL of a management node or
62
+ # nil if no vapi endpoint is found.
63
+ def find_vapi_url(node_id)
64
+ raise "node_id is required" if node_id.nil?
65
+
66
+ result = find_vapi_urls
67
+ raise "VAPI URLs not found" unless result && !result.empty?
68
+
69
+ result[node_id]
70
+ end
71
+
72
+ # Finds all the vim service endpoint URLs
73
+ # In a MxN setup where there are more than one management node;
74
+ # this method returns more than one URL
75
+ #
76
+ # @return [Hash] vim service endpoint URLs in a dictionary where
77
+ # the key is the node_id and the value is the service URL.
78
+ def find_vim_urls
79
+ find_service_url(product = "com.vmware.cis",
80
+ service = "vcenterserver",
81
+ endpoint = "com.vmware.vim",
82
+ protocol = "vmomi")
83
+ end
84
+
85
+ # Finds the vim service endpoint URL of a management node
86
+ #
87
+ # @param node_id [String] The UUID of the management node.
88
+ # @return [String] vim service endpoint URL of a management node or
89
+ # nil if no vim endpoint is found.
90
+ def find_vim_url(node_id)
91
+ raise "node_id is required" if node_id.nil?
92
+
93
+ result = find_vim_urls
94
+ raise "VIM URLs not found" unless result && !result.empty?
95
+
96
+ result[node_id]
97
+ end
98
+
99
+ # Finds all the spbm service endpoint URLs
100
+ # In a MxN setup where there are more than one management node;
101
+ # this method returns more than one URL
102
+ #
103
+ # @return [Hash] spbm service endpoint URLs in a dictionary where
104
+ # the key is the node_id and the value is the service URL.
105
+ def find_vim_pbm_urls
106
+ find_service_url(product = "com.vmware.vim.sms",
107
+ service = "sms",
108
+ endpoint = "com.vmware.vim.pbm",
109
+ protocol = "https")
110
+ end
111
+
112
+ # Finds the spbm service endpoint URL of a management node
113
+ #
114
+ # @param node_id [String] The UUID of the management node.
115
+ # @return [String] spbm service endpoint URL of a management node or
116
+ # nil if no spbm endpoint is found.
117
+ def find_vim_pbm_url(node_id)
118
+ raise "node_id is required" if node_id.nil?
119
+
120
+ result = find_vim_pbm_urls
121
+ raise "PBM URLs not found" unless result && !result.empty?
122
+
123
+ result[node_id]
124
+ end
125
+
126
+ # Get the management node id from the instance name
127
+ #
128
+ # @param instance_name [String] The instance name of the management node
129
+ # @return [String] The UUID of the management node or
130
+ # nil is no management node is found by the given instance name
131
+ def get_mgmt_node_id(instance_name)
132
+ raise "instance_name is required" if instance_name.nil?
133
+ result = find_mgmt_nodes()
134
+ raise "Management nodes not found" unless result && result.size > 0
135
+ result[instance_name]
136
+ end
137
+
138
+ def get_mgmt_node_instance_name(node_id)
139
+ raise "node_id is required" if node_id.nil?
140
+
141
+ result = find_mgmt_nodes
142
+ raise "Management nodes not found" unless result && !result.empty?
143
+
144
+ result.each { |k, v| return k if v == node_id }
145
+ nil
146
+ end
147
+
148
+ # Finds the instance name and UUID of the management node for M1xN1 or
149
+ # when the PSC and management services all reside on a single node.
150
+ def get_default_mgmt_node
151
+ result = find_mgmt_nodes
152
+ raise "Management nodes not found" unless result && !result.empty?
153
+
154
+ # WHY: raise MultipleManagementNodeException.new if result.size > 1
155
+ [result.keys[0], result.values[0]]
156
+ end
157
+
158
+ # Finds all the management nodes
159
+ #
160
+ # @return [Hash] management node instance name and node id (UUID) in a dictionary.
161
+ def find_mgmt_nodes
162
+ # assert self.serviceRegistration is not None
163
+ list = List.new(client, "com.vmware.cis", "vcenterserver",
164
+ "vmomi", "com.vmware.vim")
165
+
166
+ list.invoke
167
+ list.get_instance_names
168
+ end
169
+
170
+ private
171
+
172
+ # Finds a service URL with the given attributes.
173
+ def find_service_url(product, service, endpoint, protocol)
174
+ # assert serviceRegistration is not None
175
+ list = List.new(client, product, service, protocol, endpoint)
176
+
177
+ list.invoke
178
+ list.get_service_endpoints
179
+ end
180
+
181
+ # Gets or creates the Savon client instance.
182
+ def client
183
+ @client ||= Savon.client do |globals|
184
+ # see: http://savonrb.com/version2/globals.html
185
+ globals.wsdl wsdl_url
186
+ globals.endpoint soap_url
187
+
188
+ globals.strip_namespaces false
189
+ globals.env_namespace :S
190
+
191
+ # set like this so https connection does not fail
192
+ # TODO: find an acceptable solution for production
193
+ globals.ssl_verify_mode :none
194
+
195
+ # dev/debug settings
196
+ # globals.pretty_print_xml ENV['DEBUG_SOAP']
197
+ # globals.log ENV['DEBUG_SOAP']
192
198
  end
199
+ end
193
200
  end
194
201
 
195
-
196
202
  # @abstract Base class for invocable service calls.
197
203
  class Invocable
198
-
199
- attr_reader :operation, :client, :response
200
-
201
- # Constructs a new instance.
202
- # @param operation [Symbol] the operation name
203
- # @param client [Savon::Client] the client
204
- def initialize(operation, client)
205
- @operation = operation
206
- @client = client
207
- end
208
-
209
- # Invokes the service call represented by this type.
210
- def invoke
211
- request = request_xml.to_s
212
- Base.log.debug(request)
213
- @response = client.call(operation, xml:request)
214
- Base.log.debug(response)
215
- self # for chaining with new
204
+ attr_reader :operation, :client, :response
205
+
206
+ # Constructs a new instance.
207
+ # @param operation [Symbol] the operation name
208
+ # @param client [Savon::Client] the client
209
+ def initialize(operation, client)
210
+ @operation = operation
211
+ @client = client
212
+ end
213
+
214
+ # Invokes the service call represented by this type.
215
+ def invoke
216
+ request = request_xml.to_s
217
+ Base.log.debug(request)
218
+ @response = client.call(operation, xml: request)
219
+ Base.log.debug(response)
220
+ self # for chaining with new
221
+ end
222
+
223
+ # Builds the request XML content.
224
+ def request_xml
225
+ builder = Builder::XmlMarkup.new
226
+ builder.instruct!(:xml, encoding: "UTF-8")
227
+
228
+ builder.tag!("S:Envelope",
229
+ "xmlns:S" => "http://schemas.xmlsoap.org/soap/envelope/") do |envelope|
230
+ envelope.tag!("S:Body") do |body|
231
+ body_xml(body)
232
+ end
216
233
  end
234
+ builder.target!
235
+ end
217
236
 
218
- # Builds the request XML content.
219
- def request_xml
220
- builder = Builder::XmlMarkup.new()
221
- builder.instruct!(:xml, encoding: "UTF-8")
222
-
223
- builder.tag!("S:Envelope",
224
- "xmlns:S" => "http://schemas.xmlsoap.org/soap/envelope/") do |envelope|
225
- envelope.tag!("S:Body") do |body|
226
- body_xml(body)
227
- end
228
- end
229
- builder.target!
230
- end
237
+ # Builds the body portion of the request XML content.
238
+ # Specific service operations must override this method.
239
+ def body_xml
240
+ raise "abstract method not implemented!"
241
+ end
231
242
 
232
- # Builds the body portion of the request XML content.
233
- # Specific service operations must override this method.
234
- def body_xml
235
- raise 'abstract method not implemented!'
236
- end
243
+ # Gets the response XML content.
244
+ def response_xml
245
+ raise "illegal state: response not set yet" if response.nil?
237
246
 
238
- # Gets the response XML content.
239
- def response_xml
240
- raise 'illegal state: response not set yet' if response.nil?
241
- @response_xml ||= Nokogiri::XML(response.to_xml)
242
- end
247
+ @response_xml ||= Nokogiri::XML(response.to_xml)
248
+ end
243
249
 
244
- def response_hash
245
- @response_hash ||= response.to_hash
246
- end
250
+ def response_hash
251
+ @response_hash ||= response.to_hash
252
+ end
247
253
  end
248
254
 
249
255
  # Encapsulates the list operation of the lookup service.
250
256
  class List < Invocable
251
-
252
- # Constructs a new instance.
253
- def initialize(client, product, service, protocol, endpoint)
254
- super(:list, client)
255
-
256
- @product = product
257
- @service = service
258
- @protocol = protocol
259
- @endpoint = endpoint
260
- end
261
-
262
- =begin
263
- <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
264
- <S:Body>
265
- <List xmlns="urn:lookup">
266
- <_this type="LookupServiceRegistration">ServiceRegistration</_this>
267
- <filterCriteria>
268
- <serviceType>
269
- <product>com.vmware.cis</product>
270
- <type>cs.identity</type>
271
- </serviceType>
272
- <endpointType>
273
- <protocol>wsTrust</protocol>
274
- <type>com.vmware.cis.cs.identity.sso</type>
275
- </endpointType>
276
- </filterCriteria>
277
- </List>
278
- </S:Body>
279
- </S:Envelope>
280
- =end
281
- def body_xml(body)
282
- body.tag!("List", "xmlns" => "urn:lookup") do |list|
283
- #TODO: use the copy that was retrieved on startup?
284
- list.tag!("_this",
285
- "type" => "LookupServiceRegistration") do |this|
286
- this << "ServiceRegistration"
287
- end
288
- list.tag!("filterCriteria") do |criteria|
289
- criteria.tag!("serviceType") do |stype|
290
- stype.tag!("product") do |p|
291
- p << @product
292
- end
293
- stype.tag!("type") do |t|
294
- t << @service
295
- end
296
- end
297
- criteria.tag!("endpointType") do |etype|
298
- etype.tag!("protocol") do |p|
299
- p << @protocol
300
- end
301
- etype.tag!("type") do |t|
302
- t << @endpoint
303
- end
304
- end
305
- end
257
+ # Constructs a new instance.
258
+ def initialize(client, product, service, protocol, endpoint)
259
+ super(:list, client)
260
+
261
+ @product = product
262
+ @service = service
263
+ @protocol = protocol
264
+ @endpoint = endpoint
265
+ end
266
+
267
+ # <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
268
+ # <S:Body>
269
+ # <List xmlns="urn:lookup">
270
+ # <_this type="LookupServiceRegistration">ServiceRegistration</_this>
271
+ # <filterCriteria>
272
+ # <serviceType>
273
+ # <product>com.vmware.cis</product>
274
+ # <type>cs.identity</type>
275
+ # </serviceType>
276
+ # <endpointType>
277
+ # <protocol>wsTrust</protocol>
278
+ # <type>com.vmware.cis.cs.identity.sso</type>
279
+ # </endpointType>
280
+ # </filterCriteria>
281
+ # </List>
282
+ # </S:Body>
283
+ # </S:Envelope>
284
+ def body_xml(body)
285
+ body.tag!("List", "xmlns" => "urn:lookup") do |list|
286
+ # TODO: use the copy that was retrieved on startup?
287
+ list.tag!("_this",
288
+ "type" => "LookupServiceRegistration") do |this|
289
+ this << "ServiceRegistration"
290
+ end
291
+ list.tag!("filterCriteria") do |criteria|
292
+ criteria.tag!("serviceType") do |stype|
293
+ stype.tag!("product") do |p|
294
+ p << @product
295
+ end
296
+ stype.tag!("type") do |t|
297
+ t << @service
298
+ end
299
+ end
300
+ criteria.tag!("endpointType") do |etype|
301
+ etype.tag!("protocol") do |p|
302
+ p << @protocol
303
+ end
304
+ etype.tag!("type") do |t|
305
+ t << @endpoint
306
+ end
306
307
  end
308
+ end
307
309
  end
308
-
309
- # Gets the service endpoint information from the response.
310
- # Support for MxN.
311
- # @return [Hash] a hash where the key is NodeId and the Value is a Service URL
312
- def get_service_endpoints
313
- result = {}
314
- =begin
315
- <ListResponse xmlns="urn:lookup">
316
- <returnval>
317
- <serviceVersion>2.0</serviceVersion>
318
- <vendorNameResourceKey/>
319
- <vendorNameDefault/>
320
- <vendorProductInfoResourceKey/>
321
- <vendorProductInfoDefault/>
322
- <serviceEndpoints>
323
- <url>https://pa-rdinfra3-vm7-dhcp5583.eng.vmware.com/sts/STSService/vsphere.local</url>
324
- <endpointType>
325
- <protocol>wsTrust</protocol>
326
- <type>com.vmware.cis.cs.identity.sso</type>
327
- </endpointType>
328
- <sslTrust>
329
- ...
330
- </sslTrust>
331
- </serviceEndpoints>
332
- <serviceNameResourceKey/>
333
- <serviceNameDefault/>
334
- <serviceDescriptionResourceKey/>
335
- <serviceDescriptionDefault/>
336
- <ownerId>pa-rdinfra3-vm7-dhcp5583.eng.vmware.com@vsphere.local</ownerId>
337
- <serviceType>
338
- <product>com.vmware.cis</product>
339
- <type>cs.identity</type>
340
- </serviceType>
341
- <nodeId/>
342
- <serviceId>6a8a5058-5d3d-4d42-bb5e-383b91c8732e</serviceId>
343
- <siteId>default-first-site</siteId>
344
- </returnval>
345
- </ListResponse>
346
- =end
347
- Base.log.debug "List: response_hash = #{response_hash}"
348
- return_val = response_hash[:list_response][:returnval]
349
- return_val = [return_val] if return_val.is_a? Hash
350
- return_val.each { |entry|
351
- #FYI: the node_id is sometimes null, so use the service_id in this case
352
- node_id = entry[:node_id] || entry[:service_id]
353
- result[node_id] = entry[:service_endpoints][:url]
354
- }
355
- Base.log.debug "List: result = #{result}"
356
- return result
310
+ end
311
+
312
+ # Gets the service endpoint information from the response.
313
+ # Support for MxN.
314
+ # @return [Hash] a hash where the key is NodeId and the Value is a Service URL
315
+ def get_service_endpoints
316
+ result = {}
317
+ # <ListResponse xmlns="urn:lookup">
318
+ # <returnval>
319
+ # <serviceVersion>2.0</serviceVersion>
320
+ # <vendorNameResourceKey/>
321
+ # <vendorNameDefault/>
322
+ # <vendorProductInfoResourceKey/>
323
+ # <vendorProductInfoDefault/>
324
+ # <serviceEndpoints>
325
+ # <url>https://pa-rdinfra3-vm7-dhcp5583.eng.vmware.com/sts/STSService/vsphere.local</url>
326
+ # <endpointType>
327
+ # <protocol>wsTrust</protocol>
328
+ # <type>com.vmware.cis.cs.identity.sso</type>
329
+ # </endpointType>
330
+ # <sslTrust>
331
+ # ...
332
+ # </sslTrust>
333
+ # </serviceEndpoints>
334
+ # <serviceNameResourceKey/>
335
+ # <serviceNameDefault/>
336
+ # <serviceDescriptionResourceKey/>
337
+ # <serviceDescriptionDefault/>
338
+ # <ownerId>pa-rdinfra3-vm7-dhcp5583.eng.vmware.com@vsphere.local</ownerId>
339
+ # <serviceType>
340
+ # <product>com.vmware.cis</product>
341
+ # <type>cs.identity</type>
342
+ # </serviceType>
343
+ # <nodeId/>
344
+ # <serviceId>6a8a5058-5d3d-4d42-bb5e-383b91c8732e</serviceId>
345
+ # <siteId>default-first-site</siteId>
346
+ # </returnval>
347
+ # </ListResponse>
348
+ Base.log.debug "List: response_hash = #{response_hash}"
349
+ return_val = response_hash[:list_response][:returnval]
350
+ return_val = [return_val] if return_val.is_a? Hash
351
+ return_val.each do |entry|
352
+ # FYI: the node_id is sometimes null, so use the service_id in this case
353
+ node_id = entry[:node_id] || entry[:service_id]
354
+ result[node_id] = entry[:service_endpoints][:url]
357
355
  end
358
-
359
- def get_instance_names
360
- result = {}
361
- =begin
362
- <serviceAttributes>
363
- <key>com.vmware.cis.cm.GroupInternalId</key>
364
- <value>com.vmware.vim.vcenter</value>
365
- </serviceAttributes>
366
- <serviceAttributes>
367
- <key>com.vmware.cis.cm.ControlScript</key>
368
- <value>vmware-vpxd.sh</value>
369
- </serviceAttributes>
370
- <serviceAttributes>
371
- <key>com.vmware.cis.cm.HostId</key>
372
- <value>906477a1-24c6-4d48-9e99-55ef962878f7</value>
373
- </serviceAttributes>
374
- <serviceAttributes>
375
- <key>com.vmware.vim.vcenter.instanceName</key>
376
- <value>pa-rdinfra3-vm7-dhcp5583.eng.vmware.com</value>
377
- </serviceAttributes>
378
- =end
379
- Base.log.debug "List: response_hash = #{response_hash}"
380
- return_val = response_hash[:list_response][:returnval]
381
- return_val = [return_val] if return_val.is_a? Hash
382
- return_val.each { |entry|
383
- node_id = entry[:node_id]
384
- #TODO: is it possible there be 0 or 1 attrs? if so, deal with it.
385
- attrs = entry[:service_attributes]
386
- Base.log.debug "List: attrs=#{attrs}"
387
- attrs.each { |attr|
388
- if attr[:key] == 'com.vmware.vim.vcenter.instanceName'
389
- result[attr[:value]] = node_id
390
- end
391
- }
392
- }
393
- Base.log.debug "List: result = #{result}"
394
- return result
356
+ Base.log.debug "List: result = #{result}"
357
+ result
358
+ end
359
+
360
+ def get_instance_names
361
+ result = {}
362
+ # <serviceAttributes>
363
+ # <key>com.vmware.cis.cm.GroupInternalId</key>
364
+ # <value>com.vmware.vim.vcenter</value>
365
+ # </serviceAttributes>
366
+ # <serviceAttributes>
367
+ # <key>com.vmware.cis.cm.ControlScript</key>
368
+ # <value>vmware-vpxd.sh</value>
369
+ # </serviceAttributes>
370
+ # <serviceAttributes>
371
+ # <key>com.vmware.cis.cm.HostId</key>
372
+ # <value>906477a1-24c6-4d48-9e99-55ef962878f7</value>
373
+ # </serviceAttributes>
374
+ # <serviceAttributes>
375
+ # <key>com.vmware.vim.vcenter.instanceName</key>
376
+ # <value>pa-rdinfra3-vm7-dhcp5583.eng.vmware.com</value>
377
+ # </serviceAttributes>
378
+ Base.log.debug "List: response_hash = #{response_hash}"
379
+ return_val = response_hash[:list_response][:returnval]
380
+ return_val = [return_val] if return_val.is_a? Hash
381
+ return_val.each do |entry|
382
+ node_id = entry[:node_id]
383
+ # TODO: is it possible there be 0 or 1 attrs? if so, deal with it.
384
+ attrs = entry[:service_attributes]
385
+ Base.log.debug "List: attrs=#{attrs}"
386
+ attrs.each do |attr|
387
+ if attr[:key] == "com.vmware.vim.vcenter.instanceName"
388
+ result[attr[:value]] = node_id
389
+ end
390
+ end
395
391
  end
392
+ Base.log.debug "List: result = #{result}"
393
+ result
394
+ end
396
395
  end
397
396
 
398
397
  # Encapsulates the RetrieveServiceContent operation of the lookup service.
399
398
  class RetrieveServiceContent < Invocable
400
-
401
- # Constructs a new instance.
402
- def initialize(client)
403
- super(:retrieve_service_content, client)
404
- end
405
-
406
- =begin
407
- <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
408
- <S:Body>
409
- <RetrieveServiceContent xmlns="urn:lookup">
410
- <_this type="LookupServiceInstance">ServiceInstance</_this>
411
- </RetrieveServiceContent>
412
- </S:Body>
413
- </S:Envelope>
414
- =end
415
- def body_xml(body)
416
- body.tag!("RetrieveServiceContent", "xmlns" => "urn:lookup") do |rsc|
417
- rsc.tag!("_this", "type" => "LookupServiceInstance") do |this|
418
- this << "ServiceInstance"
419
- end
420
- end
421
- end
422
-
423
- =begin
424
- ...
425
- <RetrieveServiceContentResponse xmlns="urn:lookup">
426
- <returnval>
427
- <lookupService type="LookupLookupService">lookupService</lookupService>
428
- <serviceRegistration type="LookupServiceRegistration">ServiceRegistration</serviceRegistration>
429
- <deploymentInformationService type="LookupDeploymentInformationService">deploymentInformationService</deploymentInformationService>
430
- <l10n type="LookupL10n">l10n</l10n>
431
- </returnval>
432
- </RetrieveServiceContentResponse>
433
- ...
434
- =end
435
- def get_service_registration
436
- Base.log.debug "RetrieveServiceContent: response_hash = #{response_hash}"
437
- return_val = response_hash[:retrieve_service_content_response][:returnval]
438
- result = return_val[:service_registration]
439
- Base.log.debug "RetrieveServiceContent: result = #{result}"
440
- result
399
+ # Constructs a new instance.
400
+ def initialize(client)
401
+ super(:retrieve_service_content, client)
402
+ end
403
+
404
+ # <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
405
+ # <S:Body>
406
+ # <RetrieveServiceContent xmlns="urn:lookup">
407
+ # <_this type="LookupServiceInstance">ServiceInstance</_this>
408
+ # </RetrieveServiceContent>
409
+ # </S:Body>
410
+ # </S:Envelope>
411
+ def body_xml(body)
412
+ body.tag!("RetrieveServiceContent", "xmlns" => "urn:lookup") do |rsc|
413
+ rsc.tag!("_this", "type" => "LookupServiceInstance") do |this|
414
+ this << "ServiceInstance"
415
+ end
441
416
  end
417
+ end
418
+
419
+ # ...
420
+ # <RetrieveServiceContentResponse xmlns="urn:lookup">
421
+ # <returnval>
422
+ # <lookupService type="LookupLookupService">lookupService</lookupService>
423
+ # <serviceRegistration type="LookupServiceRegistration">ServiceRegistration</serviceRegistration>
424
+ # <deploymentInformationService type="LookupDeploymentInformationService">deploymentInformationService</deploymentInformationService>
425
+ # <l10n type="LookupL10n">l10n</l10n>
426
+ # </returnval>
427
+ # </RetrieveServiceContentResponse>
428
+ # ...
429
+ def get_service_registration
430
+ Base.log.debug "RetrieveServiceContent: response_hash = #{response_hash}"
431
+ return_val = response_hash[:retrieve_service_content_response][:returnval]
432
+ result = return_val[:service_registration]
433
+ Base.log.debug "RetrieveServiceContent: result = #{result}"
434
+ result
435
+ end
442
436
  end
443
437
 
444
- class MultipleManagementNodeException < Exception
438
+ class MultipleManagementNodeException < RuntimeError
445
439
  end
446
440
 
447
441
  # main: quick self tester
448
- if __FILE__ == $0
449
- Base.log.level = Logger::DEBUG if ENV['DEBUG']
450
- sample = SelfTestSample.new
451
- sample.ls_ip = ARGV[0] || '10.67.245.207'
452
- #MXN: sample.ls_ip = '10.160.42.83'
453
- #MXN: sample.ls_ip = '10.160.35.191'
454
- #MAYBE: sample.main() # for arg parsing
455
- ls_helper = LookupServiceHelper.new(sample)
456
- ls_helper.connect()
457
- puts '***************************************'
458
- puts "SSO URL: #{ls_helper.find_sso_url()}"
459
- puts "VAPI URL: #{ls_helper.find_vapi_urls()}"
460
- puts "VIM URL: #{ls_helper.find_vim_urls()}"
461
- puts "PBM URL: #{ls_helper.find_vim_pbm_urls()}"
462
- puts "Mgmt Nodes: #{ls_helper.find_mgmt_nodes()}"
442
+ if $PROGRAM_NAME == __FILE__
443
+ Base.log.level = Logger::DEBUG if ENV["DEBUG"]
444
+ sample = SelfTestSample.new
445
+ sample.ls_ip = ARGV[0] || "10.67.245.207"
446
+ # MXN: sample.ls_ip = '10.160.42.83'
447
+ # MXN: sample.ls_ip = '10.160.35.191'
448
+ # MAYBE: sample.main() # for arg parsing
449
+ ls_helper = LookupServiceHelper.new(sample)
450
+ ls_helper.connect
451
+ puts "***************************************"
452
+ puts "SSO URL: #{ls_helper.find_sso_url}"
453
+ puts "VAPI URL: #{ls_helper.find_vapi_urls}"
454
+ puts "VIM URL: #{ls_helper.find_vim_urls}"
455
+ puts "PBM URL: #{ls_helper.find_vim_pbm_urls}"
456
+ puts "Mgmt Nodes: #{ls_helper.find_mgmt_nodes}"
463
457
  end