Class: MCollective::Application::Playbook

Inherits:
MCollective::Application show all
Defined in:
lib/mcollective/application/playbook.rb

Instance Attribute Summary

Attributes inherited from MCollective::Application

#options

Instance Method Summary collapse

Methods inherited from MCollective::Application

[], []=, #application_cli_arguments, #application_description, #application_failure, application_options, #application_options, #application_parse_options, #application_usage, #clioptions, #configuration, description, #disconnect, exclude_argument_sections, external, #external_help, external_help, #external_main, #halt, #halt_code, #help, intialize_application_options, option, #rpcclient, usage, #validate_cli_options, #validate_option

Methods included from RPC

const_missing, discovered, #empty_filter?, #printrpc, #printrpcstats, #rpcclient, #rpcoptions, stats

Instance Method Details

#mainObject



202
203
204
# File 'lib/mcollective/application/playbook.rb', line 202

def main
  send("%s_command" % configuration[:__command])
end

#post_option_parser(configuration) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/mcollective/application/playbook.rb', line 112

def post_option_parser(configuration)
  if ARGV.length >= 1
    configuration[:__command] = ARGV.shift
  else
    abort("Please specify a command, valid commands are: %s" % valid_commands.join(", "))
  end

  if input = configuration[:__json_input]
    result = {}

    if input.start_with?("@")
      input.sub!("@", "")
      result = JSON.parse(File.read(input)) if input.end_with?("json")
      result = YAML.safe_load(File.read(input)) if input.end_with?("yaml")
    else
      result = JSON.parse(input)
    end

    configuration.merge!(result)
  end
end

#pre_parse_find_playbookString?

Playbook should be given right after the command, this finds the value after the command

Returns:



36
37
38
39
40
41
42
43
44
45
# File 'lib/mcollective/application/playbook.rb', line 36

def pre_parse_find_playbook
  commands = Regexp.union(valid_commands)

  cmd_idx = ARGV.index {|a| a.match(commands)}
  return nil unless cmd_idx

  pb = ARGV[cmd_idx + 1]

  pb if pb =~ /\A([a-z][a-z0-9_]*)?(::[a-z][a-z0-9_]*)*\Z/
end

#pre_parse_modulepathObject



23
24
25
26
27
28
29
30
31
# File 'lib/mcollective/application/playbook.rb', line 23

def pre_parse_modulepath
  words = Shellwords.shellwords(ARGV.join(" "))
  words.each_with_index do |word, idx|
    if word == "--modulepath"
      configuration[:__modulepath] = words[idx + 1]
      break
    end
  end
end

#runObject

Adds the playbook inputs as CLI options before starting the app



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
# File 'lib/mcollective/application/playbook.rb', line 79

def run
  pre_parse_modulepath

  Dir.mktmpdir("choria") do |dir|
    configuration[:__tmpdir] = dir

    if playbook_name = pre_parse_find_playbook
      configuration[:__playbook] = playbook_name
      runner(playbook_name).add_cli_options(self, false)
    end

    # Hackily done here to force it below the playbook options
    self.class.option :__json_input,
                      :arguments => ["--input INPUT"],
                      :description => "JSON input to pass to the task",
                      :required => false,
                      :type => String

    self.class.option :__modulepath,
                      :arguments => ["--modulepath PATH"],
                      :description => "Path to find Puppet module when using the Playbook DSL",
                      :type => String

    self.class.option :__loglevel,
                      :arguments => ["--loglevel LEVEL"],
                      :description => "Override the loglevel set in the playbook (emerg alert crit err warning notice info verbose debug)",
                      :type => String,
                      :validate => ->(level) { %w[emerg alert crit err warning notice info verbose debug].include?(level) }

    super
  end
end

#run_commandObject



150
151
152
153
154
155
156
157
# File 'lib/mcollective/application/playbook.rb', line 150

def run_command
  pb_config = configuration.clone
  pb_config.delete_if {|k, _| k.to_s.start_with?("__")}

  pb = runner(configuration[:__playbook], configuration[:__loglevel])

  run_plan(pb, pb_config)
end

#run_plan(playbook, pb_config) ⇒ Object



159
160
161
162
163
164
165
166
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
# File 'lib/mcollective/application/playbook.rb', line 159

def run_plan(playbook, pb_config)
  startime = Time.now

  success = true

  result = playbook.run!(pb_config)
rescue
  success = false
ensure
  disconnect

  endtime = Time.now

  color = :green
  msg = "OK"

  unless success
    color = :red
    msg = "FAILED"
  end

  puts
  puts "Playbook %s ran in %.2f seconds: %s" % [
    Util.colorize(:bold, configuration[:__playbook]),
    endtime - startime,
    Util.colorize(color, msg)
  ]

  if result
    puts
    puts "Result: "
    puts
    if result.instance_of?(String)
      puts result
    else
      puts Util.align_text(JSON.pretty_generate(result), 10000)
    end
    puts
  end

  success ? exit(0) : exit(1)
end

#runner(plan, loglevel = nil) ⇒ Util::BoltSupport::PlanRunner

Creates an instance of the plan runner

Parameters:

  • plan (String)

    the name of a plan

Returns:



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
# File 'lib/mcollective/application/playbook.rb', line 51

def runner(plan, loglevel=nil)
  require "mcollective/util/bolt_support"
  plan_runner = Util::BoltSupport::PlanRunner.new(
    plan,
    configuration[:__tmpdir],
    configuration[:__modulepath],
    configuration[:__loglevel] || "info"
  )

  unless plan_runner.exist?
    warn("Cannot find supplied Playbook %s" % plan)
    $stderr.puts
    warn("Module Path:")
    $stderr.puts

    if configuration[:__modulepath]
      warn(Util.align_text(configuration[:__modulepath].split(":").join("\n")))
    else
      warn(Util.align_text("Puppet Default"))
    end

    exit(1)
  end

  plan_runner
end

#valid_commandsArray<String>

List of valid commands this application respond to

Returns:



146
147
148
# File 'lib/mcollective/application/playbook.rb', line 146

def valid_commands
  methods.grep(/_command$/).map {|c| c.to_s.gsub("_command", "")}
end

#validate_configuration(configuration) ⇒ void

This method returns an undefined value.

Validates the configuration



137
138
139
140
141
# File 'lib/mcollective/application/playbook.rb', line 137

def validate_configuration(configuration)
  abort("Please specify a playbook to run") unless configuration[:__playbook]

  configuration[:__loglevel] = "debug" if options[:verbose] && !configuration.include?(:loglevel)
end