Class: MCollective::Util::Playbook::Inputs

Inherits:
Object
  • Object
show all
Defined in:
lib/mcollective/util/playbook/inputs.rb

Instance Method Summary collapse

Constructor Details

#initialize(playbook) ⇒ Inputs

Returns a new instance of Inputs.



5
6
7
8
# File 'lib/mcollective/util/playbook/inputs.rb', line 5

def initialize(playbook)
  @playbook = playbook
  @inputs = {}
end

Instance Method Details

#[](input) ⇒ Object

Retrieves the value for a specific input

Parameters:

  • input (String)

    input name

Returns:

  • (Object)

Raises:

  • (StandardError)

    for unknown inputs



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/mcollective/util/playbook/inputs.rb', line 172

def [](input)
  raise("Unknown input %s" % input) unless include?(input)

  props = @inputs[input][:properties]

  if @inputs[input].include?(:value)
    Log.debug("Resolving %s as static" % [input])
    @inputs[input][:value]
  elsif props.include?("data")
    Log.debug("Resolving %s as dynamic" % [input])
    lookup_from_datastore(input)
  elsif props.include?("default")
    Log.debug("Resolving %s as default" % [input])
    props["default"]
  else
    raise("Input %s has no value, data source or default" % [input])
  end
end

#add_cli_options(application, set_required) ⇒ Object

Creates options for each input in the application

Parameters:

  • application (MCollective::Application)
  • set_required (Boolean)

    when true required inputs will be required on the CLI

Raises:

  • (StandardError)

    for invalidly defined inputs



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mcollective/util/playbook/inputs.rb', line 38

def add_cli_options(application, set_required)
  @inputs.each do |input, props|
    i_props = props[:properties]

    next if i_props["dynamic"]

    type = case i_props["type"]
           when :string, "String"
             String
           when :fixnum, "Fixnum", "Integer"
             Integer
           when :float, "Float"
             Float
           when :numeric, "Numeric"
             Numeric
           when :array, ":array", "Array"
             :array
           when :bool, ":bool", ":boolean", "Boolean"
             :boolean
           else
             raise("Invalid input type %s given for input %s" % [i_props["type"], input])
           end

    description = "%s (%s) %s" % [i_props["description"], type, i_props["default"] ? ("default: %s" % i_props["default"]) : ""]

    option_params = {
      :description => description,
      :arguments => ["--%s %s" % [input.downcase, input.upcase]],
      :type => type
    }

    option_params[:arguments] = ["--%s" % input.downcase] if type == :boolean

    option_params[:required] = i_props["required"] if set_required && !i_props.include?("data")

    application.class.option(input, option_params)
  end
end

#dynamic?(input) ⇒ Boolean

Checks if a input is dynamic

Dynaic inputs are those where the data is sourced from a data source, an input that has a data source defined and had a specific input given will not be dynamic

Returns:

  • (Boolean)


108
109
110
# File 'lib/mcollective/util/playbook/inputs.rb', line 108

def dynamic?(input)
  @inputs[input][:dynamic]
end

#dynamic_keysArray<String>

List of known input names that have dynamic values

Returns:



27
28
29
30
31
# File 'lib/mcollective/util/playbook/inputs.rb', line 27

def dynamic_keys
  @inputs.select do |_, props|
    props[:dynamic]
  end.keys
end

#from_hash(data) ⇒ Object



248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/mcollective/util/playbook/inputs.rb', line 248

def from_hash(data)
  data.each do |input, props|
    props["required"] = true unless props.include?("required")

    Log.debug("Loading input %s" % [input])

    @inputs[input] = {
      :properties => props,
      :dynamic => props.include?("data")
    }
  end

  self
end

#include?(input) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/mcollective/util/playbook/inputs.rb', line 112

def include?(input)
  @inputs.include?(input)
end

#input_properties(input) ⇒ Hash

Retrieves the properties for a specific input

Parameters:

  • input (String)

    input name

Returns:

  • (Hash)

Raises:

  • (StandardError)

    for unknown inputs



196
197
198
199
200
201
202
# File 'lib/mcollective/util/playbook/inputs.rb', line 196

def input_properties(input)
  if include?(input)
    @inputs[input][:properties]
  else
    raise("Unknown input %s" % input)
  end
end

#keysArray<String>

List of known input names

Returns:



