Module: Puppet_X::Elastic

Defined in:
lib/puppet_x/elastic/hash.rb,
lib/puppet_x/elastic/deep_to_i.rb,
lib/puppet_x/elastic/deep_to_s.rb,
lib/puppet_x/elastic/deep_implode.rb,
lib/puppet_x/elastic/es_versioning.rb,
lib/puppet_x/elastic/plugin_parsing.rb,
lib/puppet_x/elastic/asymmetric_compare.rb

Overview

Custom Elastic functions

Defined Under Namespace

Modules: SortedHash Classes: EsVersioning

Class Method Summary collapse

Class Method Details

.asymmetric_compare(should_val, is_val) ⇒ Object

Certain Elasticsearch APIs return fields that are present in responses but not present when sending API requests such as creation time, and so on. When comparing desired settings and extant settings, only indicate that a value differs from another when user-desired settings differ from existing settings - we ignore keys that exist in the response that aren’t being explicitly controlled by Puppet.



12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/puppet_x/elastic/asymmetric_compare.rb', line 12

def self.asymmetric_compare(should_val, is_val)
  should_val.reduce(true) do |is_synced, (should_key, should_setting)|
    if is_val.key? should_key
      if is_val[should_key].is_a? Hash
        asymmetric_compare(should_setting, is_val[should_key])
      else
        is_synced && is_val[should_key] == should_setting
      end
    else
      is_synced && true
    end
  end
end

.deep_implode(hash) ⇒ Object

Recursively implode a hash into dot-delimited structure of Hash keys/values.



8
9
10
11
12
# File 'lib/puppet_x/elastic/deep_implode.rb', line 8

def self.deep_implode(hash)
  ret = {}
  implode ret, hash
  ret
end

.deep_to_i(obj) ⇒ Object

This ugly hack is required due to the fact Puppet passes in the puppet-native hash with stringified numerics, which causes the decoded JSON from the Elasticsearch API to be seen as out-of-sync when the parsed template hash is compared against the puppet hash.



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/puppet_x/elastic/deep_to_i.rb', line 10

def self.deep_to_i(obj)
  if obj.is_a?(String) && obj =~ %r{^-?[0-9]+$}
    obj.to_i
  elsif obj.is_a? Array
    obj.map { |element| deep_to_i(element) }
  elsif obj.is_a? Hash
    obj.merge(obj) { |_key, val| deep_to_i(val) }
  else
    obj
  end
end

.deep_to_s(obj) ⇒ Object

When given a hash, this method recurses deeply into all values to convert any that aren’t data structures into strings. This is necessary when comparing results from Elasticsearch API calls, because values like integers and booleans are in string form.



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/puppet_x/elastic/deep_to_s.rb', line 10

def self.deep_to_s(obj)
  if obj.is_a? Array
    obj.map { |element| deep_to_s(element) }
  elsif obj.is_a? Hash
    obj.merge(obj) { |_key, val| deep_to_s(val) }
  elsif (!obj.is_a? String) && ![true, false].include?(obj) && obj.respond_to?(:to_s)
    obj.to_s
  else
    obj
  end
end

.implode(new_hash, hash, path = []) ⇒ Object

Recursively descend into hash values, flattening the key structure into dot-delimited keyed Hash.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/puppet_x/elastic/deep_implode.rb', line 16

def self.implode(new_hash, hash, path = [])
  hash.sort_by { |k, _v| k.length }.reverse.each do |key, value|
    new_path = path + [key]
    case value
    when Hash
      implode(new_hash, value, new_path)
    else
      new_key = new_path.join('.')
      if value.is_a?(Array) \
          && new_hash.key?(new_key) \
          && new_hash[new_key].is_a?(Array)
        new_hash[new_key] += value
      else
        new_hash[new_key] ||= value
      end
    end
  end
end

.plugin_name(raw_name) ⇒ Object



8
9
10
# File 'lib/puppet_x/elastic/plugin_parsing.rb', line 8

def self.plugin_name(raw_name)
  plugin_split(raw_name, 1)
end

.plugin_split(original_string, position, soft_fail = true) ⇒ Object

Attempt to guess at the plugin’s final directory name



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/puppet_x/elastic/plugin_parsing.rb', line 20

def self.plugin_split(original_string, position, soft_fail = true)
  # Try both colon (maven) and slash-delimited (github/elastic.co) names
  %w[/ :].each do |delimiter|
    parts = original_string.split(delimiter)
    # If the string successfully split, assume we found the right format
    return parts[position].gsub(%r{(elasticsearch-|es-)}, '') unless parts[position].nil?
  end

  unless soft_fail
    raise(
      ElasticPluginParseFailure,
      "could not find element '#{position}' in #{original_string}"
    )
  end

  original_string
end

.plugin_version(raw_name) ⇒ Object



12
13
14
15
16
17
# File 'lib/puppet_x/elastic/plugin_parsing.rb', line 12

def self.plugin_version(raw_name)
  v = plugin_split(raw_name, 2, false).gsub(%r{^[^0-9]*}, '')
  raise ElasticPluginParseFailure, "could not parse version, got '#{v}'" if v.empty?

  v
end