Class: MCollective::Util::BoltSupport::PlanRunner

Inherits:
Object
  • Object
show all
Defined in:
lib/mcollective/util/bolt_support/plan_runner.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(plan, tmpdir, modulepath, loglevel) ⇒ PlanRunner

Returns a new instance of PlanRunner.

Parameters:

  • plan (String)

    the name of the plan to use

  • tmpdir (String)

    the path to an already existing temporary directory

  • modulepath (String, nil)

    a : seperated list of locations to look for modules, uses puppet basemodulepath if nil

  • loglevel (debug, info, warn, err)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 22

def initialize(plan, tmpdir, modulepath, loglevel)
  @plan = plan
  @loglevel = loglevel
  @tmpdir = tmpdir

  raise("A temporary directory could not be created") unless @tmpdir
  raise("A temporary directory could not be created") unless File.directory?(@tmpdir)

  @modulepath = modulepath

  unless @modulepath
    initialize_settings
    @modulepath = Puppet.settings[:basemodulepath]
  end

  @modulepath = @modulepath.split(":")

  Puppet[:log_level] = @loglevel
end

Instance Attribute Details

#modulepathObject (readonly)

Returns the value of attribute modulepath.



16
17
18
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 16

def modulepath
  @modulepath
end

Class Method Details

.init_puppetObject



9
10
11
12
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 9

def self.init_puppet
  TaskResults.include_iterable
  Puppet::Util::Log.newdestination(:console)
end

Instance Method Details

#add_cli_options(application, set_required = false) ⇒ Object

Adds the CLI options for an application based on the playbook inputs

Parameters:



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 144

def add_cli_options(application, set_required=false)
  sig = plan_signature

  return if sig.nil? || sig.empty?

  sig.each do |name, details|
    type, array = puppet_type_to_ruby(details["type"])

    properties = {
      :description => "Plan input property (%s)" % details["type"],
      :arguments => "--%s %s" % [name.downcase, name.upcase],
      :type => array ? :array : type
    }

    properties[:required] = true if details["required"] && set_required
    properties[:arguments] = "--[no-]%s" % name.downcase if type == :boolean

    application.class.option(name, properties)
  end
end

#exist?Boolean

Determines if the requested plan exist

Returns:

  • (Boolean)


45
46
47
48
49
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 45

def exist?
  with_script_compiler do |compiler|
    return !!compiler.plan_signature(@plan)
  end
end

#factsObject

Facts to use in the environment



86
87
88
89
90
91
92
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 86

def facts
  {
    "choria" => {
      "playbook" => @plan
    }
  }
end

#in_environment(&block) ⇒ Object

Sets up a temporary environment



99
100
101
102
103
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 99

def in_environment(&block)
  initialize_settings

  Puppet::Pal.in_tmp_environment("choria", :modulepath => @modulepath, :facts => facts, &block)
end

#initialize_settingsObject



94
95
96
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 94

def initialize_settings
  Puppet.initialize_settings(puppet_cli_options) unless Puppet.settings.global_defaults_initialized?
end

#plan_signatureHash

Retrieves the signature of a plan - its parameters and types

NOTE: at present it’s not possible to extract description or default values

Returns:

  • (Hash)


63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 63

def plan_signature
  with_script_compiler do |compiler|
    sig = compiler.plan_signature(@plan)

    raise("Cannot find playbook %s in %s" % [@plan, @modulepath.join(":")]) unless sig

    sig.params_type.elements.map do |elem|
      [elem.name, {
        "type" => elem.value_type.to_s,
        "required" => !elem.key_type.is_a?(Puppet::Pops::Types::POptionalType)
      }]
    end
  end
end

#puppet_cli_optionsObject

Initialize Puppet to use the configured tmp dir



52
53
54
55
56
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 52

def puppet_cli_options
  Puppet::Settings::REQUIRED_APP_SETTINGS.map do |setting|
    "--%s %s" % [setting, @tmpdir]
  end
end

#puppet_type_to_ruby(type) ⇒ Class, Boolean

Converts a Puppet type into something mcollective understands

This is inevitably hacky by its nature, there is no way for me to parse the types. PAL might get some helpers for this but till then this is going to have to be best efforts.

When there is a too complex situation users can always put in –input and some JSON to work around it until something better comes around

Parameters:

  • type (String)

    a puppet type

Returns:

  • (Class, Boolean)

    The data type, if its an array input or not



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 116

def puppet_type_to_ruby(type)
  array = false

  type = $1 if type =~ /Optional\[(.+)/

  if type =~ /Array\[(.+)/
    type = $1
    array = true
  end

  return [Numeric, array] if type =~ /Integer/
  return [Numeric, array] if type =~ /Float/
  return [Hash, array] if type =~ /Hash/
  return [:boolean, array] if type =~ /Boolean/

  [String, array]
end

#run!(params) ⇒ Object



134
135
136
137
138
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 134

def run!(params)
  with_script_compiler do |compiler|
    compiler.call_function("choria::run_playbook", @plan, params)
  end
end

#with_script_compiler(&block) ⇒ Object

Yields a PAL script compiler in the temporary environment



79
80
81
82
83
# File 'lib/mcollective/util/bolt_support/plan_runner.rb', line 79

def with_script_compiler(&block)
  in_environment do |env|
    env.with_script_compiler(&block)
  end
end