class KafoParsers::PuppetStringsModuleParser

Public Class Methods

available?() click to toggle source
# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 26
def self.available?
  %x#{puppet_bin} help strings 2>&1`
  if $?.success?
    return true
  else
    raise KafoParsers::ParserNotAvailable.new("#{puppet_bin} does not have strings module installed")
  end
end
new(file) click to toggle source
# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 35
def initialize(file)
  @file = file = File.expand_path(file)
  raise KafoParsers::ModuleName, "File not found #{file}, check your answer file" unless File.exist?(file)

  command = "#{self.class.puppet_bin} strings generate --format json #{file}"
  @raw_json = %x#{command}`
  unless $?.success?
    raise KafoParsers::ParseError, "'#{command}' returned error\n#{@raw_json}"
  end

  begin
    @complete_hash = ::JSON.parse(@raw_json)
  rescue ::JSON::ParserError => e
    raise KafoParsers::ParseError, "'#{command}' returned invalid json output: #{e.message}\n#{@raw_json}"
  end
  self.data_type # we need to determine data_type before any further parsing

  self
end
parse(file) click to toggle source

You can call this method to get all supported information from a given manifest

@param [ String ] manifest file path to parse @return [ Hash ] hash containing values, validations, documentation, types, groups and conditions

# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 11
def self.parse(file)
  content = new(file)
  docs    = content.docs

  # data_type must be called before other validations
  data = {
    :object_type => content.data_type,
    :values      => content.values,
    :validations => content.validations
  }
  data[:parameters] = data[:values].keys
  data.merge!(docs)
  data
end
puppet_bin() click to toggle source

AIO and system default puppet bins are tested for existence, fallback to just `puppet` otherwise

# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 56
def self.puppet_bin
  @puppet_bin ||= begin
    found_puppet_path = (::ENV['PATH'].split(File::PATH_SEPARATOR) + ['/opt/puppetlabs/bin']).find do |path|
      binary = File.join(path, 'puppet')
      binary if File.executable?(binary)
    end
    found_puppet_path.nil? ? 'puppet' : File.join(found_puppet_path, 'puppet')
  end
end

Public Instance Methods

data_type() click to toggle source
# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 66
def data_type
  @data_type ||= begin
    if (@parsed_hash = @complete_hash['puppet_classes'].find { |klass| klass['file'] == @file })
      'hostclass'
    elsif (@parsed_hash = @complete_hash['defined_types'].find { |klass| klass['file'] == @file })
      'definition'
    else
      raise KafoParsers::ParseError, "unable to find manifest data, syntax error in manifest #{@file}?"
    end
  end
end
docs() click to toggle source

returns data in following form {

:docs => { $param1 => ['documentation without types and conditions']}
:types => { $param1 => 'boolean'},
:groups => { $param1 => ['Parameters', 'Advanced']},
:conditions => { $param1 => '$db_type == "mysql"'},

}

# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 98
def docs
  data = { :docs => {}, :types => {}, :groups => {}, :conditions => {} }
  if @parsed_hash.nil?
    raise KafoParsers::DocParseError, "no documentation found for manifest #{@file}, parsing error?"
  elsif !@parsed_hash['docstring'].nil? && !@parsed_hash['docstring']['text'].nil?
    # Lowest precedence: types given in the strings hash from class definition
    tag_params.each do |param|
      data[:types][param['name']] = param['types'][0] unless param['types'].nil?
    end

    # Next: types and other data from RDoc parser
    rdoc_parser = DocParser.new(@parsed_hash['docstring']['text']).parse
    data[:docs] = rdoc_parser.docs
    data[:groups] = rdoc_parser.groups
    data[:conditions] = rdoc_parser.conditions
    data[:types].merge! rdoc_parser.types

    # Highest precedence: data in YARD @param stored in the 'text' field
    tag_params.each do |param|
      param_name = param['name']
      unless param['text'].nil? || param['text'].empty?
        param_parser = ParamDocParser.new(param_name, param['text'].split($/))
        data[:docs][param_name] = param_parser.doc if param_parser.doc
        data[:groups][param_name] = param_parser.group if param_parser.group
        data[:conditions][param_name] = param_parser.condition if param_parser.condition
        data[:types][param_name] = param_parser.type if param_parser.type
      end
    end
  end
  data
end
validations(param = nil) click to toggle source

unsupported in puppet strings parser

# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 87
def validations(param = nil)
  []
end
values() click to toggle source
# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 78
def values
  Hash[
    # combine known parameters (from tags) with any defaults provided
    tag_params.select { |param| !param['types'].nil? }.map { |param| [ param['name'], nil ] } +
      @parsed_hash.fetch('defaults', {}).map { |name, value| [ name, value.nil? ? nil : sanitize(value) ] }
  ]
end

Private Instance Methods

sanitize(value) click to toggle source

default values using puppet strings includes $ symbol, e.g. “$::foreman::params::ssl”

values are reported as strings which is issue especially for :under strings are double quoted others must be typecast manually according to reported type

# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 137
def sanitize(value)
  if (value.start_with?("'") && value.end_with?("'")) || (value.start_with?('"') && value.end_with?('"'))
    value = value[1..-2]
  end
  value = :undef if value == 'undef'

  value
end
tag_params() click to toggle source
# File lib/kafo_parsers/puppet_strings_module_parser.rb, line 146
def tag_params
  if @parsed_hash['docstring']['tags']
    @parsed_hash['docstring']['tags'].select { |tag| tag['tag_name'] == 'param' }
  else
    []
  end
end