Module: PuppetRepl::Support

Includes:
Compilier, Environment, Facts, Functions, InputResponders, Node, Play, Scope
Included in:
Cli
Defined in:
lib/puppet-repl/support.rb,
lib/puppet-repl/support/node.rb,
lib/puppet-repl/support/play.rb,
lib/puppet-repl/support/facts.rb,
lib/puppet-repl/support/scope.rb,
lib/puppet-repl/support/compiler.rb,
lib/puppet-repl/support/functions.rb,
lib/puppet-repl/support/environment.rb,
lib/puppet-repl/support/input_responders.rb

Defined Under Namespace

Modules: Compilier, Environment, Facts, Functions, InputResponders, Node, Play, Scope

Instance Method Summary collapse

Methods included from Play

#convert_to_text, #fetch_url_data, #play_back, #play_back_string, #play_back_url

Methods included from InputResponders

#classes, #classification, #environment, #facterdb_filter, #facts, #functions, #handle_set, #help, #krt, #play, #reset, #resources, #set_log_level, #static_responder_list, #vars, #whereami

Methods included from Node

#convert_remote_node, #create_node, #get_remote_node, #node, #remote_node_name, #remote_node_name=, #set_node, #set_node_from_name, #set_remote_node_name

Methods included from Functions

#function_files, #function_map, #lib_dirs, #load_lib_dirs, #mod_finder, #resolve_paths

Methods included from Scope

#create_scope, #scope, #scope_vars, #set_scope

Methods included from Facts

#default_facter_version, #default_facterdb_filter, #default_facts, #dynamic_facterdb_filter, #facter_os_name, #facter_os_version, #facter_version, #node_facts, #server_facts, #set_facts

Methods included from Environment

#create_environment, #default_puppet_env_name, #environment_loaders, #puppet_env_name, #puppet_environment, #set_environment

Methods included from Compilier

#compiler, #create_compiler, #set_compiler

Instance Method Details

#default_manifests_dirObject



167
168
169
# File 'lib/puppet-repl/support.rb', line 167

def default_manifests_dir
  File.join(Puppet[:environmentpath],default_puppet_env_name,'manifests')
end

#default_modules_pathsObject

returns an array of module directories, generally this is the only place to look for puppet code by default. This is read from the puppet configuration



48
49
50
51
52
53
54
55
# File 'lib/puppet-repl/support.rb', line 48

def default_modules_paths
  dirs = []
  do_initialize if Puppet[:codedir].nil?
  # add the puppet-repl directory so we can load any defined functions
  dirs << File.join(Puppet[:environmentpath],default_puppet_env_name,'modules') unless Puppet[:environmentpath].empty?
  dirs << Puppet.settings[:basemodulepath].split(':')
  dirs.flatten
end

#default_site_manifestObject



171
172
173
# File 'lib/puppet-repl/support.rb', line 171

def default_site_manifest
  File.join(default_manifests_dir, 'site.pp')
end

#do_initializeObject

this is required in order to load things only when we need them



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/puppet-repl/support.rb', line 102

def do_initialize
  begin
    Puppet.initialize_settings
    Puppet[:parser] = 'future'  # this is required in order to work with puppet 3.8
    Puppet[:trusted_node_data] = true
  rescue ArgumentError => e

  rescue Puppet::DevError => e
    # do nothing otherwise calling init twice raises an error
  end
end

#generate_ast(string = nil) ⇒ Object

Returns Hostclass - a puppet Program object which is considered the main class.

Parameters:

  • String
    • any valid puppet language code

Returns:

  • Hostclass - a puppet Program object which is considered the main class



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/puppet-repl/support.rb', line 116

def generate_ast(string = nil)
  parse_result = parser.parse_string(string, '')
  # the parse_result may be
  # * empty / nil (no input)
  # * a Model::Program
  # * a Model::Expression
  #
  model = parse_result.nil? ? nil : parse_result.current
  args = {}
  ::Puppet::Pops::Model::AstTransformer.new('').merge_location(args, model)

  ast_code =
  if model.is_a? ::Puppet::Pops::Model::Program
    ::Puppet::Parser::AST::PopsBridge::Program.new(model, args)
  else
    args[:value] = model
    ::Puppet::Parser::AST::PopsBridge::Expression.new(args)
  end
  # Create the "main" class for the content - this content will get merged with all other "main" content
  ::Puppet::Parser::AST::Hostclass.new('', :code => ast_code)
end

#initialize_from_scope(value) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/puppet-repl/support.rb', line 69

