hammer_cli_foreman_remote_execution 0.0.1
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/.gitignore +20 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +7 -0
- data/Gemfile +19 -0
- data/LICENSE +11 -0
- data/README.md +61 -0
- data/Rakefile +30 -0
- data/config/foreman_remote_execution.yml +2 -0
- data/hammer_cli_foreman_remote_execution.gemspec +21 -0
- data/lib/hammer_cli_foreman_remote_execution/i18n.rb +21 -0
- data/lib/hammer_cli_foreman_remote_execution/job_invocation.rb +111 -0
- data/lib/hammer_cli_foreman_remote_execution/job_template.rb +93 -0
- data/lib/hammer_cli_foreman_remote_execution/options/normalizers.rb +25 -0
- data/lib/hammer_cli_foreman_remote_execution/template_input.rb +49 -0
- data/lib/hammer_cli_foreman_remote_execution/version.rb +5 -0
- data/lib/hammer_cli_foreman_remote_execution.rb +14 -0
- data/test/unit/data/1.10/foreman_api.json +1 -0
- data/test/unit/data/template.txt +1 -0
- data/test/unit/job_invocation_test.rb +51 -0
- data/test/unit/job_template_test.rb +79 -0
- data/test/unit/template_input_test.rb +51 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bc6f8140afdb51443d73dcb66d8031d54d7a4eb6
|
4
|
+
data.tar.gz: edcfa63f45a679e4042bf9c1462735a3450c6085
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0957feb73b6107cf06abec25691e27842040b26eb98346d9375eb3a787b3a5acc6855fcdb7e75b1d2616b12e07eec8ad176eba7086159bf319910affafb7c8ea
|
7
|
+
data.tar.gz: 08ba0281f7f6a50f54d71aecc4d88b58e66ba34332f6350d50809fcbb559899b95dcf361c2ddc4706aefde0922fb125cbdc623a604c0c3dbefa4d7c09cb68374
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem 'gettext', '>= 3.1.3', '< 4.0.0'
|
6
|
+
|
7
|
+
group :test do
|
8
|
+
gem 'rake', '~> 10.1.0'
|
9
|
+
gem 'thor'
|
10
|
+
gem 'minitest', '< 5.0.0'
|
11
|
+
gem 'minitest-spec-context'
|
12
|
+
gem 'simplecov'
|
13
|
+
gem 'mocha'
|
14
|
+
gem 'ci_reporter', '>= 1.6.3', "< 2.0.0", :require => false
|
15
|
+
end
|
16
|
+
|
17
|
+
# load local gemfile
|
18
|
+
local_gemfile = File.join(File.dirname(__FILE__), 'Gemfile.local')
|
19
|
+
self.instance_eval(Bundler.read_file(local_gemfile)) if File.exist?(local_gemfile)
|
data/LICENSE
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
This program and entire repository is free software: you can redistribute it
|
2
|
+
and/or modify it under the terms of the GNU General Public License as published
|
3
|
+
by the Free Software Foundation, either version 3 of the License, or any later
|
4
|
+
version.
|
5
|
+
|
6
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
7
|
+
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
8
|
+
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
9
|
+
|
10
|
+
You should have received a copy of the GNU General Public License along with
|
11
|
+
this program. If not, see http://www.gnu.org/licenses/.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
CLI Plugin for Foreman Remote Execution
|
2
|
+
=======================================
|
3
|
+
|
4
|
+
This [Hammer CLI](https://github.com/theforeman/hammer-cli) plugin contains commands for [foreman_remote_execution](https://github.com/theforeman/foreman_remote_execution).
|
5
|
+
|
6
|
+
Examples
|
7
|
+
--------
|
8
|
+
|
9
|
+
### Create a Template
|
10
|
+
|
11
|
+
```
|
12
|
+
hammer job-template create --file /tmp/template.txt --name "Ping a Host"\
|
13
|
+
--provider-type Ssh --job-name "Ping"
|
14
|
+
```
|
15
|
+
|
16
|
+
### Create a Template Input
|
17
|
+
|
18
|
+
```
|
19
|
+
hammer template-input create --template-id 17 --name hostname\
|
20
|
+
--input-type user --options www.google.com,www.facebook.com,localhost
|
21
|
+
```
|
22
|
+
|
23
|
+
### Run a Job Examples
|
24
|
+
|
25
|
+
#### Command line inputs
|
26
|
+
|
27
|
+
```
|
28
|
+
hammer job-invocation create --job-name "Run Command" --inputs command="ping -c 50 www.google.com"\
|
29
|
+
--search-query "name ~ rex01"
|
30
|
+
```
|
31
|
+
|
32
|
+
```
|
33
|
+
hammer job-invocation create --job-name "Package Action"\
|
34
|
+
--inputs package=vim-enhanced,action=install --search-query "name ~ rex01"
|
35
|
+
```
|
36
|
+
|
37
|
+
#### File inputs:
|
38
|
+
|
39
|
+
```
|
40
|
+
hammer job-invocation create --job-name "Run Command"\
|
41
|
+
--input-files command=/tmp/script.sh --search-query "name ~ rex01"
|
42
|
+
```
|
43
|
+
|
44
|
+
### Show output
|
45
|
+
|
46
|
+
If the job is currently running, this will refresh until the job completes.
|
47
|
+
|
48
|
+
```
|
49
|
+
hammer job-invocation output --id 155 --host rex01.example.com
|
50
|
+
```
|
51
|
+
|
52
|
+
Alternatively, pass the `--async` option to see the output so far:
|
53
|
+
|
54
|
+
```
|
55
|
+
hammer job-invocation output --id 155 --host rex01.example.com --async
|
56
|
+
```
|
57
|
+
|
58
|
+
License
|
59
|
+
-------
|
60
|
+
|
61
|
+
This project is licensed under the GPLv3+.
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'ci/reporter/rake/minitest'
|
4
|
+
|
5
|
+
Rake::TestTask.new :test do |t|
|
6
|
+
t.libs.push "lib"
|
7
|
+
t.test_files = Dir.glob('test/**/*_test.rb')
|
8
|
+
t.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace :gettext do
|
12
|
+
desc 'Update pot file'
|
13
|
+
task :find do
|
14
|
+
require 'hammer_cli_foreman_remote_execution/version'
|
15
|
+
require 'hammer_cli_foreman_remote_execution/i18n'
|
16
|
+
require 'gettext/tools'
|
17
|
+
|
18
|
+
domain = HammerCLIForemanRemoteExecution::I18n::LocaleDomain.new
|
19
|
+
GetText.update_pofiles(domain.domain_name, domain.translated_files,
|
20
|
+
"#{domain.domain_name} #{HammerCLIForemanRemoteExecution.version}",
|
21
|
+
:po_root => domain.locale_dir)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
namespace :pkg do
|
26
|
+
desc 'Generate package source gem'
|
27
|
+
task :generate_source => :build
|
28
|
+
end
|
29
|
+
|
30
|
+
task :default => :test
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path('../lib/hammer_cli_foreman_remote_execution/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'hammer_cli_foreman_remote_execution'
|
5
|
+
s.version = HammerCLIForemanRemoteExecution.version.dup
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ['Foreman Remote Execution team']
|
8
|
+
s.email = ['foreman-dev@googlegroups.com']
|
9
|
+
s.homepage = 'http://github.com/theforeman/hammer_cli_foreman_remote_execution'
|
10
|
+
s.license = 'GPL v3+'
|
11
|
+
|
12
|
+
s.summary = 'CLI for the Foreman remote execution plugin'
|
13
|
+
s.description = 'CLI for the Foreman remote execution plugin'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files test`.split("\n")
|
17
|
+
s.extra_rdoc_files = `git ls-files doc`.split("\n") + Dir['README*', 'LICENSE']
|
18
|
+
|
19
|
+
s.add_dependency 'hammer_cli_foreman', '>= 0.1.3', '< 0.5.0'
|
20
|
+
s.add_dependency 'hammer_cli_foreman_tasks', '~> 0.0.3'
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'hammer_cli/i18n'
|
2
|
+
|
3
|
+
module HammerCLIForemanRemoteExecution
|
4
|
+
module I18n
|
5
|
+
class LocaleDomain < HammerCLI::I18n::LocaleDomain
|
6
|
+
def translated_files
|
7
|
+
Dir.glob(File.join(File.dirname(__FILE__), '../**/*.rb'))
|
8
|
+
end
|
9
|
+
|
10
|
+
def locale_dir
|
11
|
+
File.join(File.dirname(__FILE__), '../../locale')
|
12
|
+
end
|
13
|
+
|
14
|
+
def domain_name
|
15
|
+
'hammer-cli-foreman-remote-execution'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
HammerCLI::I18n.add_domain(HammerCLIForemanRemoteExecution::I18n::LocaleDomain.new)
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module HammerCLIForemanRemoteExecution
|
2
|
+
class JobInvocation < HammerCLIForeman::Command
|
3
|
+
resource :job_invocations
|
4
|
+
|
5
|
+
class ListCommand < HammerCLIForeman::ListCommand
|
6
|
+
output do
|
7
|
+
field :id, _('Id')
|
8
|
+
field :job_name, _('Name')
|
9
|
+
field :state, _('Task State')
|
10
|
+
end
|
11
|
+
|
12
|
+
def extend_data(invocation)
|
13
|
+
JobInvocation.extend_data(invocation)
|
14
|
+
end
|
15
|
+
|
16
|
+
build_options
|
17
|
+
end
|
18
|
+
|
19
|
+
class InfoCommand < HammerCLIForeman::InfoCommand
|
20
|
+
output ListCommand.output_definition do
|
21
|
+
field :hosts, _('Hosts')
|
22
|
+
end
|
23
|
+
|
24
|
+
def extend_data(invocation)
|
25
|
+
JobInvocation.extend_data(invocation)
|
26
|
+
end
|
27
|
+
|
28
|
+
build_options do |o|
|
29
|
+
o.expand(:none)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class OutputCommand < HammerCLIForeman::Command
|
34
|
+
action :output
|
35
|
+
command_name 'output'
|
36
|
+
desc _('View the output for a host')
|
37
|
+
|
38
|
+
option '--async', :flag, N_('Do not wait for job to complete, shows current output only')
|
39
|
+
|
40
|
+
def print_data(output)
|
41
|
+
line_set = output['output'].sort_by { |lines| lines['timestamp'].to_f }
|
42
|
+
since = nil
|
43
|
+
|
44
|
+
line_set.each do |line|
|
45
|
+
puts line['output']
|
46
|
+
since = line['timestamp']
|
47
|
+
end
|
48
|
+
|
49
|
+
if output['refresh'] && !option_async?
|
50
|
+
sleep 1
|
51
|
+
print_data(resource.call(action, request_params.merge(:since => since), request_headers, request_options))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
build_options do |o|
|
56
|
+
o.expand(:all).except(:job_invocations)
|
57
|
+
o.without(:since)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class CreateCommand < HammerCLIForeman::CreateCommand
|
62
|
+
include HammerCLIForemanTasks::Async
|
63
|
+
|
64
|
+
success_message _('Job invocation %{id} started')
|
65
|
+
|
66
|
+
option '--inputs', 'INPUTS', N_('Specify inputs from command line'),
|
67
|
+
:format => HammerCLI::Options::Normalizers::KeyValueList.new
|
68
|
+
|
69
|
+
# For passing larger scripts, etc.
|
70
|
+
option '--input-files', 'INPUT FILES', N_('Read input values from files'),
|
71
|
+
:format => ::HammerCLIForemanRemoteExecution::Options::Normalizers::KeyFileList.new
|
72
|
+
|
73
|
+
option '--dynamic', :flag, N_('Dynamic search queries are evaluated at run time')
|
74
|
+
|
75
|
+
def request_params
|
76
|
+
params = super
|
77
|
+
|
78
|
+
cli_inputs = option_inputs || {}
|
79
|
+
file_inputs = option_input_files || {}
|
80
|
+
params['job_invocation']['inputs'] = cli_inputs.merge(file_inputs)
|
81
|
+
|
82
|
+
params['job_invocation']['targeting_type'] = option_dynamic? ? 'dynamic_query' : 'static_query'
|
83
|
+
params
|
84
|
+
end
|
85
|
+
|
86
|
+
def task_progress(task_or_id)
|
87
|
+
print_message(success_message, task_or_id)
|
88
|
+
task = task_or_id['dynflow_task']['id']
|
89
|
+
super(task)
|
90
|
+
end
|
91
|
+
|
92
|
+
build_options do |o|
|
93
|
+
o.without(:targeting_type)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.extend_data(invocation)
|
98
|
+
invocation['state'] = invocation['dynflow_task'] ? invocation['dynflow_task']['state'] : _('unknown')
|
99
|
+
|
100
|
+
if invocation['targeting'] && invocation['targeting']['hosts']
|
101
|
+
invocation['hosts'] = "\n" + invocation['targeting']['hosts'].map { |host| " - #{host['name']}" }.join("\n")
|
102
|
+
end
|
103
|
+
|
104
|
+
invocation
|
105
|
+
end
|
106
|
+
|
107
|
+
autoload_subcommands
|
108
|
+
end
|
109
|
+
|
110
|
+
HammerCLI::MainCommand.subcommand 'job-invocation', _('Manage job invocations'), JobInvocation
|
111
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module HammerCLIForemanRemoteExecution
|
2
|
+
class JobTemplate < HammerCLIForeman::Command
|
3
|
+
resource :job_templates
|
4
|
+
|
5
|
+
class ListCommand < HammerCLIForeman::ListCommand
|
6
|
+
output do
|
7
|
+
field :id, _('Id')
|
8
|
+
field :name, _('Name')
|
9
|
+
field :job_name, _('Job Name')
|
10
|
+
field :provider_type, _('Provider')
|
11
|
+
field :type, _('Type')
|
12
|
+
end
|
13
|
+
|
14
|
+
def extend_data(template)
|
15
|
+
JobTemplate.data_extensions(template)
|
16
|
+
end
|
17
|
+
|
18
|
+
build_options
|
19
|
+
end
|
20
|
+
|
21
|
+
class InfoCommand < HammerCLIForeman::InfoCommand
|
22
|
+
output ListCommand.output_definition do
|
23
|
+
field :template_inputs, _('Inputs')
|
24
|
+
HammerCLIForeman::References.taxonomies(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def extend_data(template)
|
28
|
+
JobTemplate.data_extensions(template)
|
29
|
+
end
|
30
|
+
|
31
|
+
build_options
|
32
|
+
end
|
33
|
+
|
34
|
+
class DumpCommand < HammerCLIForeman::InfoCommand
|
35
|
+
command_name 'dump'
|
36
|
+
desc _('View job template content')
|
37
|
+
|
38
|
+
def print_data(template)
|
39
|
+
puts template['template']
|
40
|
+
end
|
41
|
+
|
42
|
+
build_options
|
43
|
+
end
|
44
|
+
|
45
|
+
class CreateCommand < HammerCLIForeman::CreateCommand
|
46
|
+
option '--file', 'TEMPLATE', N_('Path to a file that contains the template'),
|
47
|
+
:attribute_name => :option_template, :required => true,
|
48
|
+
:format => HammerCLI::Options::Normalizers::File.new
|
49
|
+
|
50
|
+
success_message _('Job template created')
|
51
|
+
failure_message _('Could not create the job template')
|
52
|
+
|
53
|
+
build_options do |o|
|
54
|
+
o.without(:template)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class UpdateCommand < HammerCLIForeman::UpdateCommand
|
59
|
+
option '--file', 'TEMPLATE', N_('Path to a file that contains the template'),
|
60
|
+
:attribute_name => :option_template,
|
61
|
+
:format => HammerCLI::Options::Normalizers::File.new
|
62
|
+
|
63
|
+
success_message _('Job template updated')
|
64
|
+
failure_message _('Could not update the job template')
|
65
|
+
|
66
|
+
build_options do |o|
|
67
|
+
o.without(:template)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class DeleteCommand < HammerCLIForeman::DeleteCommand
|
72
|
+
success_message _('Job template deleted')
|
73
|
+
failure_message _('Could not delete the job template')
|
74
|
+
|
75
|
+
build_options
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.data_extensions(template)
|
79
|
+
template['type'] = template['snippet'] ? 'snippet' : 'job_template'
|
80
|
+
|
81
|
+
if template['template_inputs']
|
82
|
+
template_inputs = template['template_inputs'].map { |option| " - #{option['name']}" }.join("\n")
|
83
|
+
template['template_inputs'] = "\n#{template_inputs}\n"
|
84
|
+
end
|
85
|
+
|
86
|
+
template
|
87
|
+
end
|
88
|
+
|
89
|
+
autoload_subcommands
|
90
|
+
end
|
91
|
+
|
92
|
+
HammerCLI::MainCommand.subcommand 'job-template', _('Manage job templates'), JobTemplate
|
93
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module HammerCLIForemanRemoteExecution
|
2
|
+
module Options
|
3
|
+
module Normalizers
|
4
|
+
class KeyFileList < ::HammerCLI::Options::Normalizers::KeyValueList
|
5
|
+
def description
|
6
|
+
_('Comma-separated list of key=file, where file is a path to a text file to be read')
|
7
|
+
end
|
8
|
+
|
9
|
+
def format(val)
|
10
|
+
Hash[super.map { |key, path| [key, ::File.read(::File.expand_path(path))] }]
|
11
|
+
end
|
12
|
+
|
13
|
+
def complete(value)
|
14
|
+
Dir[value.to_s+'*'].collect do |file|
|
15
|
+
if ::File.directory?(file)
|
16
|
+
file+'/'
|
17
|
+
else
|
18
|
+
file+' '
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module HammerCLIForemanRemoteExecution
|
2
|
+
class TemplateInput < HammerCLIForeman::Command
|
3
|
+
resource :template_inputs
|
4
|
+
desc _('Manage template inputs')
|
5
|
+
|
6
|
+
class ListCommand < HammerCLIForeman::ListCommand
|
7
|
+
output do
|
8
|
+
field :id, _('Id')
|
9
|
+
field :name, _('Name')
|
10
|
+
field :input_type, _('Input type')
|
11
|
+
end
|
12
|
+
|
13
|
+
build_options
|
14
|
+
end
|
15
|
+
|
16
|
+
class InfoCommand < HammerCLIForeman::InfoCommand
|
17
|
+
output do
|
18
|
+
field :id, _('Id')
|
19
|
+
field :name, _('Name')
|
20
|
+
field :input_type, _('Input type')
|
21
|
+
|
22
|
+
field :fact_name, _('Fact name')
|
23
|
+
field :variable_name, _('Variable name')
|
24
|
+
field :puppet_parameter_name, _('Puppet parameter name')
|
25
|
+
field :options, _('Options'), Fields::List, :width => 25, :hide_blank => true
|
26
|
+
end
|
27
|
+
|
28
|
+
build_options
|
29
|
+
end
|
30
|
+
|
31
|
+
class CreateCommand < HammerCLIForeman::CreateCommand
|
32
|
+
success_message _('Template input created')
|
33
|
+
failure_message _('Could not create the template input')
|
34
|
+
|
35
|
+
build_options
|
36
|
+
end
|
37
|
+
|
38
|
+
class DeleteCommand < HammerCLIForeman::DeleteCommand
|
39
|
+
success_message _('Template input deleted')
|
40
|
+
failure_message _('Could not delete the template input')
|
41
|
+
|
42
|
+
build_options
|
43
|
+
end
|
44
|
+
|
45
|
+
autoload_subcommands
|
46
|
+
end
|
47
|
+
|
48
|
+
HammerCLI::MainCommand.subcommand 'template-input', _('Manage template inputs'), TemplateInput
|
49
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'hammer_cli'
|
2
|
+
require 'hammer_cli_foreman'
|
3
|
+
require 'hammer_cli_foreman_tasks'
|
4
|
+
|
5
|
+
module HammerCLIForemanRemoteExecution
|
6
|
+
require 'hammer_cli_foreman_remote_execution/options/normalizers'
|
7
|
+
require 'hammer_cli_foreman_remote_execution/job_invocation'
|
8
|
+
require 'hammer_cli_foreman_remote_execution/job_template'
|
9
|
+
require 'hammer_cli_foreman_remote_execution/template_input'
|
10
|
+
|
11
|
+
def self.exception_handler_class
|
12
|
+
HammerCLIForeman::ExceptionHandler
|
13
|
+
end
|
14
|
+
end
|