Module: ChefApply::CLI::Validation

Included in:
ChefApply::CLI
Defined in:
lib/chef_apply/cli/validation.rb

Constant Summary collapse

PROPERTY_MATCHER =
/^([a-zA-Z0-9_]+)=(.+)$/.freeze
CB_MATCHER =
'[\w\-]+'.freeze

Instance Method Summary collapse

Instance Method Details

#properties_from_string(string_props) ⇒ Object

Convert properties in the form k1=v1,k2=v2,kn=vn into a hash, while validating correct form and format



56
57
58
59
60
61
62
63
64
# File 'lib/chef_apply/cli/validation.rb', line 56

def properties_from_string(string_props)
  properties = {}
  string_props.each do |a|
    key, value = PROPERTY_MATCHER.match(a)[1..-1]
    value = transform_property_value(value)
    properties[key] = value
  end
  properties
end

#transform_property_value(value) ⇒ Object

Incoming properties are always read as a string from the command line. Depending on their type we should transform them so we do not try and pass a string to a resource property that expects an integer or boolean.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/chef_apply/cli/validation.rb', line 69

def transform_property_value(value)
  case value
  when /^0/
    # when it is a zero leading value like "0777" don't turn
    # it into a number (this is a mode flag)
    value
  when /^\d+$/
    value.to_i
  when /^\d+\.\d*$/, /^\d*\.\d+$/
    value.to_f
  when /^[:].+$/
    value.split(":").last.to_sym
  when /true/i
    true
  when /false/i
    false
  else
    value
  end
end

#validate_params(params) ⇒ Object

The first param is always hostname. Then we either have

  1. A recipe designation

  2. A resource type and resource name followed by any properties



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/chef_apply/cli/validation.rb', line 29

def validate_params(params)
  if params.size < 2
    raise OptionValidationError.new("CHEFVAL002", self)
  end

  if params.size == 2
    # Trying to specify a recipe to run remotely, no properties
    cb = params[1]
    if File.exist?(cb)
      # This is a path specification, and we know it is valid
    elsif cb =~ /^#{CB_MATCHER}$/ || cb =~ /^#{CB_MATCHER}::#{CB_MATCHER}$/
      # They are specifying a cookbook as 'cb_name' or 'cb_name::recipe'
    else
      raise OptionValidationError.new("CHEFVAL004", self, cb)
    end
  elsif params.size >= 3
    properties = params[3..-1]
    properties.each do |property|
      unless property =~ PROPERTY_MATCHER
        raise OptionValidationError.new("CHEFVAL003", self, property)
      end
    end
  end
end