manageiq-appliance_console 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +47 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +4 -0
  5. data/.rspec_ci +4 -0
  6. data/.rubocop.yml +4 -0
  7. data/.rubocop_cc.yml +5 -0
  8. data/.rubocop_local.yml +2 -0
  9. data/.travis.yml +19 -0
  10. data/Gemfile +6 -0
  11. data/LICENSE.txt +202 -0
  12. data/README.md +45 -0
  13. data/Rakefile +6 -0
  14. data/bin/appliance_console +661 -0
  15. data/bin/appliance_console_cli +7 -0
  16. data/lib/manageiq-appliance_console.rb +51 -0
  17. data/lib/manageiq/appliance_console/certificate.rb +146 -0
  18. data/lib/manageiq/appliance_console/certificate_authority.rb +140 -0
  19. data/lib/manageiq/appliance_console/cli.rb +363 -0
  20. data/lib/manageiq/appliance_console/database_configuration.rb +286 -0
  21. data/lib/manageiq/appliance_console/database_maintenance.rb +35 -0
  22. data/lib/manageiq/appliance_console/database_maintenance_hourly.rb +58 -0
  23. data/lib/manageiq/appliance_console/database_maintenance_periodic.rb +84 -0
  24. data/lib/manageiq/appliance_console/database_replication.rb +146 -0
  25. data/lib/manageiq/appliance_console/database_replication_primary.rb +59 -0
  26. data/lib/manageiq/appliance_console/database_replication_standby.rb +166 -0
  27. data/lib/manageiq/appliance_console/date_time_configuration.rb +117 -0
  28. data/lib/manageiq/appliance_console/errors.rb +5 -0
  29. data/lib/manageiq/appliance_console/external_auth_options.rb +153 -0
  30. data/lib/manageiq/appliance_console/external_database_configuration.rb +34 -0
  31. data/lib/manageiq/appliance_console/external_httpd_authentication.rb +157 -0
  32. data/lib/manageiq/appliance_console/external_httpd_authentication/external_httpd_configuration.rb +249 -0
  33. data/lib/manageiq/appliance_console/internal_database_configuration.rb +187 -0
  34. data/lib/manageiq/appliance_console/key_configuration.rb +118 -0
  35. data/lib/manageiq/appliance_console/logfile_configuration.rb +117 -0
  36. data/lib/manageiq/appliance_console/logger.rb +23 -0
  37. data/lib/manageiq/appliance_console/logging.rb +102 -0
  38. data/lib/manageiq/appliance_console/logical_volume_management.rb +94 -0
  39. data/lib/manageiq/appliance_console/principal.rb +46 -0
  40. data/lib/manageiq/appliance_console/prompts.rb +211 -0
  41. data/lib/manageiq/appliance_console/scap.rb +53 -0
  42. data/lib/manageiq/appliance_console/temp_storage_configuration.rb +79 -0
  43. data/lib/manageiq/appliance_console/timezone_configuration.rb +58 -0
  44. data/lib/manageiq/appliance_console/utilities.rb +67 -0
  45. data/lib/manageiq/appliance_console/version.rb +5 -0
  46. data/locales/appliance/en.yml +42 -0
  47. data/locales/container/en.yml +30 -0
  48. data/manageiq-appliance_console.gemspec +40 -0
  49. data/zanata.xml +7 -0
  50. metadata +317 -0