def initialize_from_scope(value)
  set_scope(value)
  unless value.nil?
    set_environment(value.environment)
    set_node(value.compiler.node)
    set_compiler(value.compiler)
  end
end

#keyword_expressionObject



78
79
80
# File 'lib/puppet-repl/support.rb', line 78

def keyword_expression
  @keyword_expression ||= Regexp.new(/^exit|^:set|^play|^classification|^facts|^vars|^functions|^classes|^resources|^krt|^environment|^reset|^help/)
end

#known_resource_typesObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/puppet-repl/support.rb', line 82

def known_resource_types
  res = {
    :hostclasses => scope.environment.known_resource_types.hostclasses.keys,
    :definitions => scope.environment.known_resource_types.definitions.keys,
    :nodes => scope.environment.known_resource_types.nodes.keys,
  }
  if sites = scope.environment.known_resource_types.instance_variable_get(:@sites)
    res.merge!(:sites => scope.environment.known_resource_types.instance_variable_get(:@sites).first)
  end
  if scope.environment.known_resource_types.respond_to?(:applications)
    res.merge!(:applications => scope.environment.known_resource_types.applications.keys)
  end
  # some versions of puppet do not support capabilities
  if scope.environment.known_resource_types.respond_to?(:capability_mappings)
    res.merge!(:capability_mappings => scope.environment.known_resource_types.capability_mappings.keys)
  end
  res
end

#modules_pathsObject

returns all the modules paths defined in the environment



65
66
67
# File 'lib/puppet-repl/support.rb', line 65

def modules_paths
  puppet_environment.full_modulepath
end

#parse_error(error) ⇒ Object

parses the error type into a more useful error message defined in errors.rb returns new error object or the original if error cannot be parsed



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/puppet-repl/support.rb', line 23

def parse_error(error)
  case error
  when SocketError
    PuppetRepl::Exception::ConnectError.new(:message => "Unknown host: #{Puppet[:server]}")
  when Net::HTTPError
    PuppetRepl::Exception::AuthError.new(:message => error.message)
  when Errno::ECONNREFUSED
    PuppetRepl::Exception::ConnectError.new(:message => error.message)
  when Puppet::Error
    if error.message =~ /could\ not\ find\ class/i
      PuppetRepl::Exception::NoClassError.new(:default_modules_paths => default_modules_paths,
       :message => error.message)
    elsif error.message =~ /default\ node/i
      PuppetRepl::Exception::NodeDefinitionError.new(:default_site_manifest => default_site_manifest,
       :message => error.message)
    else
      error
    end
  else
    error
  end
end

#parserObject

returns a future parser for evaluating code



163
164
165
# File 'lib/puppet-repl/support.rb', line 163

def parser
  @parser ||= ::Puppet::Pops::Parser::EvaluatingParser.new
end

#puppet_eval(input) ⇒ Object

Returns Object - returns either a string of the result or object from puppet evaulation.

Parameters:

  • String
    • any valid puppet language code

Returns:

  • Object - returns either a string of the result or object from puppet evaulation



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/puppet-repl/support.rb', line 140

def puppet_eval(input)
  # in order to add functions to the scope the loaders must be created
  # in order to call native functions we need to set the global_scope
  ast = generate_ast(input)
  # record the input for puppet to retrieve and reference later
  file = Tempfile.new(['puppet_repl_input', '.pp'])
  File.open(file, 'w') do |f|
    f.write(input)
  end
  Puppet.override( {:code => input, :global_scope => scope, :loaders => scope.compiler.loaders } , 'For puppet-repl') do
     # because the repl is not a module we leave the modname blank
     scope.environment.known_resource_types.import_ast(ast, '')
     parser.evaluate_string(scope, input, File.expand_path(file))
  end
end

#puppet_lib_dirObject



156
157
158
159
160
# File 'lib/puppet-repl/support.rb', line 156

def puppet_lib_dir
  # returns something like "/Library/Ruby/Gems/2.0.0/gems/puppet-4.2.2/lib/puppet.rb"
  # this is only useful when returning a namespace with the functions
  @puppet_lib_dir ||= File.dirname(Puppet.method(:[]).source_location.first)
end

#puppet_repl_lib_dirObject

this is the lib directory of this gem in order to load any puppet functions from this gem we need to add the lib path of this gem



60
61
62
# File 'lib/puppet-repl/support.rb', line 60

def puppet_repl_lib_dir
  File.expand_path(File.join(File.dirname(File.dirname(File.dirname(__FILE__))), 'lib'))
end