manageiq-appliance_console 1.0.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 +7 -0
- data/.codeclimate.yml +47 -0
- data/.gitignore +12 -0
- data/.rspec +4 -0
- data/.rspec_ci +4 -0
- data/.rubocop.yml +4 -0
- data/.rubocop_cc.yml +5 -0
- data/.rubocop_local.yml +2 -0
- data/.travis.yml +19 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +202 -0
- data/README.md +45 -0
- data/Rakefile +6 -0
- data/bin/appliance_console +661 -0
- data/bin/appliance_console_cli +7 -0
- data/lib/manageiq-appliance_console.rb +51 -0
- data/lib/manageiq/appliance_console/certificate.rb +146 -0
- data/lib/manageiq/appliance_console/certificate_authority.rb +140 -0
- data/lib/manageiq/appliance_console/cli.rb +363 -0
- data/lib/manageiq/appliance_console/database_configuration.rb +286 -0
- data/lib/manageiq/appliance_console/database_maintenance.rb +35 -0
- data/lib/manageiq/appliance_console/database_maintenance_hourly.rb +58 -0
- data/lib/manageiq/appliance_console/database_maintenance_periodic.rb +84 -0
- data/lib/manageiq/appliance_console/database_replication.rb +146 -0
- data/lib/manageiq/appliance_console/database_replication_primary.rb +59 -0
- data/lib/manageiq/appliance_console/database_replication_standby.rb +166 -0
- data/lib/manageiq/appliance_console/date_time_configuration.rb +117 -0
- data/lib/manageiq/appliance_console/errors.rb +5 -0
- data/lib/manageiq/appliance_console/external_auth_options.rb +153 -0
- data/lib/manageiq/appliance_console/external_database_configuration.rb +34 -0
- data/lib/manageiq/appliance_console/external_httpd_authentication.rb +157 -0
- data/lib/manageiq/appliance_console/external_httpd_authentication/external_httpd_configuration.rb +249 -0
- data/lib/manageiq/appliance_console/internal_database_configuration.rb +187 -0
- data/lib/manageiq/appliance_console/key_configuration.rb +118 -0
- data/lib/manageiq/appliance_console/logfile_configuration.rb +117 -0
- data/lib/manageiq/appliance_console/logger.rb +23 -0
- data/lib/manageiq/appliance_console/logging.rb +102 -0
- data/lib/manageiq/appliance_console/logical_volume_management.rb +94 -0
- data/lib/manageiq/appliance_console/principal.rb +46 -0
- data/lib/manageiq/appliance_console/prompts.rb +211 -0
- data/lib/manageiq/appliance_console/scap.rb +53 -0
- data/lib/manageiq/appliance_console/temp_storage_configuration.rb +79 -0
- data/lib/manageiq/appliance_console/timezone_configuration.rb +58 -0
- data/lib/manageiq/appliance_console/utilities.rb +67 -0
- data/lib/manageiq/appliance_console/version.rb +5 -0
- data/locales/appliance/en.yml +42 -0
- data/locales/container/en.yml +30 -0
- data/manageiq-appliance_console.gemspec +40 -0
- data/zanata.xml +7 -0
- metadata +317 -0
@@ -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
|
data/lib/manageiq/appliance_console/external_httpd_authentication/external_httpd_configuration.rb
ADDED
@@ -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
|