File: elasticsearch_template.rb

package info (click to toggle)
puppet-module-voxpupuli-elasticsearch 9.0.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,496 kB
  • sloc: ruby: 9,906; sh: 392; makefile: 4
file content (117 lines) | stat: -rw-r--r-- 3,819 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# frozen_string_literal: true

$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..'))

require 'puppet/file_serving/content'
require 'puppet/file_serving/metadata'

require 'puppet_x/elastic/deep_implode'
require 'puppet_x/elastic/deep_to_i'
require 'puppet_x/elastic/deep_to_s'
require 'puppet_x/elastic/elasticsearch_rest_resource'

Puppet::Type.newtype(:elasticsearch_template) do
  extend ElasticsearchRESTResource

  desc 'Manages Elasticsearch index templates.'

  ensurable

  newparam(:name, namevar: true) do
    desc 'Template name.'
  end

  newproperty(:content) do
    desc 'Structured content of template.'

    validate do |value|
      raise Puppet::Error, 'hash expected' unless value.is_a? Hash
    end

    munge do |value|
      # The Elasticsearch API will return default empty values for
      # order, aliases, and mappings if they aren't defined in the
      # user mapping, so we need to set defaults here to keep the
      # `in` and `should` states consistent if the user hasn't
      # provided any.
      #
      # The value is first stringified, then integers are parse out as
      # necessary, since the Elasticsearch API enforces some fields to be
      # integers.
      #
      # We also need to fully qualify index settings, since users
      # can define those with the index json key absent, but the API
      # always fully qualifies them.
      { 'order' => 0, 'aliases' => {}, 'mappings' => {} }.merge(
        Puppet_X::Elastic.deep_to_i(
          Puppet_X::Elastic.deep_to_s(
            value.tap do |val|
              if val.key? 'settings'
                val['settings']['index'] = {} unless val['settings'].key? 'index'
                (val['settings'].keys - ['index']).each do |setting|
                  new_key = if setting.start_with? 'index.'
                              setting[6..]
                            else
                              setting
                            end
                  val['settings']['index'][new_key] = \
                    val['settings'].delete setting
                end
              end
            end
          )
        )
      )
    end

    def insync?(value)
      Puppet_X::Elastic.deep_implode(value) == \
        Puppet_X::Elastic.deep_implode(should)
    end
  end

  newparam(:source) do
    desc 'Puppet source to file containing template contents.'

    validate do |value|
      raise Puppet::Error, 'string expected' unless value.is_a? String
    end
  end

  # rubocop:disable Style/SignalException
  validate do
    # Ensure that at least one source of template content has been provided
    if self[:ensure] == :present
      fail Puppet::ParseError, '"content" or "source" required' \
        if self[:content].nil? && self[:source].nil?

      if !self[:content].nil? && !self[:source].nil?
        fail(
          Puppet::ParseError,
          "'content' and 'source' cannot be simultaneously defined"
        )
      end
    end

    # If a source was passed, retrieve the source content from Puppet's
    # FileServing indirection and set the content property
    unless self[:source].nil?
      fail(format('Could not retrieve source %s', self[:source])) unless Puppet::FileServing::Metadata.indirection.find(self[:source])

      tmp = if !catalog.nil? \
                && catalog.respond_to?(:environment_instance)
              Puppet::FileServing::Content.indirection.find(
                self[:source],
                environment: catalog.environment_instance
              )
            else
              Puppet::FileServing::Content.indirection.find(self[:source])
            end

      fail(format('Could not find any content at %s', self[:source])) unless tmp

      self[:content] = JSON.parse(tmp.content)
    end
  end
  # rubocop:enable Style/SignalException
end