Skip to content

Commit 20e9684

Browse files
committed
Use more native methods of SmartProxy for validation
This uses more built in validators. It also creates a setting for the public key file and derives it if not specified. The only downside is that the validate_readable doesn't print a helpful command to generate it if needed. Programmable settings can be used to generate it on the fly if the parent directory is readable. Another alternative is to introduce another custom validator. It slightly abuses the dependency injection hook to configure the task launcher registry.
1 parent ee17ca9 commit 20e9684

File tree

3 files changed

+52
-44
lines changed

3 files changed

+52
-44
lines changed

lib/smart_proxy_remote_execution_ssh.rb

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,50 +6,12 @@
66
module Proxy::RemoteExecution
77
module Ssh
88
class << self
9-
def validate!
10-
unless private_key_file
11-
raise "settings for `ssh_identity_key` not set"
12-
end
13-
14-
unless File.exist?(private_key_file)
15-
raise "Ssh public key file #{private_key_file} doesn't exist.\n"\
16-
"You can generate one with `ssh-keygen -t rsa -b 4096 -f #{private_key_file} -N ''`"
17-
end
18-
19-
unless File.exist?(public_key_file)
20-
raise "Ssh public key file #{public_key_file} doesn't exist"
21-
end
22-
23-
validate_ssh_log_level!
24-
end
25-
269
def private_key_file
2710
File.expand_path(Plugin.settings.ssh_identity_key_file)
2811
end
2912

3013
def public_key_file
31-
File.expand_path("#{private_key_file}.pub")
32-
end
33-
34-
def validate_ssh_log_level!
35-
wanted_level = Plugin.settings.ssh_log_level.to_s
36-
levels = Plugin::SSH_LOG_LEVELS
37-
unless levels.include? wanted_level
38-
raise "Wrong value '#{Plugin.settings.ssh_log_level}' for ssh_log_level, must be one of #{levels.join(', ')}"
39-
end
40-
41-
current = ::Proxy::SETTINGS.log_level.to_s.downcase
42-
43-
# regular log levels correspond to upcased ssh logger levels
44-
ssh, regular = [wanted_level, current].map do |wanted|
45-
levels.each_with_index.find { |value, _index| value == wanted }.last
46-
end
47-
48-
if ssh < regular
49-
raise 'ssh_log_level cannot be more verbose than regular log level'
50-
end
51-
52-
Plugin.settings.ssh_log_level = Plugin.settings.ssh_log_level.to_sym
14+
File.expand_path(Plugin.settings.ssh_identity_public_key_file)
5315
end
5416
end
5517
end

lib/smart_proxy_remote_execution_ssh/plugin.rb

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
require_relative 'validators'
2+
13
module Proxy::RemoteExecution::Ssh
24
class Plugin < Proxy::Plugin
35
SSH_LOG_LEVELS = %w[debug info warn error fatal].freeze
46

5-
http_rackup_path File.expand_path("http_config.ru", File.expand_path("../", __FILE__))
6-
https_rackup_path File.expand_path("http_config.ru", File.expand_path("../", __FILE__))
7+
http_rackup_path File.expand_path("http_config.ru", __dir__)
8+
https_rackup_path File.expand_path("http_config.ru", __dir__)
79

810
settings_file "remote_execution_ssh.yml"
911
default_settings :ssh_identity_key_file => '~/.ssh/id_rsa_foreman_proxy',
@@ -17,8 +19,21 @@ class Plugin < Proxy::Plugin
1719
:ssh_log_level => :fatal,
1820
:cleanup_working_dirs => true
1921

22+
load_validators ssh_log_level: Proxy::RemoteExecution::Ssh::Validators::SshLogLevel
23+
load_programmable_settings do |settings|
24+
if settings[:ssh_identity_key_file] && !settings[:ssh_identity_public_key_file]
25+
settings[:ssh_identity_public_key_file] = "#{settings[:ssh_identity_key_file}.pub"
26+
end
27+
28+
settings[:ssh_log_level] = settings[:ssh_log_level].to_sym
29+
end
30+
31+
validate_readable :ssh_identity_key_file, :ssh_identity_public_key_file
32+
validate :ssh_log_level, ssh_log_level: SSH_LOG_LEVELS
33+
2034
plugin :ssh, Proxy::RemoteExecution::Ssh::VERSION
21-
after_activation do
35+
36+
load_classes do
2237
require 'smart_proxy_dynflow'
2338
require 'smart_proxy_remote_execution_ssh/version'
2439
require 'smart_proxy_remote_execution_ssh/cockpit'
@@ -27,9 +42,10 @@ class Plugin < Proxy::Plugin
2742
require 'smart_proxy_remote_execution_ssh/dispatcher'
2843
require 'smart_proxy_remote_execution_ssh/log_filter'
2944
require 'smart_proxy_remote_execution_ssh/runners'
45+
end
3046

31-
Proxy::RemoteExecution::Ssh.validate!
32-
47+
# Not really Smart Proxy dependency injection, but similar enough
48+
load_dependency_injection_wirings do |container_instance, settings|
3349
Proxy::Dynflow::TaskLauncherRegistry.register('ssh', Proxy::Dynflow::TaskLauncher::Batch)
3450
end
3551

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module Proxy
2+
module RemoteExecution
3+
module Ssh
4+
module Validators
5+
class SshLogLevel < ::Proxy::PluginValidators::Base
6+
def validate!(settings)
7+
setting_value = settings[@setting_name].to_s
8+
9+
unless @params.include?(setting_value)
10+
raise ::Proxy::Error::ConfigurationError, "Parameter '#{@setting_name}' must be one of #{@params.join(', ')}"
11+
end
12+
13+
current = ::Proxy::SETTINGS.log_level.to_s.downcase
14+
15+
# regular log levels correspond to upcased ssh logger levels
16+
ssh, regular = [wanted_level, current].map do |wanted|
17+
levels.each_with_index.find { |value, _index| value == wanted }.last
18+
end
19+
20+
if ssh < regular
21+
raise ::Proxy::Error::ConfigurationError, "Parameter '#{@setting_name}' cannot be more verbose than regular log level (#{current})"
22+
end
23+
24+
true
25+
end
26+
end
27+
end
28+
end
29+
end
30+
end

0 commit comments

Comments
 (0)