@@ -0,0 +1,5 @@
1
+ module ManageIQ
2
+ module ApplianceConsole
3
+ class MiqSignalError < RuntimeError; end
4
+ end
5
+ end
@@ -0,0 +1,153 @@
1
+ require 'pathname'
2
+ require 'fileutils'
3
+
4
+ module ManageIQ
5
+ module ApplianceConsole
6
+ class ExternalAuthOptions
7
+ AUTH_PATH = "/authentication".freeze
8
+
9
+ EXT_AUTH_OPTIONS = {
10
+ "#{AUTH_PATH}/sso_enabled" => {:label => "Single Sign-On", :logic => true},
11
+ "#{AUTH_PATH}/saml_enabled" => {:label => "SAML", :logic => true},
12
+ "#{AUTH_PATH}/local_login_disabled" => {:label => "Local Login", :logic => false}
13
+ }.freeze
14
+
15
+ include ManageIQ::ApplianceConsole::Logging
16
+
17
+ def initialize
18
+ @updates = {}
19
+ @current_config = {}
20
+ end
21
+
22
+ def ask_questions
23
+ @current_config = load_current
24
+ apply = EXT_AUTH_OPTIONS.keys.count + 1
25
+ skip = apply + 1
26
+ selection = 0
27
+ while selection < apply
28
+ say("\nExternal Authentication Options:")
29
+ cnt = 1
30
+ EXT_AUTH_OPTIONS.keys.each do |key|
31
+ current_state = selected_value(key)
32
+ say("#{cnt}) #{selected_verb(key, !current_state)} #{EXT_AUTH_OPTIONS[key][:label]}")
33
+ cnt += 1
34
+ end
35
+ say("#{apply}) Apply updates")
36
+ say("#{skip}) Skip updates")
37
+ show_updates
38
+ selection = ask_for_integer("option number to apply", 1..skip)
39
+ if selection < apply
40
+ key = EXT_AUTH_OPTIONS.keys[selection - 1]
41
+ @updates[key] = !selected_value(key)
42
+ end
43
+ end
44
+ @updates = {} if selection == skip
45
+ true
46
+ end
47
+
48
+ def show_updates
49
+ updates_todo = ""
50
+ EXT_AUTH_OPTIONS.keys.each do |key|
51
+ next unless @updates.key?(key)
52
+ updates_todo << ", " if updates_todo.present?
53
+ updates_todo << " #{selected_verb(key, @updates[key])} #{EXT_AUTH_OPTIONS[key][:label]}"
54
+ end
55
+ updates_to_apply = updates_todo.present? ? "Updates to apply: #{updates_todo}" : ""
56
+ say("\n#{updates_to_apply}")
57
+ end
58
+
59
+ def selected_value(key)
60
+ return @updates[key] if @updates.key?(key)
61
+ return @current_config[key] if @current_config.key?(key)
62
+ false
63
+ end
64
+
65
+ def selected_verb(key, flag)
66
+ if EXT_AUTH_OPTIONS[key][:logic]
67
+ flag ? "Enable" : "Disable"
68
+ else
69
+ flag ? "Disable" : "Enable"
70
+ end
71
+ end
72
+
73
+ def any_updates?
74
+ @updates.present?
75
+ end
76
+
77
+ def update_configuration(update_hash = nil)
78
+ update_hash ||= @updates
79
+ if update_hash.present?
80
+ say("\nUpdating external authentication options on appliance ...")
81
+ params = update_hash.collect { |key, value| "#{key}=#{value}" }
82
+ result = ManageIQ::ApplianceConsole::Utilities.rake_run("evm:settings:set", params)
83
+ raise parse_errors(result).join(', ') if result.failure?
84
+ end
85
+ end
86
+
87
+ # extauth_opts option parser: syntax is key=value,key=value
88
+ # key is one of the EXT_AUTH_OPTIONS keys.
89
+ # value is one of 1, true, 0 or false.
90
+ #
91
+ def parse(options)
92
+ parsed_updates = {}
93
+ options.split(",").each do |keyval|
94
+ key, val = keyval.split('=')
95
+ key, val = normalize_key(key.to_s.strip), val.to_s.strip
96
+ unless EXT_AUTH_OPTIONS.key?(key)
97
+ message = "Unknown external authentication option #{key} specified"
98
+ message << ", supported options are #{EXT_AUTH_OPTIONS.keys.join(', ')}"
99
+ raise message
100
+ end
101
+
102
+ value = option_value(val)
103
+ raise("Invalid #{key} option value #{val} specified, must be true or false") if value.nil?
104
+ parsed_updates[key] = value
105
+ end
106
+ parsed_updates
107
+ end
108
+
109
+ def self.configured?
110
+ # DB Up and running
111
+ true
112
+ end
113
+
114
+ private
115
+
116
+ def load_current
117
+ say("\nFetching external authentication options from appliance ...")
118
+ result = ManageIQ::ApplianceConsole::Utilities.rake_run("evm:settings:get", EXT_AUTH_OPTIONS.keys)
119
+
120
+ if result.success?
121
+ return parse_response(result)
122
+ else
123
+ raise parse_errors(result).join(', ')
124
+ end
125
+ end
126
+
127
+ def parse_errors(result)
128
+ result.error.split("\n").collect { |line| line if line =~ /^error: /i }.compact
129
+ end
130
+
131
+ def normalize_key(key)
132
+ key.include?('/') ? key : "#{AUTH_PATH}/#{key}"
133
+ end
134
+
135
+ def parse_response(result)
136
+ result.output.split("\n").each_with_object({}) do |line, hash|
137
+ key, val = line.split("=")
138
+ hash[key] = parse_value(val)
139
+ end
140
+ end
141
+
142
+ def option_value(value)
143
+ return true if value == '1' || value =~ /true/i
144
+ return false if value == '0' || value =~ /false/i
145
+ nil
146
+ end
147
+
148
+ def parse_value(value)
149
+ value.present? ? option_value(value) : false
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,34 @@
1
+ module ManageIQ
2
+ module ApplianceConsole
3
+ class ExternalDatabaseConfiguration < DatabaseConfiguration
4
+ attr_accessor :action
5
+
6
+ def initialize(hash = {})
7
+ set_defaults
8
+ super
9
+ end
10
+
11
+ def set_defaults
12
+ self.username = "root"
13
+ self.port = DEFAULT_PORT
14
+ self.database = "vmdb_production"
15
+ end
16
+
17
+ def activate
18
+ ask_questions if host.nil?
19
+ super
20
+ end
21
+
22
+ def ask_questions
23
+ create_new_region_questions if action == :create
24
+ clear_screen
25
+ say("Database Configuration\n")
26
+ ask_for_database_credentials(false)
27
+ end
28
+
29
+ def post_activation
30
+ start_evm
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,157 @@
1
+ require "manageiq/appliance_console/external_httpd_authentication/external_httpd_configuration"
2
+
3
+ module ManageIQ
4
+ module ApplianceConsole
5
+ class ExternalHttpdAuthentication
6
+ include ExternalHttpdConfiguration
7
+
8
+ def initialize(host = nil, options = {})
9
+ @ipaserver, @domain, @password = nil
10
+ @host = host
11
+ @domain = options[:domain] || domain_from_host(host)
12
+ @realm = options[:realm]
13
+ @ipaserver = options[:ipaserver]
14
+ @principal = options[:principal] || "admin"
15
+ @password = options[:password]
16
+ @timestamp = Time.now.strftime(TIMESTAMP_FORMAT)
17
+
18
+ @ipaserver = fqdn(@ipaserver, @domain)
19
+ end
20
+
21
+ def ask_for_parameters
22
+ say("\nIPA Server Parameters:\n\n")
23
+ @ipaserver = ask_for_hostname("IPA Server Hostname", @ipaserver)
24
+ @domain = ask_for_domain("IPA Server Domain", @domain)
25
+ @realm = ask_for_string("IPA Server Realm", realm)
26
+ @principal = ask_for_string("IPA Server Principal", @principal)
27
+ @password = ask_for_password("IPA Server Principal Password", @password)
28
+
29
+ @ipaserver = fqdn(@ipaserver, @domain)
30
+ end
31
+
32
+ def show_parameters
33
+ say("\nExternal Authentication (httpd) Configuration:\n")
34
+ say("IPA Server Details:\n")
35
+ say(" Hostname: #{@ipaserver}\n")
36
+ say(" Domain: #{@domain}\n")
37
+ say(" Realm: #{realm}\n")
38
+ say(" Naming Context: #{domain_naming_context}\n")
39
+ say(" Principal: #{@principal}\n")
40
+ end
41
+
42
+ def show_current_configuration
43
+ return unless ipa_client_configured?
44
+ config = config_file_read(SSSD_CONFIG)
45
+ say("\nCurrent External Authentication (httpd) Configuration:\n")
46
+ say("IPA Server Details:\n")
47
+ say(" Hostname: #{fetch_ipa_configuration("ipa_server", config)}\n")
48
+ say(" Domain: #{fetch_ipa_configuration("ipa_domain", config)}\n")
49
+ end
50
+
51
+ def ask_questions
52
+ return false unless valid_environment?
53
+ ask_for_parameters
54
+ show_parameters
55
+ return false unless agree("\nProceed? (Y/N): ")
56
+ return false unless valid_parameters?(@ipaserver)
57
+ true
58
+ end
59
+
60
+ def activate
61
+ begin
62
+ configure_ipa
63
+ configure_pam
64
+ configure_sssd
65
+ configure_ipa_http_service
66
+ configure_httpd
67
+ configure_selinux
68
+ rescue AwesomeSpawn::CommandResultError => e
69
+ say e.result.output
70
+ say e.result.error
71
+ say ""
72
+ say("Failed to Configure External Authentication - #{e}")
73
+ return false
74
+ rescue => e
75
+ say("Failed to Configure External Authentication - #{e}")
76
+ return false
77
+ end
78
+ true
79
+ end
80
+
81
+ def post_activation
82
+ say("\nRestarting httpd, if running ...")
83
+ httpd_service = LinuxAdmin::Service.new("httpd")
84
+ httpd_service.restart if httpd_service.running?
85
+
86
+ say("Restarting sssd and configure it to start on reboots ...")
87
+ LinuxAdmin::Service.new("sssd").restart.enable
88
+ end
89
+
90
+ private
91
+
92
+ def domain_naming_context
93
+ @domain.split(".").collect { |s| "dc=#{s}" }.join(",")
94
+ end
95
+
96
+ def domain_from_host(host)
97
+ host.gsub(/^([^.]+\.)/, '') if host && host.include?('.')
98
+ end
99
+
100
+ def fqdn(host, domain)
101
+ (host && domain && !host.include?(".")) ? "#{host}.#{domain}" : host
102
+ end
103
+
104
+ def realm
105
+ (@realm || @domain).upcase
106
+ end
107
+
108
+ def configure_ipa
109
+ say("\nConfiguring IPA (may take a minute) ...")
110
+ ipa_client_unconfigure if ipa_client_configured?
111
+ ipa_client_configure(realm, @domain, @ipaserver, @principal, @password)
112
+ enable_kerberos_dns_lookups
113
+ end
114
+
115
+ def configure_pam
116
+ say("Configuring pam ...")
117
+ cp_template(PAM_CONFIG, template_directory)
118
+ end
119
+
120
+ def configure_sssd
121
+ say("Configuring sssd ...")
122
+ config = config_file_read(SSSD_CONFIG)
123
+ configure_sssd_domain(config, @domain)
124
+ configure_sssd_service(config)
125
+ configure_sssd_ifp(config)
126
+ config_file_write(config, SSSD_CONFIG, @timestamp)
127
+ end
128
+
129
+ def configure_ipa_http_service
130
+ say("Configuring IPA HTTP Service and Keytab ...")
131
+ AwesomeSpawn.run!("/usr/bin/kinit", :params => [@principal], :stdin_data => @password)
132
+ service = Principal.new(:hostname => @host, :realm => realm, :service => "HTTP", :ca_name => "ipa")
133
+ service.register
134
+ AwesomeSpawn.run!(IPA_GETKEYTAB, :params => {"-s" => @ipaserver, "-k" => HTTP_KEYTAB, "-p" => service.name})
135
+ FileUtils.chown(APACHE_USER, nil, HTTP_KEYTAB)
136
+ FileUtils.chmod(0600, HTTP_KEYTAB)
137
+ end
138
+
139
+ def configure_httpd
140
+ say("Configuring httpd ...")
141
+ configure_httpd_application
142
+ end
143
+
144
+ def configure_selinux
145
+ say("Configuring SELinux ...")
146
+ get_enforce = AwesomeSpawn.run!(GETENFORCE_COMMAND)
147
+ if get_enforce.output.downcase.include?("disabled")
148
+ say("SELinux is Disabled")
149
+ else
150
+ AwesomeSpawn.run!("#{SETSEBOOL_COMMAND} -P allow_httpd_mod_auth_pam on")
151
+ result = AwesomeSpawn.run("#{GETSEBOOL_COMMAND} httpd_dbus_sssd")
152
+ AwesomeSpawn.run!("#{SETSEBOOL_COMMAND} -P httpd_dbus_sssd on") if result.exit_status == 0
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,249 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+ require 'pathname'
3
+
4
+ module ManageIQ
5
+ module ApplianceConsole
6
+ class ExternalHttpdAuthentication
7
+ module ExternalHttpdConfiguration
8
+ #
9
+ # External Authentication Definitions
10
+ #
11
+ IPA_COMMAND = "/usr/bin/ipa".freeze
12
+ IPA_INSTALL_COMMAND = "/usr/sbin/ipa-client-install".freeze
13
+ IPA_GETKEYTAB = "/usr/sbin/ipa-getkeytab".freeze
14
+
15
+ KERBEROS_CONFIG_FILE = "/etc/krb5.conf".freeze
16
+
17
+ SSSD_CONFIG = "/etc/sssd/sssd.conf".freeze
18
+ PAM_CONFIG = "/etc/pam.d/httpd-auth".freeze
19
+ HTTP_KEYTAB = "/etc/http.keytab".freeze
20
+ HTTP_REMOTE_USER = "/etc/httpd/conf.d/manageiq-remote-user.conf".freeze
21
+ HTTP_EXTERNAL_AUTH = "/etc/httpd/conf.d/manageiq-external-auth.conf".freeze
22
+ HTTP_EXTERNAL_AUTH_TEMPLATE = "#{HTTP_EXTERNAL_AUTH}.erb".freeze
23
+
24
+ GETSEBOOL_COMMAND = "/usr/sbin/getsebool".freeze
25
+ SETSEBOOL_COMMAND = "/usr/sbin/setsebool".freeze
26
+ GETENFORCE_COMMAND = "/usr/sbin/getenforce".freeze
27
+
28
+ APACHE_USER = "apache".freeze
29
+
30
+ TIMESTAMP_FORMAT = "%Y%m%d_%H%M%S".freeze
31
+
32
+ LDAP_ATTRS = {
33
+ "mail" => "REMOTE_USER_EMAIL",
34
+ "givenname" => "REMOTE_USER_FIRSTNAME",
35
+ "sn" => "REMOTE_USER_LASTNAME",
36
+ "displayname" => "REMOTE_USER_FULLNAME",
37
+ "domainname" => "REMOTE_USER_DOMAIN"
38
+ }.freeze
39
+
40
+ def template_directory
41
+ Pathname.new(ENV.fetch("APPLIANCE_TEMPLATE_DIRECTORY"))
42
+ end
43
+
44
+ #
45
+ # IPA Configuration Methods
46
+ #
47
+ def ipa_client_configure(realm, domain, server, principal, password)
48
+ say("Configuring the IPA Client ...")
49
+ AwesomeSpawn.run!(IPA_INSTALL_COMMAND,
50
+ :params => [
51
+ "-N", :force_join, :fixed_primary, :unattended, {
52
+ :realm= => realm,
53
+ :domain= => domain,
54
+ :server= => server,
55
+ :principal= => principal,
56
+ :password= => password
57
+ }
58
+ ])
59
+ end
60
+
61
+ def deactivate
62
+ ipa_client_unconfigure
63
+ unconfigure_httpd
64
+ end
65
+
66
+ def ipa_client_unconfigure
67
+ say("Un-Configuring the IPA Client ...")
68
+ AwesomeSpawn.run(IPA_INSTALL_COMMAND, :params => [:uninstall, :unattended])
69
+ end
70
+
71
+ def unconfigure_httpd
72
+ say("Unconfiguring httpd ...")
73
+ unconfigure_httpd_application
74
+
75
+ say("Restarting httpd ...")
76
+ LinuxAdmin::Service.new("httpd").restart
77
+ end
78
+
79
+ def configure_httpd_application
80
+ cp_template(HTTP_EXTERNAL_AUTH_TEMPLATE, template_directory)
81
+ cp_template(HTTP_REMOTE_USER, template_directory)
82
+ end
83
+
84
+ def unconfigure_httpd_application
85
+ rm_file(HTTP_EXTERNAL_AUTH)
86
+ rm_file(HTTP_REMOTE_USER)
87
+ end
88
+
89
+ #
90
+ # Kerberos KRB5 File Methods
91
+ #
92
+ def enable_kerberos_dns_lookups
93
+ FileUtils.copy(KERBEROS_CONFIG_FILE, "#{KERBEROS_CONFIG_FILE}.miqbkp")
94
+ krb5config = File.read(KERBEROS_CONFIG_FILE)
95
+ krb5config[/(\s*)dns_lookup_kdc(\s*)=(\s*)(.*)/, 4] = 'true'
96
+ krb5config[/(\s*)dns_lookup_realm(\s*)=(\s*)(.*)/, 4] = 'true'
97
+ File.write(KERBEROS_CONFIG_FILE, krb5config)
98
+ end
99
+
100
+ #
101
+ # SSSD File Methods
102
+ #
103
+ def configure_sssd_domain(config, domain)
104
+ ldap_user_extra_attrs = LDAP_ATTRS.keys.join(", ")
105
+ if config.include?("ldap_user_extra_attrs = ")
106
+ pattern = "[domain/#{Regexp.escape(domain)}](\n.*)+ldap_user_extra_attrs = (.*)"
107
+ config[/#{pattern}/, 2] = ldap_user_extra_attrs
108
+ else
109
+ pattern = "[domain/#{Regexp.escape(domain)}].*(\n)"
110
+ config[/#{pattern}/, 1] = "\nldap_user_extra_attrs = #{ldap_user_extra_attrs}\n"
111
+ end
112
+
113
+ pattern = "[domain/#{Regexp.escape(domain)}].*(\n)"
114
+ config[/#{pattern}/, 1] = "\nentry_cache_timeout = 600\n"
115
+ end
116
+
117
+ def configure_sssd_service(config)
118
+ services = config.match(/\[sssd\](\n.*)+services = (.*)/)[2]
119
+ services = "#{services}, ifp" unless services.include?("ifp")
120
+ config[/\[sssd\](\n.*)+services = (.*)/, 2] = services
121
+ end
122
+
123
+ def configure_sssd_ifp(config)
124
+ user_attributes = LDAP_ATTRS.keys.collect { |k| "+#{k}" }.join(", ")
125
+ ifp_config = "
126
+ allowed_uids = #{APACHE_USER}, root
127
+ user_attributes = #{user_attributes}
128
+ "
129
+ if config.include?("[ifp]")
130
+ if config[/\[ifp\](\n.*)+user_attributes = (.*)/]
131
+ config[/\[ifp\](\n.*)+user_attributes = (.*)/, 2] = user_attributes
132
+ else
133
+ config[/\[ifp\](\n)/, 1] = ifp_config
134
+ end
135
+ else
136
+ config << "\n[ifp]#{ifp_config}\n"
137
+ end
138
+ end
139
+
140
+ #
141
+ # Validation Methods
142
+ #
143
+ def installation_valid?
144
+ installed_rpm_packages = LinuxAdmin::Rpm.list_installed.keys
145
+ rpm_packages = %w(ipa-client sssd-dbus mod_intercept_form_submit mod_authnz_pam mod_lookup_identity)
146
+
147
+ missing = rpm_packages.count do |package|
148
+ installed = installed_rpm_packages.include?(package)
149
+ say("#{package} RPM is not installed") unless installed
150
+ !installed
151
+ end
152
+
153
+ if missing > 0
154
+ say("\nAppliance Installation is not valid for enabling External Authentication\n")
155
+ return false
156
+ end
157
+
158
+ true
159
+ end
160
+
161
+ def valid_environment?
162
+ return false unless installation_valid?
163
+ if ipa_client_configured?
164
+ show_current_configuration
165
+ return false unless agree("\nIPA Client already configured on this Appliance, Un-Configure first? (Y/N): ")
166
+ deactivate
167
+ return false unless agree("\nProceed with External Authentication Configuration? (Y/N): ")
168
+ end
169
+ true
170
+ end
171
+
172
+ def valid_parameters?(ipaserver)
173
+ host_reachable?(ipaserver, "IPA Server")
174
+ end
175
+
176
+ #
177
+ # Config File I/O Methods
178
+ #
179
+ def config_file_write(config, path, timestamp)
180
+ FileUtils.copy(path, "#{path}.#{timestamp}") if File.exist?(path)
181
+ File.open(path, "w") { |f| f.write(config) }
182
+ end
183
+
184
+ #
185
+ # Network validation
186
+ #
187
+ def host_reachable?(host, what = "Server")
188
+ require 'net/ping'
189
+ say("Checking connectivity to #{host} ... ")
190
+ unless Net::Ping::External.new(host).ping
191
+ say("Failed.\nCould not connect to #{host},")
192
+ say("the #{what} must be reachable by name.")
193
+ return false
194
+ end
195
+ say("Succeeded.")
196
+ true
197
+ end
198
+
199
+ def cp_template(file, src_dir, dest_dir = "/")
200
+ src_path = path_join(src_dir, file)
201
+ dest_path = path_join(dest_dir, file.gsub(".erb", ""))
202
+ if src_path.to_s.include?(".erb")
203
+ File.write(dest_path, ERB.new(File.read(src_path), nil, '-').result(binding))
204
+ else
205
+ FileUtils.cp src_path, dest_path
206
+ end
207
+ end
208
+
209
+ def rm_file(file, dir = "/")
210
+ path = path_join(dir, file)
211
+ File.delete(path) if File.exist?(path)
212
+ end
213
+
214
+ def path_join(*args)
215
+ path = Pathname.new(args.shift)
216
+ args.each { |path_seg| path = path.join("./#{path_seg}") }
217
+ path
218
+ end
219
+ end
220
+
221
+ def self.config_status
222
+ fetch_ipa_configuration("ipa_server") || fetch_sssd_domain || "not configured"
223
+ end
224
+
225
+ def self.ipa_client_configured?
226
+ File.exist?(SSSD_CONFIG)
227
+ end
228
+
229
+ def self.config_file_read(path)
230
+ File.read(path)
231
+ end
232
+
233
+ def self.fetch_ipa_configuration(what, config = nil)
234
+ unless config
235
+ return nil unless ipa_client_configured?
236
+ config = config_file_read(SSSD_CONFIG)
237
+ end
238
+ pattern = "[domain/.*].*(\n.*)+#{Regexp.escape(what)} = (.*)"
239
+ config[/#{pattern}/, 2]
240
+ end
241
+
242
+ def self.fetch_sssd_domain
243
+ config_file_read(SSSD_CONFIG)[/\[domain\/(.*)\]/, 1] if File.exist?(SSSD_CONFIG)
244
+ end
245
+
246
+ delegate :ipa_client_configured?, :config_file_read, :fetch_ipa_configuration, :config_status, :to => self
247
+ end
248
+ end
249
+ end