class VcoWorkflows::Workflow

Class to represent a Workflow as presented by vCenter Orchestrator.

Attributes

description[R]

Workflow description @return [String] workflow description

execution_id[R]

Workflow execution ID @return [String]

id[R]

Workflow GUID @return [String] workflow GUID

input_parameters[R]

Workflow Input Parameters: Hash of WorkflowParameters, keyed by name @return [Hash<VcoWorkflows::WorkflowParameter>]

name[R]

Workflow name @return [String] workflow name

output_parameters[R]

Workflow Output Parameters: Hash of WorkflowParameters, keyed by name @return [Hash<VcoWorkflows::WorkflowParameter>]

service[RW]

Workflow Service in use by this Workflow @return [VcoWorkflows::WorkflowService]

source_json[R]

Workflow source JSON @return [String]

version[R]

Workflow version @return [String] workflow version

Public Class Methods

new(name = nil, options = {}) click to toggle source

Create a Workflow object given vCenter Orchestrator's JSON description

When passed `url`, `username` and `password` the necessary session and service objects will be created behind the scenes. Alternatively you can pass in a Config or a WorkflowService object if you have constructed them yourself. You may also pass in the path to a configuration file (`config_file`).

@param [String] name Name of the requested workflow @param [Hash] options Hash of options:

- id: (String) GUID for the Workflow
- url: (String) vCO REST API URL
- username: (String) User to authenticate as
- password: (String) Password for username
- verify_ssl: (Boolean) Perform TLS/SSL certificate validation
- service: (VcoWorkflows::WorkflowService) WorkflowService to use for communicating to vCO
- config: (VcoWorkflows::Config) Configuration object to use for this workflow's session
- config_file: (String) Path to load configuration file from for this workflow's session

@return [VcoWorkflows::Workflow]

# File lib/vcoworkflows/workflow.rb, line 71
def initialize(name = nil, options = {})
  @options = {
    id: nil,
    url: nil,
    username: nil,
    password: nil,
    verify_ssl: true,
    service: nil,
    config: nil,
    config_file: nil
  }.merge(options)

  config = nil
  @service = nil
  @execution_id = nil

  # -------------------------------------------------------------
  # Figure out how to get a workflow service. If I can't, I die.
  # (DUN dun dun...)

  if options[:service]
    @service = options[:service]
  else
    # If we were given a configuration object, use it
    # If we were given a config file path, use it
    # If we have a url, username and password, use them
    # If all we have is a URL, try anyway, maybe we'll get username and
    # password from ENV values (hey, it might work...)
    if @options[:config]
      config = @options[:config]
    elsif @options[:config_file]
      config = VcoWorkflows::Config.new(config_file: @options[:config_file])
    elsif @options[:url] && @options[:username] && @options[:password]
      config = VcoWorkflows::Config.new(url:        @options[:url],
                                        username:   @options[:username],
                                        password:   @options[:password],
                                        verify_ssl: @options[:verify_ssl])
    elsif @options[:url]
      config = VcoWorkflows::Config.new(url:        @options[:url],
                                        verify_ssl: @options[:verify_ssl])
    end

    # If we got a config object above, great. If it's still nil, VcoSession
    # will accept that and try to load the default config file.
    session  = VcoWorkflows::VcoSession.new(config: config)
    @service = VcoWorkflows::WorkflowService.new(session)
  end

  raise(IOError, 'Unable to create/use a WorkflowService!') if @service.nil?

  # -------------------------------------------------------------
  # Retrieve the workflow and parse it into a data structure
  # If we're given both a name and ID, prefer the id
  workflow_json = if @options[:id]
                    @service.get_workflow_for_id(@options[:id])
                  else
                    @service.get_workflow_for_name(name)
                  end
  workflow_data = JSON.parse(workflow_json)

  # Set up the attributes if they exist in the data json,
  # otherwise nil them
  @id          = workflow_data.key?('id')          ? workflow_data['id']          : nil
  @name        = workflow_data.key?('name')        ? workflow_data['name']        : nil
  @version     = workflow_data.key?('version')     ? workflow_data['version']     : nil
  @description = workflow_data.key?('description') ? workflow_data['description'] : nil

  # Process the input parameters
  if workflow_data.key?('input-parameters')
    @input_parameters = Workflow.parse_parameters(workflow_data['input-parameters'])
  else
    @input_parameters = {}
  end

  # Identify required input_parameters
  wfpres = VcoWorkflows::WorkflowPresentation.new(@service, @id)
  wfpres.required.each do |req_param|
    @input_parameters[req_param].required(true)
  end

  # Process the output parameters
  if workflow_data.key?('output-parameters')
    @output_parameters = Workflow.parse_parameters(workflow_data['output-parameters'])
  else
    @output_parameters = {}
  end
