smart_proxy_remote_execution_ssh 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/smart_proxy_remote_execution_ssh/actions/pull_script.rb +34 -2
- data/lib/smart_proxy_remote_execution_ssh/api.rb +1 -0
- data/lib/smart_proxy_remote_execution_ssh/command_logging.rb +1 -1
- data/lib/smart_proxy_remote_execution_ssh/job_storage.rb +4 -2
- data/lib/smart_proxy_remote_execution_ssh/multiplexed_ssh_connection.rb +4 -4
- data/lib/smart_proxy_remote_execution_ssh/plugin.rb +2 -1
- data/lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb +0 -1
- data/lib/smart_proxy_remote_execution_ssh/version.rb +1 -1
- data/settings.d/remote_execution_ssh.yml.example +4 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f28e2eb48888626dad82eb56e7a5309da15d584e6d4c53eaf648e5ddfc6f3d1e
|
4
|
+
data.tar.gz: a5b604d80264dc78b461e1792100ecd6fc9a4a71791b8df5b064bd80a32f6920
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3231a3d465b180d1b8b325fd9fc341c009b566452946ee56837f9f37e6502d7095d1a213bc5b4b13078b9d54e5bd592f5430aea502ecdee93edab15901440815
|
7
|
+
data.tar.gz: 62e77d3cf6d37c90b2e6e8e48ad8b2080186a50fd1d3633b38743a099e0897b9b1e4d4dafaf7b02b1855dcd51036d418333c156438c3b20e5fa42feac93ded17
|
@@ -5,6 +5,8 @@ require 'time'
|
|
5
5
|
module Proxy::RemoteExecution::Ssh::Actions
|
6
6
|
class PullScript < Proxy::Dynflow::Action::Runner
|
7
7
|
JobDelivered = Class.new
|
8
|
+
PickupTimeout = Class.new
|
9
|
+
ResendNotification = Class.new
|
8
10
|
|
9
11
|
execution_plan_hooks.use :cleanup, :on => :stopped
|
10
12
|
|
@@ -17,9 +19,20 @@ module Proxy::RemoteExecution::Ssh::Actions
|
|
17
19
|
if event == JobDelivered
|
18
20
|
output[:state] = :delivered
|
19
21
|
suspend
|
22
|
+
elsif event == PickupTimeout
|
23
|
+
process_pickup_timeout
|
24
|
+
elsif event == ResendNotification
|
25
|
+
if input[:with_mqtt] && %w(ready_for_pickup notified).include?(output[:state])
|
26
|
+
schedule_mqtt_resend
|
27
|
+
mqtt_start(::Proxy::Dynflow::OtpManager.passwords[execution_plan_id])
|
28
|
+
end
|
29
|
+
suspend
|
20
30
|
else
|
21
31
|
super
|
22
32
|
end
|
33
|
+
rescue => e
|
34
|
+
action_logger.error(e)
|
35
|
+
process_update(Proxy::Dynflow::Runner::Update.encode_exception('Proxy error', e))
|
23
36
|
end
|
24
37
|
|
25
38
|
def init_run
|
@@ -27,10 +40,15 @@ module Proxy::RemoteExecution::Ssh::Actions
|
|
27
40
|
::Proxy::Dynflow::OtpManager.generate_otp(execution_plan_id)
|
28
41
|
end
|
29
42
|
|
30
|
-
input[:
|
43
|
+
plan_event(PickupTimeout, input[:time_to_pickup], optional: true) if input[:time_to_pickup]
|
44
|
+
|
45
|
+
input[:job_uuid] = job_storage.store_job(host_name, execution_plan_id, run_step_id, input[:script].tr("\r", ''), effective_user: input[:effective_user])
|
31
46
|
output[:state] = :ready_for_pickup
|
32
47
|
output[:result] = []
|
33
|
-
|
48
|
+
if input[:with_mqtt]
|
49
|
+
schedule_mqtt_resend
|
50
|
+
mqtt_start(otp_password)
|
51
|
+
end
|
34
52
|
suspend
|
35
53
|
end
|
36
54
|
|
@@ -103,6 +121,8 @@ module Proxy::RemoteExecution::Ssh::Actions
|
|
103
121
|
'username': execution_plan_id,
|
104
122
|
'password': otp_password,
|
105
123
|
'return_url': "#{input[:proxy_url]}/ssh/jobs/#{input[:job_uuid]}/update",
|
124
|
+
'version': 'v1',
|
125
|
+
'effective_user': input[:effective_user]
|
106
126
|
},
|
107
127
|
)
|
108
128
|
mqtt_notify payload
|
@@ -164,5 +184,17 @@ module Proxy::RemoteExecution::Ssh::Actions
|
|
164
184
|
directive: 'foreman'
|
165
185
|
}
|
166
186
|
end
|
187
|
+
|
188
|
+
def process_pickup_timeout
|
189
|
+
if output[:state] != :delivered
|
190
|
+
raise "The job was not picked up in time"
|
191
|
+
else
|
192
|
+
suspend
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def schedule_mqtt_resend
|
197
|
+
plan_event(ResendNotification, settings[:mqtt_resend_interval], optional: true)
|
198
|
+
end
|
167
199
|
end
|
168
200
|
end
|
@@ -14,7 +14,7 @@ module Proxy::RemoteExecution::Ssh::Runners
|
|
14
14
|
logger.debug(line.chomp) if user_method.nil? || !user_method.filter_password?(line)
|
15
15
|
user_method.on_data(data, pm.stdin) if user_method
|
16
16
|
end
|
17
|
-
|
17
|
+
data
|
18
18
|
end
|
19
19
|
pm.on_stdout(&callback)
|
20
20
|
pm.on_stderr(&callback)
|
@@ -11,6 +11,7 @@ module Proxy::RemoteExecution::Ssh
|
|
11
11
|
String :hostname, null: false, index: true
|
12
12
|
String :execution_plan_uuid, fixed: true, size: 36, null: false, index: true
|
13
13
|
Integer :run_step_id, null: false
|
14
|
+
String :effective_user
|
14
15
|
String :job, text: true
|
15
16
|
end
|
16
17
|
end
|
@@ -24,13 +25,14 @@ module Proxy::RemoteExecution::Ssh
|
|
24
25
|
.select_map(:uuid)
|
25
26
|
end
|
26
27
|
|
27
|
-
def store_job(hostname, execution_plan_uuid, run_step_id, job, uuid: SecureRandom.uuid, timestamp: Time.now.utc)
|
28
|
+
def store_job(hostname, execution_plan_uuid, run_step_id, job, uuid: SecureRandom.uuid, timestamp: Time.now.utc, effective_user: nil)
|
28
29
|
jobs.insert(timestamp: timestamp,
|
29
30
|
uuid: uuid,
|
30
31
|
hostname: hostname,
|
31
32
|
execution_plan_uuid: execution_plan_uuid,
|
32
33
|
run_step_id: run_step_id,
|
33
|
-
job: job
|
34
|
+
job: job,
|
35
|
+
effective_user: effective_user)
|
34
36
|
uuid
|
35
37
|
end
|
36
38
|
|
@@ -32,7 +32,7 @@ module Proxy::RemoteExecution::Ssh::Runners
|
|
32
32
|
return [] unless @password
|
33
33
|
|
34
34
|
prompt = ['-P', @prompt] if @prompt
|
35
|
-
[{'SSHPASS' => SensitiveString.new(@password)}, '
|
35
|
+
[{'SSHPASS' => SensitiveString.new(@password)}, 'sshpass', '-e', prompt].compact
|
36
36
|
end
|
37
37
|
|
38
38
|
def ssh_options
|
@@ -93,7 +93,7 @@ module Proxy::RemoteExecution::Ssh::Runners
|
|
93
93
|
def command(cmd)
|
94
94
|
raise "Cannot build command to run over multiplexed connection without having an established connection" unless connected?
|
95
95
|
|
96
|
-
['
|
96
|
+
['ssh', reuse_ssh_options, cmd].flatten
|
97
97
|
end
|
98
98
|
|
99
99
|
private
|
@@ -103,7 +103,7 @@ module Proxy::RemoteExecution::Ssh::Runners
|
|
103
103
|
# does not close its stderr which trips up the process manager which
|
104
104
|
# expects all FDs to be closed
|
105
105
|
|
106
|
-
full_command = [method.ssh_command_prefix, '
|
106
|
+
full_command = [method.ssh_command_prefix, 'ssh', establish_ssh_options, method.ssh_options, @host, 'true'].flatten
|
107
107
|
log_command(full_command)
|
108
108
|
pm = Proxy::Dynflow::ProcessManager.new(full_command)
|
109
109
|
pm.start!
|
@@ -166,7 +166,7 @@ module Proxy::RemoteExecution::Ssh::Runners
|
|
166
166
|
end
|
167
167
|
|
168
168
|
def verify_key_passphrase
|
169
|
-
command = ['
|
169
|
+
command = ['ssh-keygen', '-y', '-f', File.expand_path(@client_private_key_file)]
|
170
170
|
log_command(command, label: "Checking if private key has passphrase")
|
171
171
|
pm = Proxy::Dynflow::ProcessManager.new(command)
|
172
172
|
pm.start!
|
@@ -133,7 +133,6 @@ module Proxy::RemoteExecution::Ssh::Runners
|
|
133
133
|
def cleanup
|
134
134
|
if @cleanup_working_dirs
|
135
135
|
ensure_remote_command("rm -rf #{remote_command_dir}",
|
136
|
-
publish: true,
|
137
136
|
error: "Unable to remove working directory #{remote_command_dir} on remote system, exit code: %{exit_code}")
|
138
137
|
end
|
139
138
|
end
|
@@ -32,3 +32,7 @@
|
|
32
32
|
# unset, SSL gets used if smart-proxy's foreman_ssl_cert, foreman_ssl_key and
|
33
33
|
# foreman_ssl_ca settings are set available.
|
34
34
|
# :mqtt_tls:
|
35
|
+
|
36
|
+
# The notification is sent over mqtt every $mqtt_resend_interval seconds, until
|
37
|
+
# the job is picked up by the host or cancelled
|
38
|
+
# :mqtt_resend_interval: 900
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_proxy_remote_execution_ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Nečas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -205,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
205
205
|
- !ruby/object:Gem::Version
|
206
206
|
version: '0'
|
207
207
|
requirements: []
|
208
|
-
rubygems_version: 3.
|
208
|
+
rubygems_version: 3.3.20
|
209
209
|
signing_key:
|
210
210
|
specification_version: 4
|
211
211
|
summary: Ssh remote execution provider for Foreman Smart-Proxy
|