foreman_remote_execution 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/job_templates_controller.rb +2 -2
- data/app/helpers/remote_execution_helper.rb +5 -0
- data/app/models/job_template_importer.rb +24 -0
- data/app/models/setting/remote_execution.rb +4 -1
- data/app/models/ssh_execution_provider.rb +6 -1
- data/app/views/job_invocations/_tab_overview.html.erb +1 -1
- data/app/views/job_invocations/index.html.erb +1 -1
- data/app/views/job_invocations/show.html.erb +1 -1
- data/app/views/template_invocations/_output_line_set.html.erb +1 -1
- data/config/routes.rb +12 -0
- data/db/migrate/20160926225841_update_template_input_value.rb +5 -0
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/test/functional/api/v2/job_templates_controller_test.rb +10 -0
- data/test/unit/job_invocation_composer_test.rb +3 -2
- data/test/unit/job_template_importer_test.rb +48 -0
- data/test/unit/remote_execution_provider_test.rb +23 -0
- data/test/unit/template_invocation_input_value_test.rb +9 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a436dbf82dcf2ef9b040cdc5dfecf517dd25cc9e
|
4
|
+
data.tar.gz: 8f8d044eba9abcbb997d4299ba828700d29e71f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f27bc513effd681f1d186a264e1a1d289c3c164aabedf7fad48c90d3891eac9ce1a7f319e13196d532fe061f7b679e0d3f0da475688f72cf82d53f1c270826a1
|
7
|
+
data.tar.gz: b3f489e09fbad3cc4f69c8197f939bc7e3ed6a013f93b46989cf4f9f863509d73a87213715bd7f038d82a13a3a14a755da8321f096f890acaf8a99085a38bf52
|
@@ -167,6 +167,11 @@ module RemoteExecutionHelper
|
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
|
+
def invocation_description(invocation)
|
171
|
+
description = invocation.description.try(:capitalize) || invocation.job_category
|
172
|
+
trunc_with_tooltip(description, 80)
|
173
|
+
end
|
174
|
+
|
170
175
|
def invocation_result(invocation, key)
|
171
176
|
unknown = '—'
|
172
177
|
result = invocation_count(invocation, :output_key => key, :unknown_string => unknown.html_safe)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# This class is a shim to handle the importing of templates via the
|
2
|
+
# foreman_templates plugin. It expects a method like
|
3
|
+
# def import(name, text, metadata)
|
4
|
+
# but REx already has an import! method, so this class provides the
|
5
|
+
# translation layer.
|
6
|
+
|
7
|
+
class JobTemplateImporter
|
8
|
+
def self.import!(name, text, _metadata)
|
9
|
+
template = JobTemplate.import(
|
10
|
+
text.sub(/^name: .*$/, "name: #{name}").sub(/^model: .*$/, ''),
|
11
|
+
:update => true
|
12
|
+
)
|
13
|
+
|
14
|
+
c_or_u = template.new_record? ? 'Created' : 'Updated'
|
15
|
+
id_string = ('id' + template.id) rescue ''
|
16
|
+
|
17
|
+
result = " #{c_or_u} Template #{id_string}:#{name}"
|
18
|
+
{ :old => template.template_was,
|
19
|
+
:new => template.template,
|
20
|
+
:status => template.save,
|
21
|
+
:result => result
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
@@ -32,7 +32,10 @@ class Setting::RemoteExecution < Setting
|
|
32
32
|
{ :collection => Proc.new {Hash[SSHExecutionProvider::EFFECTIVE_USER_METHODS.map{|method| [method, method]}]} }),
|
33
33
|
self.set('remote_execution_sync_templates',
|
34
34
|
N_('Whether we should sync templates from disk when running db:seed.'),
|
35
|
-
true)
|
35
|
+
true),
|
36
|
+
self.set('remote_execution_ssh_port',
|
37
|
+
N_('Port to use for SSH communication. Default port 22. You may override per host by setting a parameter called remote_execution_ssh_port.'),
|
38
|
+
'22')
|
36
39
|
].each { |s| self.create! s.update(:category => 'Setting::RemoteExecution') }
|
37
40
|
end
|
38
41
|
|
@@ -6,7 +6,8 @@ class SSHExecutionProvider < RemoteExecutionProvider
|
|
6
6
|
def proxy_command_options(template_invocation, host)
|
7
7
|
super.merge(:ssh_user => ssh_user(host),
|
8
8
|
:effective_user => effective_user(template_invocation),
|
9
|
-
:effective_user_method => effective_user_method(host)
|
9
|
+
:effective_user_method => effective_user_method(host),
|
10
|
+
:ssh_port => ssh_port(host))
|
10
11
|
end
|
11
12
|
|
12
13
|
def humanized_name
|
@@ -23,6 +24,10 @@ class SSHExecutionProvider < RemoteExecutionProvider
|
|
23
24
|
host.params['remote_execution_ssh_user']
|
24
25
|
end
|
25
26
|
|
27
|
+
def ssh_port(host)
|
28
|
+
Integer(host.params['remote_execution_ssh_port'] || Setting[:remote_execution_ssh_port])
|
29
|
+
end
|
30
|
+
|
26
31
|
def effective_user(template_invocation)
|
27
32
|
template_invocation.effective_user
|
28
33
|
end
|
@@ -36,7 +36,7 @@
|
|
36
36
|
<%= _('following user inputs were provided') %>
|
37
37
|
<ul>
|
38
38
|
<% template_invocation.input_values.joins(:template_input).each do |input_value| %>
|
39
|
-
<li><b><%= input_value.template_input.name %></b>: <%= input_value.value %></li>
|
39
|
+
<li><b><%= input_value.template_input.name %></b>: <%= trunc_with_tooltip(input_value.value, 255) %></li>
|
40
40
|
<% end %>
|
41
41
|
</ul>
|
42
42
|
<% end %>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
<tbody>
|
19
19
|
<% @job_invocations.each do |invocation| %>
|
20
20
|
<tr>
|
21
|
-
<td><%= link_to_if_authorized
|
21
|
+
<td><%= link_to_if_authorized invocation_description(invocation), hash_for_job_invocation_path(invocation).merge(:auth_object => invocation, :permission => :view_job_invocations) %></td>
|
22
22
|
<td><%= link_to_invocation_task_if_authorized(invocation) %></td>
|
23
23
|
<td><%= invocation_result(invocation, :success_count) %></td>
|
24
24
|
<td><%= invocation_result(invocation, :failed_count) %></td>
|
@@ -2,6 +2,6 @@
|
|
2
2
|
<%= content_tag :div, :class => 'line ' + output_line_set['output_type'], :data => { :timestamp => output_line_set['timestamp'] } do %>
|
3
3
|
|
4
4
|
<%= content_tag(:span, (@line_counter += 1).to_s.rjust(4).gsub(' ', ' ').html_safe + ':', :class => 'counter', :title => (output_line_set['timestamp'] && Time.at(output_line_set['timestamp']))) %>
|
5
|
-
<%= content_tag(:div, (line.empty? ? ' ' : line).html_safe, :class => 'content') %>
|
5
|
+
<%= content_tag(:div, (line.empty? ? ' ' : h(line)).html_safe, :class => 'content') %>
|
6
6
|
<% end %>
|
7
7
|
<% end %>
|
data/config/routes.rb
CHANGED
@@ -55,6 +55,18 @@ Rails.application.routes.draw do
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
if SETTINGS[:organizations_enabled]
|
59
|
+
resources :organizations, :only => [:index] do
|
60
|
+
resources :job_templates, :only =>[:index, :show]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
if SETTINGS[:locations_enabled]
|
65
|
+
resources :locations, :only => [:index] do
|
66
|
+
resources :job_templates, :only =>[:index, :show]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
58
70
|
resources :templates, :only => :none do
|
59
71
|
resources :template_inputs, :only => [:index, :show, :create, :destroy, :update]
|
60
72
|
resources :foreign_input_sets, :only => [:index, :show, :create, :destroy, :update]
|
@@ -14,6 +14,16 @@ module Api
|
|
14
14
|
assert_response :success
|
15
15
|
end
|
16
16
|
|
17
|
+
test 'should get templates of give organization' do
|
18
|
+
@organization = FactoryGirl.create(:organization)
|
19
|
+
@template.organizations << @organization
|
20
|
+
@template.save!
|
21
|
+
get :index, :organization_id => @organization.id
|
22
|
+
templates = ActiveSupport::JSON.decode(@response.body)
|
23
|
+
assert !templates.empty?, 'Should respond with template'
|
24
|
+
assert_response :success
|
25
|
+
end
|
26
|
+
|
17
27
|
test 'should get template detail' do
|
18
28
|
get :show, :id => @template.to_param
|
19
29
|
assert_response :success
|
@@ -4,7 +4,7 @@ RemoteExecutionProvider.register(:Mcollective, OpenStruct)
|
|
4
4
|
|
5
5
|
describe JobInvocationComposer do
|
6
6
|
before do
|
7
|
-
permission1 =
|
7
|
+
permission1 = Permission.find_by_name('view_job_templates')
|
8
8
|
permission2 = Permission.find_by_name('view_bookmarks')
|
9
9
|
permission3 = Permission.find_by_name('view_hosts')
|
10
10
|
filter1 = FactoryGirl.build(:filter, :permissions => [permission1], :search => 'name ~ trying*')
|
@@ -17,7 +17,8 @@ describe JobInvocationComposer do
|
|
17
17
|
role.filters = filter1, filter2, filter3
|
18
18
|
role.save
|
19
19
|
User.current = FactoryGirl.build(:user)
|
20
|
-
User.current.
|
20
|
+
User.current.current_password = User.current.password
|
21
|
+
User.current.roles << role
|
21
22
|
User.current.save
|
22
23
|
end
|
23
24
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
|
3
|
+
describe JobTemplateImporter do
|
4
|
+
context 'importing a new template' do
|
5
|
+
# JobTemplate tests handle most of this, we just check that the shim
|
6
|
+
# correctly loads a template returns a hash
|
7
|
+
let(:remote_execution_feature) do
|
8
|
+
FactoryGirl.create(:remote_execution_feature)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:result) do
|
12
|
+
name = "Community Service Restart"
|
13
|
+
text = <<-END_TEMPLATE
|
14
|
+
<%#
|
15
|
+
model: JobTemplateImporter
|
16
|
+
kind: job_template
|
17
|
+
name: Service Restart
|
18
|
+
job_category: Service Restart
|
19
|
+
provider_type: SSH
|
20
|
+
feature: #{remote_execution_feature.label}
|
21
|
+
template_inputs:
|
22
|
+
- name: service_name
|
23
|
+
input_type: user
|
24
|
+
required: true
|
25
|
+
- name: verbose
|
26
|
+
input_type: user
|
27
|
+
%>
|
28
|
+
|
29
|
+
service <%= input("service_name") %> restart
|
30
|
+
END_TEMPLATE
|
31
|
+
|
32
|
+
# This parameter is unused but foreman_templates will supply it
|
33
|
+
# so we test it's accepted
|
34
|
+
metadata = "unused"
|
35
|
+
|
36
|
+
JobTemplateImporter.import!(name, text, metadata)
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:template) { JobTemplate.find_by_name 'Community Service Restart' }
|
40
|
+
|
41
|
+
it 'returns a valid foreman_templates hash' do
|
42
|
+
result[:status].must_equal true
|
43
|
+
result[:result].must_equal ' Created Template :Community Service Restart'
|
44
|
+
result[:old].must_equal nil
|
45
|
+
result[:new].must_equal template.template.squish
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -89,5 +89,28 @@ describe RemoteExecutionProvider do
|
|
89
89
|
proxy_options[:effective_user_method].must_equal 'su'
|
90
90
|
end
|
91
91
|
end
|
92
|
+
|
93
|
+
|
94
|
+
describe 'ssh port from settings' do
|
95
|
+
before do
|
96
|
+
Setting[:remote_execution_ssh_port] = '66'
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'has ssh port changed in settings and check return type' do
|
100
|
+
proxy_options[:ssh_port].must_be_kind_of Integer
|
101
|
+
proxy_options[:ssh_port].must_equal 66
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'ssh port from params' do
|
106
|
+
it 'takes ssh port number from params and check return type' do
|
107
|
+
host.params['remote_execution_ssh_port'] = '30'
|
108
|
+
host.host_parameters << FactoryGirl.build(:host_parameter, :name => 'remote_execution_ssh_port', :value => '30')
|
109
|
+
host.clear_host_parameters_cache!
|
110
|
+
proxy_options[:ssh_port].must_be_kind_of Integer
|
111
|
+
proxy_options[:ssh_port].must_equal 30
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
92
115
|
end
|
93
116
|
end
|
@@ -26,4 +26,13 @@ describe TemplateInvocationInputValue do
|
|
26
26
|
:value => 'foreman')
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
it 'supports large inputs' do
|
31
|
+
template.template_inputs << FactoryGirl.build(:template_input, :name => 'service_name',
|
32
|
+
:input_type => 'user', :required => true)
|
33
|
+
assert_valid FactoryGirl.create(:template_invocation_input_value,
|
34
|
+
:template_invocation => template_invocation,
|
35
|
+
:template_input => template.template_inputs.first,
|
36
|
+
:value => 'foreman' * 1000000)
|
37
|
+
end
|
29
38
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_remote_execution
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman Remote Execution team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|
@@ -198,6 +198,7 @@ files:
|
|
198
198
|
- app/models/job_invocation_task_group.rb
|
199
199
|
- app/models/job_template.rb
|
200
200
|
- app/models/job_template_effective_user.rb
|
201
|
+
- app/models/job_template_importer.rb
|
201
202
|
- app/models/remote_execution_feature.rb
|
202
203
|
- app/models/remote_execution_provider.rb
|
203
204
|
- app/models/setting/remote_execution.rb
|
@@ -310,6 +311,7 @@ files:
|
|
310
311
|
- db/migrate/20160127134031_add_advanced_to_template_input.rb
|
311
312
|
- db/migrate/20160127162711_reword_puppet_template_description.rb
|
312
313
|
- db/migrate/20160203104056_add_concurrency_options_to_job_invocation.rb
|
314
|
+
- db/migrate/20160926225841_update_template_input_value.rb
|
313
315
|
- db/seeds.d/60-ssh_proxy_feature.rb
|
314
316
|
- db/seeds.d/70-job_templates.rb
|
315
317
|
- db/seeds.d/90-bookmarks.rb
|
@@ -398,6 +400,7 @@ files:
|
|
398
400
|
- test/unit/job_invocation_composer_test.rb
|
399
401
|
- test/unit/job_invocation_test.rb
|
400
402
|
- test/unit/job_template_effective_user_test.rb
|
403
|
+
- test/unit/job_template_importer_test.rb
|
401
404
|
- test/unit/job_template_test.rb
|
402
405
|
- test/unit/remote_execution_feature_test.rb
|
403
406
|
- test/unit/remote_execution_provider_test.rb
|
@@ -446,6 +449,7 @@ test_files:
|
|
446
449
|
- test/unit/job_invocation_composer_test.rb
|
447
450
|
- test/unit/job_invocation_test.rb
|
448
451
|
- test/unit/job_template_effective_user_test.rb
|
452
|
+
- test/unit/job_template_importer_test.rb
|
449
453
|
- test/unit/job_template_test.rb
|
450
454
|
- test/unit/remote_execution_feature_test.rb
|
451
455
|
- test/unit/remote_execution_provider_test.rb
|