Module: Puppet::Icinga2::Utils

Defined in:
lib/puppet_x/icinga2/utils.rb

Class Method Summary collapse

Class Method Details

.attribute_types(attr) ⇒ Object



185
186
187
188
189
190
191
192
193
# File 'lib/puppet_x/icinga2/utils.rb', line 185

def self.attribute_types(attr)
  if attr =~ /^[a-zA-Z0-9_]+$/
    result = attr
  else
    result = "\"#{attr}\""
  end

  return result
end

.attributes(attrs, globals, consts, indent = 2) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/puppet_x/icinga2/utils.rb', line 167

def self.attributes(attrs, globals, consts, indent=2)

  def self.value_types(value)

    if value =~ /^-?\d+\.?\d*[dhms]?$/ || value =~ /^(true|false|null)$/ || value =~ /^!?(host|service|user)\./ || value =~ /^\{{2}.*\}{2}$/
      result = value
    else
      if $constants.index { |x| if $hash_attrs.include?(x) then value =~ /^!?(#{x})(\..+$|$)/ else value =~ /^!?#{x}$/ end }
        result = value
      else
        result = value.dump
      end
    end

    return result
  end


  def self.attribute_types(attr)
    if attr =~ /^[a-zA-Z0-9_]+$/
      result = attr
    else
      result = "\"#{attr}\""
    end

    return result
  end


  def self.parse(row)
    result = ''

    # parser is disabled
    if row =~ /^-:(.*)$/m
      return $1
    end

    if row =~ /^\{{2}(.+)\}{2}$/m
      # scan function
      result += "{{%s}}" % [ $1 ]
    elsif row =~ /^(.+)\s([\+-]|\*|\/|==|!=|&&|\|{2}|in)\s\{{2}(.+)\}{2}$/m
      # scan expression + function (function should contain expressions, but we donno parse it)
      result += "%s %s {{%s}}" % [ parse($1), $2, $3 ]
    elsif row =~ /^(.+)\s([\+-]|\*|\/|==|!=|&&|\|{2}|in)\s(.+)$/
      # scan expression
      result += "%s %s %s" % [ parse($1), $2, parse($3) ]
    else
      if row =~ /^(.+)\((.*)$/
        result += "%s(%s" % [ $1, $2.split(',').map {|x| parse(x.lstrip)}.join(', ') ]
      elsif row =~ /^(.*)\)(.+)?$/
        # closing bracket ) with optional access of an attribute e.g. '.arguments'
        result += "%s)%s" % [ $1.split(',').map {|x| parse(x.lstrip)}.join(', '), $2 ]
      elsif row =~ /^\((.*)$/
        result += "(%s" % [ parse($1) ]
      elsif row =~ /^\s*\[\s*(.*)\s*\]\s?(.+)?$/
        # parse array
        result += "[ %s]" % [ process_array($1.split(',')) ]
        result += " %s" % [ parse($2) ] if $2
      elsif row =~ /^\s*\{\s*(.*)\s*\}\s?(.+)?$/
        # parse hash
        result += "{\n%s}" % [ process_hash(Hash[$1.gsub(/\s*=>\s*|\s*,\s*/, ',').split(',').each_slice(2).to_a]) ]
        result += " %s" % [ parse($2) ] if $2
      else
        result += value_types(row.to_s.strip)
      end
    end

    return result.gsub(/" in "/, ' in ')
  end


  def self.process_array(items, indent=2)
    result = ''

    items.each do |value|
      if value.is_a?(Hash)
        result += "\n%s{\n%s%s}, " % [ ' ' * indent, process_hash(value, indent + 2), ' ' * indent ]
      elsif value.is_a?(Array)
        result += "[ %s], " % [ process_array(value, indent+2) ]
      else
        result += "%s, " % [ parse(value) ] if value
      end
    end

    return result
  end


  def self.process_hash(attrs, indent=2, level=3, prefix=' '*indent)
    result = ''
    attrs.each do |attr, value|
      if value.is_a?(Hash)
        op = '+' if value.delete('+')
        if value.empty?
          result += case level
            when 1 then "%s%s #{op}= {}\n" % [ prefix, attribute_types(attr) ]
            when 2 then "%s[\"%s\"] #{op}= {}\n" % [ prefix, attr ]
            else "%s%s #{op}= {}\n" % [ prefix, attribute_types(attr) ]
          end
        else
          result += case level
            when 1 then process_hash(value, indent, 2, "%s%s" % [ prefix, attr ])
            when 2 then "%s[\"%s\"] #{op}= {\n%s%s}\n" % [ prefix, attr, process_hash(value, indent), ' ' * (indent-2) ]
            else "%s%s #{op}= {\n%s%s}\n" % [ prefix, attribute_types(attr), process_hash(value, indent+2), ' ' * indent ]
          end
        end
      elsif value.is_a?(Array)
        op = value.delete_at(0) if value[0] == '+' or value[0] == '-'
        result += case level
          when 2 then "%s[\"%s\"] #{op}= [ %s]\n" % [ prefix, attribute_types(attr), process_array(value) ]
          else "%s%s #{op}= [ %s]\n" % [ prefix, attribute_types(attr), process_array(value) ]
        end
      else
        # String: attr = '+ value' -> attr += 'value'
        if value =~ /^([\+,-])\s+/
          operator = "#{$1}="
          value = value.sub(/^[\+,-]\s+/, '')
        else
          operator = '='
        end
        if level > 1
          if level == 3
            result += "%s%s #{operator} %s\n" % [ prefix, attribute_types(attr), parse(value) ] if value != :nil
          else
            result += "%s[\"%s\"] #{operator} %s\n" % [ prefix, attr, parse(value) ] if value != :nil
          end
        else
          result += "%s%s #{operator} %s\n" % [ prefix, attr, parse(value) ] if value != :nil
        end
      end
    end

    return result
  end


  # globals (params.pp) and all keys of attrs hash itselfs must not quoted
  $constants = globals.concat(consts.keys) << "name"

  # select all attributes and constants if there value is a hash
  $hash_attrs = attrs.merge(consts).select { |x,y| y.is_a?(Hash) }.keys

  # initialize returned configuration
  config = ''

  attrs.each do |attr, value|

    if attr =~ /^(assign|ignore) where$/
      value.each do |x|
        config += "%s%s %s\n" % [ ' ' * indent, attr, parse(x) ] if x
      end
    elsif attr == 'vars'
      if value.is_a?(Hash)
        # delete pair of key '+' because a merge at this point is not allowed
        value.delete('+')
        config += process_hash(value, indent+2, 1, "%s%s." % [ ' ' * indent, attr])
      elsif value.is_a?(Array)
        value.each do |item|
          if item.is_a?(String)
            config += "%s%s += %s\n" % [ ' ' * indent, attr, item.sub(/^[\+,-]\s+/, '') ]
          else
            item.delete('+')
            if item.empty?
              config += "%s%s += {}\n" % [ ' ' * indent, attr]
            else
              config += process_hash(item, indent+2, 1, "%s%s." % [ ' ' * indent, attr])
            end
          end
        end
      else
        op = '+' if value =~ /^\+\s+/
        config += "%s%s #{op}= %s\n" % [ ' ' * indent, attr, parse(value.sub(/^\+\s+/, '')) ]
      end
    else
      if value.is_a?(Hash)
        op = '+' if value.delete('+')
        unless value.empty?
          config += "%s%s #{op}= {\n%s%s}\n" % [ ' ' * indent, attr, process_hash(value, indent+2), ' ' * indent ]
        else
          config += "%s%s #{op}= {}\n" % [ ' ' * indent, attr ]
        end
      elsif value.is_a?(Array)
        op = value.delete_at(0) if value[0] == '+' or value[0] == '-'
        config += "%s%s #{op}= [ %s]\n" % [ ' ' * indent, attr, process_array(value) ]
      else
        # String: attr = '+config' -> attr += config 
        if value =~ /^([\+,-])\s+/
          config += "%s%s #{$1}= %s\n" % [ ' ' * indent, attr, parse(value.sub(/^[\+,-]\s+/, '')) ]
        else
          config += "%s%s = %s\n" % [ ' ' * indent, attr, parse(value) ]
        end
      end
    end
  end

  return config
end

.parse(row) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/puppet_x/icinga2/utils.rb', line 196

def self.parse(row)
  result = ''

  # parser is disabled
  if row =~ /^-:(.*)$/m
    return $1
  end

  if row =~ /^\{{2}(.+)\}{2}$/m
    # scan function
    result += "{{%s}}" % [ $1 ]
  elsif row =~ /^(.+)\s([\+-]|\*|\/|==|!=|&&|\|{2}|in)\s\{{2}(.+)\}{2}$/m
    # scan expression + function (function should contain expressions, but we donno parse it)
    result += "%s %s {{%s}}" % [ parse($1), $2, $3 ]
  elsif row =~ /^(.+)\s([\+-]|\*|\/|==|!=|&&|\|{2}|in)\s(.+)$/
    # scan expression
    result += "%s %s %s" % [ parse($1), $2, parse($3) ]
  else
    if row =~ /^(.+)\((.*)$/
      result += "%s(%s" % [ $1, $2.split(',').map {|x| parse(x.lstrip)}.join(', ') ]
    elsif row =~ /^(.*)\)(.+)?$/
      # closing bracket ) with optional access of an attribute e.g. '.arguments'
      result += "%s)%s" % [ $1.split(',').map {|x| parse(x.lstrip)}.join(', '), $2 ]
    elsif row =~ /^\((.*)$/
      result += "(%s" % [ parse($1) ]
    elsif row =~ /^\s*\[\s*(.*)\s*\]\s?(.+)?$/
      # parse array
      result += "[ %s]" % [ process_array($1.split(',')) ]
      result += " %s" % [ parse($2) ] if $2
    elsif row =~ /^\s*\{\s*(.*)\s*\}\s?(.+)?$/
      # parse hash
      result += "{\n%s}" % [ process_hash(Hash[$1.gsub(/\s*=>\s*|\s*,\s*/, ',').split(',').each_slice(2).to_a]) ]
      result += " %s" % [ parse($2) ] if $2
    else
      result += value_types(row.to_s.strip)
    end
  end

  return result.gsub(/" in "/, ' in ')
end

.process_array(items, indent = 2) ⇒ Object



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/puppet_x/icinga2/utils.rb', line 238

def self.process_array(items, indent=2)
  result = ''

  items.each do |value|
    if value.is_a?(Hash)
      result += "\n%s{\n%s%s}, " % [ ' ' * indent, process_hash(value, indent + 2), ' ' * indent ]
    elsif value.is_a?(Array)
      result += "[ %s], " % [ process_array(value, indent+2) ]
    else
      result += "%s, " % [ parse(value) ] if value
    end
  end

  return result
end

.process_hash(attrs, indent = 2, level = 3, prefix = ' '*indent) ⇒ Object



255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/puppet_x/icinga2/utils.rb', line 255

def self.process_hash(attrs, indent=2, level=3, prefix=' '*indent)
  result = ''
  attrs.each do |attr, value|
    if value.is_a?(Hash)
      op = '+' if value.delete('+')
      if value.empty?
        result += case level
          when 1 then "%s%s #{op}= {}\n" % [ prefix, attribute_types(attr) ]
          when 2 then "%s[\"%s\"] #{op}= {}\n" % [ prefix, attr ]
          else "%s%s #{op}= {}\n" % [ prefix, attribute_types(attr) ]
        end
      else
        result += case level
          when 1 then process_hash(value, indent, 2, "%s%s" % [ prefix, attr ])
          when 2 then "%s[\"%s\"] #{op}= {\n%s%s}\n" % [ prefix, attr, process_hash(value, indent), ' ' * (indent-2) ]
          else "%s%s #{op}= {\n%s%s}\n" % [ prefix, attribute_types(attr), process_hash(value, indent+2), ' ' * indent ]
        end
      end
    elsif value.is_a?(Array)
      op = value.delete_at(0) if value[0] == '+' or value[0] == '-'
      result += case level
        when 2 then "%s[\"%s\"] #{op}= [ %s]\n" % [ prefix, attribute_types(attr), process_array(value) ]
        else "%s%s #{op}= [ %s]\n" % [ prefix, attribute_types(attr), process_array(value) ]
      end
    else
      # String: attr = '+ value' -> attr += 'value'
      if value =~ /^([\+,-])\s+/
        operator = "#{$1}="
        value = value.sub(/^[\+,-]\s+/, '')
      else
        operator = '='
      end
      if level > 1
        if level == 3
          result += "%s%s #{operator} %s\n" % [ prefix, attribute_types(attr), parse(value) ] if value != :nil
        else
          result += "%s[\"%s\"] #{operator} %s\n" % [ prefix, attr, parse(value) ] if value != :nil
        end
      else
        result += "%s%s #{operator} %s\n" % [ prefix, attr, parse(value) ] if value != :nil
      end
    end
  end

  return result
end

.value_types(value) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/puppet_x/icinga2/utils.rb', line 169

def self.value_types(value)

  if value =~ /^-?\d+\.?\d*[dhms]?$/ || value =~ /^(true|false|null)$/ || value =~ /^!?(host|service|user)\./ || value =~ /^\{{2}.*\}{2}$/
    result = value
  else
    if $constants.index { |x| if $hash_attrs.include?(x) then value =~ /^!?(#{x})(\..+$|$)/ else value =~ /^!?#{x}$/ end }
      result = value
    else
      result = value.dump
    end
  end

  return result
end