end
parse_failure(error, wfparam, parameter) click to toggle source

Process exceptions raised in parse_parameters by bravely ignoring them

and forging ahead blindly!

@param [Exception] error

# File lib/vcoworkflows/workflow.rb, line 223
def self.parse_failure(error, wfparam, parameter)
  $stderr.puts "\nWhoops!"
  $stderr.puts "Ran into a problem parsing parameter #{wfparam.name} (#{wfparam.type})!"
  $stderr.puts "Source data: #{JSON.pretty_generate(parameter)}\n"
  $stderr.puts error.message
  $stderr.puts "\nBravely forging on and ignoring parameter #{wfparam.name}!"
end
parse_parameters(parameter_data = []) click to toggle source

Parse json parameters and return a nice hash @param [Array<Hash>] parameter_data Array of parameter data hashes by vCO @return [Hash]

# File lib/vcoworkflows/workflow.rb, line 190
def self.parse_parameters(parameter_data = [])
  wfparams = {}
  parameter_data.each do |parameter|
    wfparam = VcoWorkflows::WorkflowParameter.new(parameter['name'], parameter['type'])
    if parameter['value']
      if wfparam.type.eql?('Array')
        value = []
        begin
          parameter['value'][wfparam.type.downcase]['elements'].each do |element|
            value << element[element.keys.first]['value']
          end
        rescue StandardError => error
          parse_failure(error, wfparam, parameter)
        end
      else
        begin
          value = parameter['value'][parameter['value'].keys.first]['value']
        rescue StandardError => error
          parse_failure(error, wfparam, parameter)
        end
      end
      value = nil if value.eql?('null')
      wfparam.set(value)
    end
    wfparams[parameter['name']] = wfparam
  end
  wfparams
end

Public Instance Methods

execute(workflow_service = nil) click to toggle source

Execute this workflow @param [VcoWorkflows::WorkflowService] workflow_service @return [String] Workflow Execution ID

# File lib/vcoworkflows/workflow.rb, line 308
def execute(workflow_service = nil)
  # If we're not given an explicit workflow service for this execution
  # request, use the one defined when we were created.
  workflow_service = @service if workflow_service.nil?
  # If we still have a nil workflow_service, go home.
  raise(IOError, ERR[:no_workflow_service_defined]) if workflow_service.nil?
  # Make sure we didn't forget any required parameters
  verify_parameters
  # Let's get this thing running!
  @execution_id = workflow_service.execute_workflow(@id, input_parameter_json)
end
executions() click to toggle source

Get a list of all the executions of this workflow. Wrapper for VcoWorkflows::WorkflowService#get_execution_list @return [Hash]

# File lib/vcoworkflows/workflow.rb, line 323
def executions
  @service.get_execution_list(@id)
end
get_parameter(parameter_name) click to toggle source