13
14
15
# File 'lib/mcollective/util/playbook/inputs.rb', line 13

def keys
  @inputs.keys
end

#lookup_from_datastore(input) ⇒ Object

Looks up data from a datastore, returns default when not found

Parameters:

  • input (String)

    input name

Returns:

  • (Object)

    value from the ds

Raises:

  • (StandardError)

    for invalid inputs and ds errors



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/mcollective/util/playbook/inputs.rb', line 121

def lookup_from_datastore(input)
  raise("Unknown input %s" % input) unless include?(input)

  properties = @inputs[input][:properties]

  value = @playbook.data_stores.read(properties["data"])
  validate_data(input, value)

  value
rescue
  raise("Could not resolve %s for input %s: %s: %s" % [properties["data"], input, $!.class, $!.to_s]) unless properties.include?("default")

  Log.warn("Could not find %s, returning default value" % properties["data"])

  properties["default"]
end

#prepare(data = {}) ⇒ void

This method returns an undefined value.

Attempts to find values for all declared inputs

During tests saving to the ds can be skipped by setting

Parameters:

  • data (Hash) (defaults to: {})

    input data from CLI etc

Raises:

  • (StandardError)

    when required data could not be found

  • (StandardError)

    when validation fails for any data



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/mcollective/util/playbook/inputs.rb', line 86

def prepare(data={})
  @inputs.each do |input, props|
    next unless data.include?(input)
    next if data[input].nil?
    next if props[:properties]["dynamic"]

    validate_data(input, data[input])

    props[:value] = data[input]
    props[:dynamic] = false
  end

  validate_requirements
end

#save_input_dataObject

Saves static property values in their associated data stores for any keys with save set



139
140
141
142
143
144
145
146
147
148
# File 'lib/mcollective/util/playbook/inputs.rb', line 139

def save_input_data
  @inputs.each do |input, props|
    next unless props[:properties]["save"]
    next unless props[:properties]["data"]
    next unless props[:value]
    next if props[:dynamic]

    save_to_datastore(input)
  end
end

#save_to_datastore(input) ⇒ Object

Saves the value of a input to the data entry associated with it

Parameters:

  • input (String)

    input name

Raises:

  • (StandardError)

    for invalid inputs and ds errors

See Also:



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/mcollective/util/playbook/inputs.rb', line 155

def save_to_datastore(input)
  raise("Unknown input %s" % input) unless include?(input)

  i_data = @inputs[input]

  raise("Input %s has no value, cannot store it" % input) unless i_data.include?(:value)

  Log.debug("Saving value for input %s to data item %s" % [input, i_data[:properties]["data"]])

  @playbook.data_stores.write(i_data[:properties]["data"], i_data[:value])
end

#static_keysArray<String>

List of known input names that have static values

Returns:



20
21
22
# File 'lib/mcollective/util/playbook/inputs.rb', line 20

def static_keys
  keys - dynamic_keys
end

#validate_data(input, value) ⇒ Object

TODO:

this seems quite limited, we have to expand with real needs

Validates a piece of data against an input

Parameters:

  • input (String)

    a valid input name

  • value (Object)

    a value to validate

Raises:

  • (StandardError)

    on validation failure



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/mcollective/util/playbook/inputs.rb', line 227

def validate_data(input, value)
  return unless @inputs[input][:properties].include?("validation")

  validator = @inputs[input][:properties]["validation"]

  case validator
  when /^:(.+)/
    validator = $1.intern
  when /^\/(.+)\/$/
    validator = Regexp.new($1)
  end

  Log.debug("Validating input %s using %s validator" % [input, validator])

  Validator.validate(value, validator)
rescue
  Log.warn("Attempt to validate input %s with validator %s failed: %s" % [input, validator, $!.to_s]) if validator

  raise("Failed to validate value for input %s: %s" % [input, $!.to_s])
end

#validate_requirementsObject

Checks all required inputs have values

Raises:

  • (StandardError)

    when not



207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/mcollective/util/playbook/inputs.rb', line 207

def validate_requirements
  invalid = @inputs.map do |input, props|
    next unless props[:properties]["required"]
    next if props[:properties].include?("data")

    unless props[:value]
      Log.warn("Input %s requires a value but has none or nil" % input)
      input
    end
  end.compact

  raise("Values were required but not given for inputs: %s" % invalid.join(", ")) unless invalid.empty?
end