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.



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

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.



6
7
8
9
10
# File 'lib/puppet_x/elastic/deep_implode.rb', line 6

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.



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

def self.deep_to_i(obj)
  if obj.is_a? String and obj =~ /^-?[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.



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

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 (not obj.is_a? String) and (not [true, false].include?(obj)) and 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.



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

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 \
          and new_hash.key? new_key \
          and 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



6
7
8
# File 'lib/puppet_x/elastic/plugin_parsing.rb', line 6

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



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

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(/(elasticsearch-|es-)/, '') unless parts[position].nil?
  end

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

  original_string
end

.plugin_version(raw_name) ⇒ Object



10
11
12
13
14
# File 'lib/puppet_x/elastic/plugin_parsing.rb', line 10

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