smart_proxy_remote_execution_ssh 0.8.0 → 0.9.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 +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
|