Class: Kitchen::Driver::Vro
- Inherits:
-
Base
- Object
- Base
- Kitchen::Driver::Vro
- Defined in:
- lib/kitchen/driver/vro.rb
Overview
Test Kitchen driver for VMware vRealize Orchestrator (vRO).
This driver does not build a machine itself. It runs two vRO workflows you supply -- one to create a server and one to destroy it -- and treats their output parameters as the machine's identity.
The create workflow must return two output parameters, server_id and
ip_address, both non-empty. server_id is stored in instance state
and handed back to the destroy workflow, and ip_address becomes the
address the transport connects to. A workflow that completes without
those two fails the create, since there would be nothing to connect to
and nothing to tear down later.
Instance Attribute Summary collapse
-
#workflow_id ⇒ String?
Id of the workflow currently being run, used to disambiguate when several workflows share a name.
-
#workflow_name ⇒ String
Name of the workflow currently being run.
Instance Method Summary collapse
-
#create(state) ⇒ void
Runs the create workflow and waits for the server to be reachable.
-
#destroy(state) ⇒ void
Runs the destroy workflow for the server named in state.
-
#execute_create_workflow(state) ⇒ void
Runs the create workflow and records what it produced.
-
#execute_destroy_workflow(state) ⇒ void
Runs the destroy workflow, passing it the stored
server_id. -
#execute_workflow ⇒ void
Submits the current workflow for execution.
-
#name ⇒ String
The driver's display name in
kitchen list. -
#output_parameter_empty?(key) ⇒ Boolean
True when the parameter is missing or empty.
-
#output_parameter_value(key) ⇒ String
The parameter's value, stringified.
-
#output_parameters ⇒ Hash{String => VcoWorkflows::WorkflowParameter}
Output parameters from the finished workflow run.
-
#set_workflow_parameters(data) ⇒ void
Sets input parameters on the current workflow.
-
#set_workflow_vars(name, id) ⇒ void
Points the driver at a different workflow.
-
#validate_create_output_parameters! ⇒ void
Checks that the create workflow returned what the driver needs.
-
#verify_ssl? ⇒ Boolean
Whether to verify the vRO server's TLS certificate.
-
#vro_client ⇒ VcoWorkflows::Workflow
Client for the workflow named by #workflow_name and #workflow_id.
-
#vro_config ⇒ VcoWorkflows::Config
Connection settings for the vRO API.
-
#wait_for_server(state) ⇒ void
Waits for the transport to accept a connection.
-
#wait_for_workflow ⇒ void
Polls until the running workflow's token is no longer alive.
-
#workflow_successful? ⇒ Boolean
Whether the workflow run reached the "completed" state.
Instance Attribute Details
#workflow_id ⇒ String?
Returns id of the workflow currently being run, used to disambiguate when several workflows share a name.
46 |
# File 'lib/kitchen/driver/vro.rb', line 46 attr_accessor :workflow_name, :workflow_id |
#workflow_name ⇒ String
Returns name of the workflow currently being run.
46 47 48 |
# File 'lib/kitchen/driver/vro.rb', line 46 def workflow_name @workflow_name end |
Instance Method Details
#create(state) ⇒ void
This method returns an undefined value.
Runs the create workflow and waits for the server to be reachable.
Returns immediately if state already names a server, so a re-run does not create a second one.
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/kitchen/driver/vro.rb', line 77 def create(state) return unless state[:server_id].nil? info("Executing the create-server workflow...") execute_create_workflow(state) info("Server #{state[:hostname]} (#{state[:server_id]}) created. Waiting for it to be ready...") wait_for_server(state) info("Server #{state[:hostname]} (#{state[:server_id]}) ready.") end |
#destroy(state) ⇒ void
This method returns an undefined value.
Runs the destroy workflow for the server named in state.
92 93 94 95 96 97 98 |
# File 'lib/kitchen/driver/vro.rb', line 92 def destroy(state) return if state[:server_id].nil? info("Executing the destroy-server workflow for #{state[:hostname]} (#{state[:server_id]})...") execute_destroy_workflow(state) info("Server #{state[:hostname]} (#{state[:server_id]}) destroyed.") end |
#execute_create_workflow(state) ⇒ void
This method returns an undefined value.
Runs the create workflow and records what it produced.
153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/kitchen/driver/vro.rb', line 153 def execute_create_workflow(state) set_workflow_vars(config[:create_workflow_name], config[:create_workflow_id]) set_workflow_parameters(config[:create_workflow_parameters]) execute_workflow wait_for_workflow raise "The workflow did not complete successfully. Check the vRO UI for more info." unless workflow_successful? validate_create_output_parameters! state[:server_id] = output_parameter_value("server_id") state[:hostname] = output_parameter_value("ip_address") end |
#execute_destroy_workflow(state) ⇒ void
This method returns an undefined value.
Runs the destroy workflow, passing it the stored server_id.
172 173 174 175 176 177 178 179 180 |
# File 'lib/kitchen/driver/vro.rb', line 172 def execute_destroy_workflow(state) set_workflow_vars(config[:destroy_workflow_name], config[:destroy_workflow_id]) set_workflow_parameters(config[:destroy_workflow_parameters]) vro_client.parameter("server_id", state[:server_id]) execute_workflow wait_for_workflow raise "The workflow did not complete successfully. Check the vRO UI for more info." unless workflow_successful? end |
#execute_workflow ⇒ void
This method returns an undefined value.
Submits the current workflow for execution.
187 188 189 190 191 192 193 194 195 |
# File 'lib/kitchen/driver/vro.rb', line 187 def execute_workflow vro_client.execute rescue RestClient::BadRequest => e error("The workflow execution request failed: #{e.response}") raise rescue => e error("The workflow execution request failed: #{e.}") raise end |
#name ⇒ String
Returns the driver's display name in kitchen list.
65 66 67 |
# File 'lib/kitchen/driver/vro.rb', line 65 def name "vRO" end |
#output_parameter_empty?(key) ⇒ Boolean
Returns true when the parameter is missing or empty.
255 256 257 |
# File 'lib/kitchen/driver/vro.rb', line 255 def output_parameter_empty?(key) output_parameter_value(key).nil? || output_parameter_value(key).empty? end |
#output_parameter_value(key) ⇒ String
Returns the parameter's value, stringified.
249 250 251 |
# File 'lib/kitchen/driver/vro.rb', line 249 def output_parameter_value(key) output_parameters[key].value.to_s end |
#output_parameters ⇒ Hash{String => VcoWorkflows::WorkflowParameter}
Output parameters from the finished workflow run.
243 244 245 |
# File 'lib/kitchen/driver/vro.rb', line 243 def output_parameters @output_parameters ||= vro_client.token.output_parameters end |
#set_workflow_parameters(data) ⇒ void
This method returns an undefined value.
Sets input parameters on the current workflow.
234 235 236 237 238 |
# File 'lib/kitchen/driver/vro.rb', line 234 def set_workflow_parameters(data) # rubocop:disable Style/AccessorMethodName data.each do |key, value| vro_client.parameter(key.to_s, value) end end |
#set_workflow_vars(name, id) ⇒ void
This method returns an undefined value.
Points the driver at a different workflow.
Clears the memoized client, which is what makes it safe to run the destroy workflow after the create workflow in the same process.
140 141 142 143 144 |
# File 'lib/kitchen/driver/vro.rb', line 140 def set_workflow_vars(name, id) @vro_client = nil @workflow_name = name @workflow_id = id end |
#validate_create_output_parameters! ⇒ void
This method returns an undefined value.
Checks that the create workflow returned what the driver needs.
263 264 265 266 267 268 269 |
# File 'lib/kitchen/driver/vro.rb', line 263 def validate_create_output_parameters! raise "The workflow output did not contain a server_id and ip_address parameter." unless output_parameters.key?("server_id") && output_parameters.key?("ip_address") raise "The server_id parameter was empty." if output_parameter_empty?("server_id") raise "The ip_address parameter was empty." if output_parameter_empty?("ip_address") end |
#verify_ssl? ⇒ Boolean
Returns whether to verify the vRO server's TLS certificate.
128 129 130 |
# File 'lib/kitchen/driver/vro.rb', line 128 def verify_ssl? !config[:vro_disable_ssl_verify] end |
#vro_client ⇒ VcoWorkflows::Workflow
Client for the workflow named by #workflow_name and #workflow_id.
Memoized, and reset by #set_workflow_vars, so switching from the create workflow to the destroy workflow builds a fresh client rather than reusing the previous workflow's.
119 120 121 122 123 124 125 |
# File 'lib/kitchen/driver/vro.rb', line 119 def vro_client @vro_client ||= VcoWorkflows::Workflow.new( workflow_name, id: workflow_id, config: vro_config ) end |
#vro_config ⇒ VcoWorkflows::Config
Connection settings for the vRO API.
103 104 105 106 107 108 109 110 |
# File 'lib/kitchen/driver/vro.rb', line 103 def vro_config @vro_config ||= VcoWorkflows::Config.new( url: config[:vro_base_url], username: config[:vro_username], password: config[:vro_password], verify_ssl: verify_ssl? ) end |
#wait_for_server(state) ⇒ void
This method returns an undefined value.
Waits for the transport to accept a connection.
A server that never becomes reachable is destroyed before the error is re-raised, so a failed create does not leave a machine behind.
222 223 224 225 226 227 228 |
# File 'lib/kitchen/driver/vro.rb', line 222 def wait_for_server(state) instance.transport.connection(state).wait_until_ready rescue error("Server #{state[:hostname]} (#{state[:server_id]}) not reachable. Destroying server...") destroy(state) raise end |
#wait_for_workflow ⇒ void
This method returns an undefined value.
Polls until the running workflow's token is no longer alive.
201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/kitchen/driver/vro.rb', line 201 def wait_for_workflow wait_time = config[:request_timeout] Timeout.timeout(wait_time) do loop do token = vro_client.token break unless token.alive? sleep 2 end end rescue Timeout::Error raise Timeout::Error, "Workflow did not complete in #{wait_time} seconds. Please check the vRO UI for more information." end |
#workflow_successful? ⇒ Boolean
Returns whether the workflow run reached the "completed" state.
272 273 274 |
# File 'lib/kitchen/driver/vro.rb', line 272 def workflow_successful? vro_client.token.state == "completed" end |