Get the value for an input parameter @deprecated Use {#parameter} to retrieve the

{VcoWorkflows::WorkflowParameter} object, instead

@param [String] parameter_name Name of the input parameter

whose value to get

@return [Object]

# File lib/vcoworkflows/workflow.rb, line 301
def get_parameter(parameter_name)
  parameter(parameter_name).value
end
log(execution_id = nil) click to toggle source

Return logs for the given execution @param [String] execution_id optional execution id to get logs for @return [VcoWorkflows::WorkflowExecutionLog]

# File lib/vcoworkflows/workflow.rb, line 338
def log(execution_id = nil)
  execution_id = @execution_id if execution_id.nil?
  log_json = @service.get_log(@id, execution_id)
  VcoWorkflows::WorkflowExecutionLog.new(log_json)
end
parameter(parameter_name, parameter_value = nil) click to toggle source

Get the parameter object named. If a value is provided, set the value and return the parameter object.

To get a parameter value, use parameter(parameter_name).value

@param [String] parameter_name Name of the parameter to get @param [Object, nil] parameter_value Optional value for parameter. @return [VcoWorkflows::WorkflowParameter] The resulting WorkflowParameter

rubocop:disable Metrics/MethodLength

# File lib/vcoworkflows/workflow.rb, line 250
def parameter(parameter_name, parameter_value = nil)
  unless parameter_value.nil?
    if @input_parameters.key?(parameter_name)
      @input_parameters[parameter_name].set parameter_value
    else
      $stderr.puts "\nAttempted to set a value for a non-existent WorkflowParameter!"
      $stderr.puts "It appears that there is no parameter \"#{parameter}\"."
      $stderr.puts "Valid parameter names are: #{@input_parameters.keys.join(', ')}"
      $stderr.puts ''
      raise(IOError, ERR[:no_such_parameter])
    end
  end
  @input_parameters[parameter_name]
end
parameter=(wfparameter) click to toggle source

Set a parameter with a WorkflowParameter object @param [VcoWorkflows::WorkflowParameter] wfparameter New parameter

# File lib/vcoworkflows/workflow.rb, line 268
def parameter=(wfparameter)
  @input_parameters[wfparameter.name] = wfparameter
end
parameter?(parameter_name) click to toggle source

Determine whether a parameter has been set @param [String] parameter_name Name of the parameter to check @return [Boolean]

# File lib/vcoworkflows/workflow.rb, line 275
def parameter?(parameter_name)
  parameter(parameter_name).set?
end
parameters=(parameter_hash) click to toggle source

Set all input parameters using the given hash @param [Hash] parameter_hash input parameter values keyed by

input_parameter name
# File lib/vcoworkflows/workflow.rb, line 282
def parameters=(parameter_hash)
  parameter_hash.each { |name, value| parameter(name, value) }
end
password() click to toggle source

vCO password used when creating this workflow object @return [String]

# File lib/vcoworkflows/workflow.rb, line 174
def password
  options[:password]
end
required_parameters() click to toggle source

Get an array of the names of all the required input parameters @return [Hash] Hash of WorkflowParameter input parameters which

are required for this workflow
# File lib/vcoworkflows/workflow.rb, line 234
def required_parameters
  required = {}
  @input_parameters.each_value { |v| required[v.name] = v if v.required? }
  required
end
set_parameter(parameter_name, value) click to toggle source

Set a parameter to a value. @deprecated Use {#parameter} instead @param [String] parameter_name name of the parameter to set @param [Object] value value to set @return [VcoWorkflows::WorkflowParameter] The resulting WorkflowParameter

# File lib/vcoworkflows/workflow.rb, line 291
def set_parameter(parameter_name, value)
  parameter(parameter_name, value)
end
to_s() click to toggle source

Stringify the workflow @return [String]

# File lib/vcoworkflows/workflow.rb, line 348
def to_s
  string =  "Workflow:    #{@name}\n"
  string << "ID:          #{@id}\n"
  string << "Description: #{@description}\n"
  string << "Version:     #{@version}\n"

  string << "\nInput Parameters:\n"
  unless @input_parameters.empty?
    @input_parameters.each_value { |wf_param| string << " #{wf_param}" }
  end

  string << "\nOutput Parameters:" << "\n"
  unless @output_parameters.empty?
    @output_parameters.each_value { |wf_param| string << " #{wf_param}" }
  end

  # Assert
  string
end
token(execution_id = nil) click to toggle source

Return a WorkflowToken @param [String] execution_id optional execution id to get logs for @return [VcoWorkflows::WorkflowToken]

# File lib/vcoworkflows/workflow.rb, line 330
def token(execution_id = nil)
  execution_id = @execution_id if execution_id.nil?
  VcoWorkflows::WorkflowToken.new(@service, @id, execution_id)
end
url() click to toggle source

vCO API URL used when creating this workflow @return [String]

# File lib/vcoworkflows/workflow.rb, line 162
def url
  options[:url]
end
username() click to toggle source

vCO user name used when creating this workflow object @return [String]

# File lib/vcoworkflows/workflow.rb, line 168
def username
  options[:username]
end
verify_ssl?() click to toggle source

Verify SSL? @return [Boolean]

# File lib/vcoworkflows/workflow.rb, line 180
def verify_ssl?
  options[:verify_ssl]
end

Private Instance Methods

input_parameter_json() click to toggle source

Convert the input parameters to a JSON document @return [String]

# File lib/vcoworkflows/workflow.rb, line 373
def input_parameter_json
  tmp_params = []
  @input_parameters.each_value { |v| tmp_params << v.as_struct if v.set? }
  param_struct = { parameters: tmp_params }
  param_struct.to_json
end
verify_parameters() click to toggle source

Verify that all mandatory input parameters have values

# File lib/vcoworkflows/workflow.rb, line 381
def verify_parameters
  required_parameters.each do |name, wfparam|
    # rubocop:disable Style/Next
    if wfparam.required? && (wfparam.value.nil? || wfparam.value.to_s.empty?)
      raise(
        IOError,
        ERR[:param_verify_failed] << "#{name} required but not present."
      )
    end
    # rubocop:enable Style/Next
  end
end