choria-colt 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +38 -0
- data/Gemfile +6 -0
- data/README.md +54 -0
- data/Rakefile +8 -0
- data/choria-colt.gemspec +44 -0
- data/exe/colt +5 -0
- data/lib/choria/colt/cache.rb +33 -0
- data/lib/choria/colt/cli/thor.rb +42 -0
- data/lib/choria/colt/cli.rb +109 -0
- data/lib/choria/colt/version.rb +7 -0
- data/lib/choria/colt.rb +58 -0
- data/lib/choria/orchestrator/task.rb +59 -0
- data/lib/choria/orchestrator.rb +99 -0
- data/sig/choria/colt.rbs +6 -0
- metadata +159 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fa21249d732edfc1a2391bd20dcfc33cd8eee373329f90ffbf95ad6e9feb0a5c
|
4
|
+
data.tar.gz: 1ee9fbda91dd047ca932e8d117b65c2aab0252fdc96c30bf4b3be7a841ef3af5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d6b9e92533f0911ba97d3032f46a6d6b7c8f779317cf471dae1ee70a5457cca53ee62b1410a8ecba691cba504dadc3df54f92f9dfb4a63238e11cbc16c04d261
|
7
|
+
data.tar.gz: cc601e0c25747af5ff818a32eff04138138a66277a2daf430016ac5755a2906a3016f918fe43c23cffd3a5a3a66cc40267267a3cfe65bef211b178c1cc5ca8ef
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.5
|
3
|
+
Exclude:
|
4
|
+
- 'bin/colt'
|
5
|
+
- 'vendor/**/*'
|
6
|
+
NewCops: enable
|
7
|
+
|
8
|
+
Metrics/AbcSize:
|
9
|
+
Max: 20
|
10
|
+
|
11
|
+
Metrics/MethodLength:
|
12
|
+
Max: 17
|
13
|
+
|
14
|
+
Layout/LineLength:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Style/Documentation:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Style/FrozenStringLiteralComment:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Style/NumericLiterals:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Style/TrailingCommaInArrayLiteral:
|
27
|
+
EnforcedStyleForMultiline: comma
|
28
|
+
|
29
|
+
Style/TrailingCommaInHashLiteral:
|
30
|
+
EnforcedStyleForMultiline: comma
|
31
|
+
|
32
|
+
Layout/HashAlignment:
|
33
|
+
EnforcedHashRocketStyle: table
|
34
|
+
|
35
|
+
Metrics/BlockLength:
|
36
|
+
Exclude:
|
37
|
+
- '*.gemspec'
|
38
|
+
- 'spec/**/*_spec.rb'
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Choria::Colt
|
2
|
+
|
3
|
+
This _gem_ provides:
|
4
|
+
* `colt` executable, a [Bolt](https://puppet.com/docs/bolt/latest/bolt.html)-like command line interface to run _Bolt_ task through [Choria](https://puppet.com/docs/bolt/latest/bolt.html)
|
5
|
+
* helpers functions and classes to run _Bolt_ tasks through _Choria_ infrastructure from any _ruby_ code
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
### CLI
|
10
|
+
|
11
|
+
```shell-session
|
12
|
+
$ colt tasks run exec=hostname -t vm012345.example.net,vm543210.example.net
|
13
|
+
```
|
14
|
+
|
15
|
+
### Code
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
require 'choria/colt'
|
19
|
+
|
20
|
+
targets = [ 'vm012345.example.net' ]
|
21
|
+
task_name = 'exec'
|
22
|
+
task_input = { 'command' => 'hostname' }
|
23
|
+
|
24
|
+
colt = Choria::Colt.new(logger: Logger.new($stdout))
|
25
|
+
results = colt.run_bolt_task task_name, input: task_input, targets: targets
|
26
|
+
|
27
|
+
$stdout.puts JSON.pretty_generate(results)
|
28
|
+
```
|
29
|
+
|
30
|
+
## Installation
|
31
|
+
|
32
|
+
Add this line to your application's Gemfile:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
gem 'choria-colt'
|
36
|
+
```
|
37
|
+
|
38
|
+
And then execute:
|
39
|
+
|
40
|
+
$ bundle install
|
41
|
+
|
42
|
+
Or install it yourself as:
|
43
|
+
|
44
|
+
$ gem install choria-colt
|
45
|
+
|
46
|
+
## Development
|
47
|
+
|
48
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
49
|
+
|
50
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
51
|
+
|
52
|
+
## Contributing
|
53
|
+
|
54
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/opus-codium/choria-colt.
|
data/Rakefile
ADDED
data/choria-colt.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/choria/colt/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'choria-colt'
|
7
|
+
spec.version = Choria::Colt::VERSION
|
8
|
+
spec.authors = ['Romuald Conty']
|
9
|
+
spec.email = ['romuald@opus-codium.fr']
|
10
|
+
|
11
|
+
spec.summary = 'Bolt-like CLI to run Bolt tasks, through Choria'
|
12
|
+
spec.description = 'Colt eases the Bolt tasks run through Choria'
|
13
|
+
spec.homepage = 'https://github.com/opus-codium/choria-colt'
|
14
|
+
spec.required_ruby_version = '>= 2.5.0'
|
15
|
+
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
17
|
+
spec.metadata['source_code_uri'] = 'https://github.com/opus-codium/choria-colt'
|
18
|
+
spec.metadata['changelog_uri'] = 'https://github.com/opus-codium/choria-colt/CHANGELOG.md'
|
19
|
+
|
20
|
+
# Specify which files should be added to the gem when it is released.
|
21
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
23
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
24
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
spec.bindir = 'exe'
|
28
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ['lib']
|
30
|
+
|
31
|
+
spec.add_dependency 'choria-mcorpc-support'
|
32
|
+
spec.add_dependency 'deep_merge'
|
33
|
+
spec.add_dependency 'puppet'
|
34
|
+
spec.add_dependency 'thor'
|
35
|
+
|
36
|
+
spec.add_development_dependency 'rake'
|
37
|
+
spec.add_development_dependency 'rspec'
|
38
|
+
spec.add_development_dependency 'rubocop'
|
39
|
+
#spec.add_development_dependency 'byebug'
|
40
|
+
|
41
|
+
# For more information and examples about making a new gem, check out our
|
42
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
43
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
44
|
+
end
|
data/exe/colt
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Choria
|
4
|
+
class Colt
|
5
|
+
class Cache
|
6
|
+
def initialize(path:, force_refresh: false)
|
7
|
+
@path = path
|
8
|
+
@data = YAML.safe_load File.read(@path)
|
9
|
+
@clean = true unless force_refresh
|
10
|
+
rescue Errno::ENOENT
|
11
|
+
@clean = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def dirty?
|
15
|
+
!clean?
|
16
|
+
end
|
17
|
+
|
18
|
+
def clean?
|
19
|
+
@clean
|
20
|
+
end
|
21
|
+
|
22
|
+
def load
|
23
|
+
@data
|
24
|
+
end
|
25
|
+
|
26
|
+
def save(data)
|
27
|
+
@data = data
|
28
|
+
File.write @path, data.to_yaml
|
29
|
+
@clean = true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'choria/colt/cli'
|
3
|
+
|
4
|
+
module Choria
|
5
|
+
class Colt
|
6
|
+
# Workaround some, still unfixed, Thor behaviors
|
7
|
+
#
|
8
|
+
# This class extends ::Thor class to
|
9
|
+
# - exit with status code sets to `1` on Thor failure (e.g. missing required option)
|
10
|
+
# - exit with status code sets to `1` when user calls `msync` (or a subcommand) without required arguments
|
11
|
+
# - show subcommands help using `msync subcommand --help`
|
12
|
+
class Thor < ::Thor
|
13
|
+
def self.start(*args)
|
14
|
+
if (Thor::HELP_MAPPINGS & ARGV).any? && subcommands.none? { |command| command.start_with?(ARGV[0]) }
|
15
|
+
Thor::HELP_MAPPINGS.each do |cmd|
|
16
|
+
if (match = ARGV.delete(cmd))
|
17
|
+
ARGV.unshift match
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
desc '_invalid_command_call', 'Invalid command', hide: true
|
25
|
+
def _invalid_command_call
|
26
|
+
self.class.new.help
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
default_task :_invalid_command_call
|
30
|
+
|
31
|
+
def self.exit_on_failure?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.is_thor_reserved_word?(word, type) # rubocop:disable Naming/PredicateName
|
36
|
+
return false if word == 'run'
|
37
|
+
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'choria/colt'
|
2
|
+
require 'choria/colt/cli/thor'
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
module Choria
|
8
|
+
class Colt
|
9
|
+
class CLI < Thor
|
10
|
+
class Tasks < Thor
|
11
|
+
# BOLT: desc 'run <task name> [parameters] {--targets TARGETS | --query QUERY | --rerun FILTER} [options]', 'Run a Bolt task'
|
12
|
+
desc 'run <task name> [parameters] --targets TARGETS [options]', 'Run a Bolt task'
|
13
|
+
long_desc <<~DESC
|
14
|
+
Run a task on the specified targets.
|
15
|
+
|
16
|
+
Parameters take the form parameter=value.
|
17
|
+
DESC
|
18
|
+
option :targets,
|
19
|
+
aliases: ['--target', '-t'],
|
20
|
+
desc: 'Identifies the targets of the command.',
|
21
|
+
required: true
|
22
|
+
def run(*args)
|
23
|
+
input = extract_task_parameters_from_args(args)
|
24
|
+
|
25
|
+
raise Thor::Error, 'Task name is required' if args.empty?
|
26
|
+
raise Thor::Error, "Too many arguments: #{args}" unless args.count == 1
|
27
|
+
|
28
|
+
task_name = args.shift
|
29
|
+
|
30
|
+
targets = options['targets'].split ','
|
31
|
+
targets = nil if options['targets'] == 'all'
|
32
|
+
|
33
|
+
results = colt.run_bolt_task task_name, input: input, targets: targets
|
34
|
+
$stdout.puts JSON.pretty_generate(results)
|
35
|
+
rescue Choria::Orchestrator::Error => e
|
36
|
+
raise Thor::Error, "#{e.class}: #{e}"
|
37
|
+
end
|
38
|
+
|
39
|
+
desc 'show [task name] [options]', 'Show available tasks and task documentation'
|
40
|
+
long_desc <<~DESC
|
41
|
+
Show available tasks and task documentation.
|
42
|
+
|
43
|
+
Omitting the name of a task will display a list of tasks available
|
44
|
+
in the Bolt project.
|
45
|
+
|
46
|
+
Providing the name of a task will display detailed documentation for
|
47
|
+
the task, including a list of available parameters.
|
48
|
+
DESC
|
49
|
+
option :environment,
|
50
|
+
aliases: ['-E'],
|
51
|
+
desc: 'Puppet environment to grab tasks from',
|
52
|
+
default: 'production'
|
53
|
+
def show(*tasks_names)
|
54
|
+
environment = options['environment']
|
55
|
+
cache_directory = File.expand_path('.cache/colt/tasks')
|
56
|
+
FileUtils.mkdir_p cache_directory
|
57
|
+
# TODO: Support multiple infrastructure
|
58
|
+
cache = Cache.new(path: File.join(cache_directory, "#{environment}.yaml"))
|
59
|
+
|
60
|
+
tasks = colt.tasks(environment: environment, cache: cache)
|
61
|
+
|
62
|
+
if tasks_names.nil?
|
63
|
+
show_tasks_summary
|
64
|
+
else
|
65
|
+
tasks_names.each { |task_name| show_task_details(task_name, tasks) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
no_commands do
|
70
|
+
def colt
|
71
|
+
@colt ||= Choria::Colt.new logger: Logger.new($stdout)
|
72
|
+
end
|
73
|
+
|
74
|
+
def extract_task_parameters_from_args(args)
|
75
|
+
parameters = args.grep(/^\w+=/)
|
76
|
+
args.reject! { |arg| arg =~ /^\w+=/ }
|
77
|
+
|
78
|
+
parameters.map do |parameter|
|
79
|
+
key, value = parameter.split('=')
|
80
|
+
[key, value]
|
81
|
+
end.to_h
|
82
|
+
end
|
83
|
+
|
84
|
+
def show_tasks_summary(tasks)
|
85
|
+
tasks.reject! { |_task, metadata| metadata['metadata']['private'] }
|
86
|
+
|
87
|
+
puts <<~OUTPUT
|
88
|
+
Tasks
|
89
|
+
#{tasks.map { |task, metadata| "#{task}#{' ' * (60 - task.size)}#{metadata['metadata']['description']}" }.join("\n").gsub(/^/, ' ')}
|
90
|
+
OUTPUT
|
91
|
+
end
|
92
|
+
|
93
|
+
def show_task_details(task_name, tasks)
|
94
|
+
metadata = tasks[task_name]
|
95
|
+
puts <<~OUTPUT
|
96
|
+
Task: '#{task_name}'
|
97
|
+
#{metadata['metadata']['description']}
|
98
|
+
|
99
|
+
#{metadata}
|
100
|
+
OUTPUT
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
desc 'tasks', 'Show and run Bolt tasks.'
|
106
|
+
subcommand 'tasks', CLI::Tasks
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/choria/colt.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'choria/colt/cache'
|
4
|
+
require 'choria/colt/version'
|
5
|
+
require 'choria/orchestrator'
|
6
|
+
require 'choria/orchestrator/task'
|
7
|
+
|
8
|
+
require 'logger'
|
9
|
+
|
10
|
+
module Choria
|
11
|
+
class Colt
|
12
|
+
class Error < StandardError; end
|
13
|
+
|
14
|
+
attr_reader :logger, :orchestrator
|
15
|
+
|
16
|
+
def initialize(logger: nil)
|
17
|
+
@logger = logger
|
18
|
+
|
19
|
+
@orchestrator = Choria::Orchestrator.new logger: @logger
|
20
|
+
end
|
21
|
+
|
22
|
+
def run_bolt_task(task_name, input: {}, targets: nil)
|
23
|
+
logger.debug "Instantiate task '#{task_name}' and validate input"
|
24
|
+
task = Choria::Orchestrator::Task.new(task_name, input: input, orchestrator: orchestrator)
|
25
|
+
|
26
|
+
orchestrator.run(task, targets: targets)
|
27
|
+
task.wait
|
28
|
+
task.results
|
29
|
+
rescue Choria::Orchestrator::Error => e
|
30
|
+
logger.error e.message
|
31
|
+
raise
|
32
|
+
end
|
33
|
+
|
34
|
+
def tasks(environment:, cache: nil)
|
35
|
+
tasks_names = orchestrator.tasks_support.tasks(environment).map do |task|
|
36
|
+
task['name']
|
37
|
+
end
|
38
|
+
|
39
|
+
def tasks_metadata(tasks, environment)
|
40
|
+
tasks.map do |task|
|
41
|
+
logger.debug "Fetching metadata for task '#{task}' (environment: '#{environment}')"
|
42
|
+
metadata = orchestrator.tasks_support.task_metadata(task, environment)
|
43
|
+
[task, metadata]
|
44
|
+
end.to_h
|
45
|
+
end
|
46
|
+
|
47
|
+
return tasks_metadata(tasks_names, environment) if cache.nil?
|
48
|
+
|
49
|
+
cached_tasks = cache.load
|
50
|
+
return cached_tasks if cache.clean? && cached_tasks.keys.sort == tasks_names.sort
|
51
|
+
|
52
|
+
updated_tasks = tasks_metadata(tasks_names, environment)
|
53
|
+
cache.save updated_tasks
|
54
|
+
|
55
|
+
updated_tasks
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Choria
|
2
|
+
class Orchestrator
|
3
|
+
class Task
|
4
|
+
class Error < Orchestrator::Error; end
|
5
|
+
|
6
|
+
attr_reader :name, :input, :environment, :rpc_results
|
7
|
+
attr_accessor :rpc_responses
|
8
|
+
|
9
|
+
def initialize(name, orchestrator:, input: {}, environment: 'production')
|
10
|
+
@name = name
|
11
|
+
@input = input
|
12
|
+
@environment = environment
|
13
|
+
@orchestrator = orchestrator
|
14
|
+
|
15
|
+
validate_inputs
|
16
|
+
end
|
17
|
+
|
18
|
+
def metadata
|
19
|
+
@metadata ||= _metadata
|
20
|
+
end
|
21
|
+
|
22
|
+
def files
|
23
|
+
metadata['files'].to_json
|
24
|
+
end
|
25
|
+
|
26
|
+
def wait
|
27
|
+
task_ids = rpc_responses.map { |res| res[:body][:data][:task_id] }.uniq
|
28
|
+
raise NotImplementedError, "Multiple task IDs: #{task_ids}" unless task_ids.count == 1
|
29
|
+
|
30
|
+
@rpc_results = @orchestrator.wait_results task_id: task_ids.first
|
31
|
+
end
|
32
|
+
|
33
|
+
def results
|
34
|
+
@rpc_results.map do |res|
|
35
|
+
raise NotImplementedError, 'What to do when res[:data][:stderr] contains something?' unless res[:data][:stderr].empty?
|
36
|
+
|
37
|
+
res[:result] = JSON.parse res[:data][:stdout]
|
38
|
+
res[:data].delete :stderr
|
39
|
+
res[:data].delete :stdout
|
40
|
+
res
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def _metadata
|
47
|
+
# puts 'Retrieving task metadata for task %s from the Puppet Server' % task if verbose
|
48
|
+
@orchestrator.tasks_support.task_metadata(@name, @environment)
|
49
|
+
rescue RuntimeError => e
|
50
|
+
raise Error, e.message
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate_inputs
|
54
|
+
ok, reason = @orchestrator.tasks_support.validate_task_inputs(@input, metadata)
|
55
|
+
raise Error, reason.sub(/^\n/, '') unless ok
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'English'
|
2
|
+
require 'mcollective'
|
3
|
+
|
4
|
+
module Choria
|
5
|
+
class Orchestrator
|
6
|
+
class Error < StandardError; end
|
7
|
+
class DiscoverError < Error; end
|
8
|
+
|
9
|
+
include MCollective::RPC
|
10
|
+
|
11
|
+
attr_reader :logger
|
12
|
+
|
13
|
+
def initialize(logger:)
|
14
|
+
@logger = logger
|
15
|
+
|
16
|
+
configfile ||= MCollective::Util.config_file_for_user
|
17
|
+
MCollective::Config.instance.loadconfig(configfile)
|
18
|
+
end
|
19
|
+
|
20
|
+
def tasks_support
|
21
|
+
@tasks_support ||= MCollective::Util::Choria.new.tasks_support
|
22
|
+
end
|
23
|
+
|
24
|
+
def run(task, targets: nil, verbose: false)
|
25
|
+
logger.debug "Running task: '#{task.name}' (targets: #{targets.nil? ? 'all' : targets})"
|
26
|
+
rpc_client.progress = verbose
|
27
|
+
|
28
|
+
targets&.each { |target| rpc_client.identity_filter target }
|
29
|
+
|
30
|
+
raise DiscoverError, 'No request sent, no node discovered' if rpc_client.discover.size.zero?
|
31
|
+
|
32
|
+
logger.info "Attempting to download and run task '#{task.name}' on #{rpc_client.discover.size} nodes"
|
33
|
+
|
34
|
+
rpc_client.download(task: task.name, files: task.files, verbose: verbose)
|
35
|
+
|
36
|
+
# TODO: Extract error from 'rpc' (see MCollective::RPC#printrpc)
|
37
|
+
|
38
|
+
responses = []
|
39
|
+
rpc_client.run_no_wait(task: task.name, files: task.files, input: task.input.to_json, verbose: verbose) do |response|
|
40
|
+
logger.debug " Response: '#{response}'"
|
41
|
+
responses << response
|
42
|
+
end
|
43
|
+
|
44
|
+
# TODO: Include stats in logs when logger will be available (see MCollective::RPC#printrpcstats)
|
45
|
+
|
46
|
+
task.rpc_responses = responses
|
47
|
+
end
|
48
|
+
|
49
|
+
def wait_results(task_id:)
|
50
|
+
raise 'Task ID is required!' if task_id.nil?
|
51
|
+
|
52
|
+
loop do
|
53
|
+
task_status_results = rpc_client.task_status(task_id: task_id).map(&:results)
|
54
|
+
logger.debug "Task ##{task_id} status: #{task_status_results}"
|
55
|
+
break if task_completed? task_status_results
|
56
|
+
end
|
57
|
+
|
58
|
+
task_status_results
|
59
|
+
end
|
60
|
+
|
61
|
+
def task_completed?(results)
|
62
|
+
results.each do |result|
|
63
|
+
return false unless result[:data][:completed]
|
64
|
+
end
|
65
|
+
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_rpc_result(result)
|
70
|
+
raise Error, "The RPC agent returned an error: #{result[:statusmsg]}" unless (result[:statuscode]).zero?
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def rpc_client
|
76
|
+
@rpc_client ||= rpcclient('bolt_tasks', options: rpc_options)
|
77
|
+
end
|
78
|
+
|
79
|
+
def rpc_options
|
80
|
+
{
|
81
|
+
verbose: false,
|
82
|
+
disctimeout: nil,
|
83
|
+
timeout: 5,
|
84
|
+
config: '/etc/choria/client.conf',
|
85
|
+
collective: 'mcollective',
|
86
|
+
discovery_method: nil,
|
87
|
+
discovery_options: [],
|
88
|
+
filter: {
|
89
|
+
'fact' => [], 'cf_class' => [], 'agent' => [], 'identity' => [], 'compound' => []
|
90
|
+
},
|
91
|
+
progress_bar: false,
|
92
|
+
mcollective_limit_targets: false,
|
93
|
+
batch_size: nil,
|
94
|
+
batch_sleep_time: 1,
|
95
|
+
output_format: :json,
|
96
|
+
}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/sig/choria/colt.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: choria-colt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Romuald Conty
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-03-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: choria-mcorpc-support
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: deep_merge
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: puppet
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Colt eases the Bolt tasks run through Choria
|
112
|
+
email:
|
113
|
+
- romuald@opus-codium.fr
|
114
|
+
executables:
|
115
|
+
- colt
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- ".rubocop.yml"
|
120
|
+
- Gemfile
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- choria-colt.gemspec
|
124
|
+
- exe/colt
|
125
|
+
- lib/choria/colt.rb
|
126
|
+
- lib/choria/colt/cache.rb
|
127
|
+
- lib/choria/colt/cli.rb
|
128
|
+
- lib/choria/colt/cli/thor.rb
|
129
|
+
- lib/choria/colt/version.rb
|
130
|
+
- lib/choria/orchestrator.rb
|
131
|
+
- lib/choria/orchestrator/task.rb
|
132
|
+
- sig/choria/colt.rbs
|
133
|
+
homepage: https://github.com/opus-codium/choria-colt
|
134
|
+
licenses: []
|
135
|
+
metadata:
|
136
|
+
homepage_uri: https://github.com/opus-codium/choria-colt
|
137
|
+
source_code_uri: https://github.com/opus-codium/choria-colt
|
138
|
+
changelog_uri: https://github.com/opus-codium/choria-colt/CHANGELOG.md
|
139
|
+
rubygems_mfa_required: 'true'
|
140
|
+
post_install_message:
|
141
|
+
rdoc_options: []
|
142
|
+
require_paths:
|
143
|
+
- lib
|
144
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: 2.5.0
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
requirements: []
|
155
|
+
rubygems_version: 3.1.2
|
156
|
+
signing_key:
|
157
|
+
specification_version: 4
|
158
|
+
summary: Bolt-like CLI to run Bolt tasks, through Choria
|
159
|
+
test_files: []
|