Class: ManageIQ::ApplianceConsole::MessageConfiguration

Inherits:
Object
  • Object
show all
Includes:
ManageiqUserMixin, Prompts
Defined in:
lib/manageiq/appliance_console/message_configuration.rb

Constant Summary collapse

BASE_DIR =
"/var/lib/kafka".freeze
BIN_DIR =
"/opt/kafka/bin".freeze
LOGS_DIR =
"#{BASE_DIR}/logs".freeze
CONFIG_DIR =
"/etc/kafka/config".freeze
SAMPLE_CONFIG_DIR =
"/etc/kafka/config-sample".freeze
MIQ_CONFIG_DIR =
ManageIQ::ApplianceConsole::RAILS_ROOT.join("config").freeze

Constants included from Prompts

Prompts::CLEAR_CODE, Prompts::DOMAIN_REGEXP, Prompts::HOSTNAME_REGEXP, Prompts::INT_REGEXP, Prompts::IPV4_REGEXP, Prompts::IPV6_REGEXP, Prompts::IP_REGEXP, Prompts::MESSAGING_HOSTNAME_REGEXP, Prompts::MESSAGING_PASSWORD_REGEXP, Prompts::NONE_REGEXP

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Prompts

#are_you_sure?, #ask_for_disk, #ask_for_domain, #ask_for_hostname, #ask_for_hour_number, #ask_for_integer, #ask_for_ip, #ask_for_ip_or_hostname, #ask_for_ip_or_hostname_or_none, #ask_for_many, #ask_for_messaging_hostname, #ask_for_messaging_password, #ask_for_month_day_number, #ask_for_new_password, #ask_for_password, #ask_for_schedule_frequency, #ask_for_string, #ask_for_uri, #ask_for_week_day_number, #ask_with_menu, #ask_yn?, #clear_screen, #default_to_index, #just_ask, #press_any_key

Methods included from ManageiqUserMixin

#manageiq_gid, #manageiq_uid, #run_as_manageiq!

Constructor Details

#initialize(options = {}) ⇒ MessageConfiguration

Returns a new instance of MessageConfiguration.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 35

def initialize(options = {})
  @message_server_port        = options[:message_server_port] || 9093
  @message_keystore_username  = options[:message_keystore_username] || "admin"
  @message_keystore_password  = options[:message_keystore_password]

  @miq_config_dir_path        = Pathname.new(MIQ_CONFIG_DIR)
  @config_dir_path            = Pathname.new(CONFIG_DIR)
  @sample_config_dir_path     = Pathname.new(SAMPLE_CONFIG_DIR)

  @client_properties_path     = config_dir_path.join("client.properties")
  @keystore_dir_path          = config_dir_path.join("keystore")
  @truststore_path            = keystore_dir_path.join("truststore.jks")
  @keystore_path              = keystore_dir_path.join("keystore.jks")

  @messaging_yaml_sample_path = miq_config_dir_path.join("messaging.kafka.yml")
  @messaging_yaml_path        = miq_config_dir_path.join("messaging.yml")
  @ca_cert_path               = keystore_dir_path.join("ca-cert")
end

Instance Attribute Details

#ca_cert_pathObject (readonly)

Returns the value of attribute ca_cert_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def ca_cert_path
  @ca_cert_path
end

#client_properties_pathObject (readonly)

Returns the value of attribute client_properties_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def client_properties_path
  @client_properties_path
end

#config_dir_pathObject (readonly)

Returns the value of attribute config_dir_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def config_dir_path
  @config_dir_path
end

#keystore_dir_pathObject (readonly)

Returns the value of attribute keystore_dir_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def keystore_dir_path
  @keystore_dir_path
end

#keystore_pathObject (readonly)

Returns the value of attribute keystore_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def keystore_path
  @keystore_path
end

#message_keystore_passwordObject (readonly)

Returns the value of attribute message_keystore_password.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def message_keystore_password
  @message_keystore_password
end

#message_keystore_usernameObject (readonly)

Returns the value of attribute message_keystore_username.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def message_keystore_username
  @message_keystore_username
end

#message_server_hostObject (readonly)

Returns the value of attribute message_server_host.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def message_server_host
  @message_server_host
end

#message_server_portObject (readonly)

Returns the value of attribute message_server_port.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def message_server_port
  @message_server_port
end

#messaging_yaml_pathObject (readonly)

Returns the value of attribute messaging_yaml_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def messaging_yaml_path
  @messaging_yaml_path
end

#messaging_yaml_sample_pathObject (readonly)

Returns the value of attribute messaging_yaml_sample_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def messaging_yaml_sample_path
  @messaging_yaml_sample_path
end

#miq_config_dir_pathObject (readonly)

Returns the value of attribute miq_config_dir_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def miq_config_dir_path
  @miq_config_dir_path
end

#sample_config_dir_pathObject (readonly)

Returns the value of attribute sample_config_dir_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def sample_config_dir_path
  @sample_config_dir_path
end

#truststore_pathObject (readonly)

Returns the value of attribute truststore_path.



12
13
14
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 12

def truststore_path
  @truststore_path
end

Class Method Details

.available?Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 27

def self.available?
  File.exist?("#{BIN_DIR}/kafka-run-class.sh")
end

.configured?Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 31

def self.configured?
  MessageServerConfiguration.configured? || MessageClientConfiguration.configured?
end

Instance Method Details

#already_configured?Boolean

Returns:

  • (Boolean)


54
55
56
57
58
59
60
61
62
63
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 54

def already_configured?
  installed_file_found = false
  installed_files.each do |f|
    if File.exist?(f)
      installed_file_found = true
      say("Installed file #{f} found.")
    end
  end
  installed_file_found
end

#ask_questionsObject



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 65

def ask_questions
  return false unless valid_environment?

  ask_for_parameters
  show_parameters
  return false unless agree("\nProceed? (Y/N): ")

  return false unless host_resolvable?(message_server_host) && host_reachable?(message_server_host, "Message Server Host:")

  true
end

#configure_messaging_yamlObject



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 110

def configure_messaging_yaml
  say(__method__.to_s.tr("_", " ").titleize)

  return if file_found?(messaging_yaml_path)

  data = File.read(messaging_yaml_sample_path)
  messaging_yaml =
    if YAML.respond_to?(:safe_load)
      YAML.safe_load(data, :aliases => true)
    else
      YAML.load(data) # rubocop:disable Security/YAMLLoad
    end

  messaging_yaml["production"]["host"]      = message_server_host
  messaging_yaml["production"]["port"]      = message_server_port
  messaging_yaml["production"]["username"]  = message_keystore_username
  messaging_yaml["production"]["password"]  = ManageIQ::Password.try_encrypt(message_keystore_password)

  if secure?
    messaging_yaml["production"]["ssl"]     = true
    messaging_yaml["production"]["ca_file"] = ca_cert_path.to_path
  else
    messaging_yaml["production"]["ssl"] = false
  end

  File.open(messaging_yaml_path, "w") do |f|
    f.write(messaging_yaml.to_yaml)
    f.chown(manageiq_uid, manageiq_gid)
  end
end

#create_client_propertiesObject



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 77

def create_client_properties
  say(__method__.to_s.tr("_", " ").titleize)

  return if file_found?(client_properties_path)

  algorithm = message_server_host.ipaddress? ? "" : "HTTPS"
  protocol = secure? ? "SASL_SSL" : "PLAINTEXT"
  content = secure? ? secure_client_properties_content(algorithm, protocol) : unsecure_client_properties_content(algorithm, protocol)

  File.write(client_properties_path, content)
end

#file_contains?(path, content) ⇒ Boolean

Returns:

  • (Boolean)


169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 169

def file_contains?(path, content)
  return false unless File.exist?(path)

  content.split("\n").each do |l|
    l.gsub!("/", "\\/")
    l.gsub!(/password=.*$/, "password=") # Remove the password as it can have special characters that grep can not match.
    return false unless File.foreach(path).grep(/#{l}/).any?
  end

  say("Content already exists in #{path}. Taking no action.")
  true
end

#file_found?(path) ⇒ Boolean

Returns:

  • (Boolean)


155
156
157
158
159
160
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 155

def file_found?(path)
  return false unless File.exist?(path)

  say("\tWARNING: #{path} already exists. Taking no action.")
  true
end

#files_found?(path_list) ⇒ Boolean

Returns:

  • (Boolean)


162
163
164
165
166
167
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 162

def files_found?(path_list)
  return false unless path_list.all? { |path| File.exist?(path) }

  path_list.each { |path| file_found?(path) }
  true
end

#host_reachable?(host, what) ⇒ Boolean

Returns:

  • (Boolean)


182
183
184
185
186
187
188
189
190
191
192
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 182

def host_reachable?(host, what)
  require 'net/ping'
  say("Checking connectivity to #{host} ... ")
  unless Net::Ping::External.new(host).ping
    say("Failed.\nCould not connect to #{host},")
    say("the #{what} must be reachable by name.")
    return false
  end
  say("Succeeded.")
  true
end

#host_resolvable?(host) ⇒ Boolean

Returns:

  • (Boolean)


194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 194

def host_resolvable?(host)
  require 'ipaddr'
  require 'resolv'

  say("Checking if #{host} is resolvable ... ")
  begin
    ip_address = Resolv.getaddress(host)

    if IPAddr.new("127.0.0.1/8").include?(ip_address) || IPAddr.new("::1/128").include?(ip_address)
      say("Failed.\nThe hostname must not resolve to a link-local address")

      return false
    end
  rescue Resolv::ResolvError => e
    say("Failed.\nHostname #{host} is not resolvable: #{e.message}")

    return false
  end

  say("Succeeded.")
  true
end

#remove_installed_filesObject



141
142
143
144
145
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 141

def remove_installed_files
  say(__method__.to_s.tr("_", " ").titleize)

  installed_files.each { |f| FileUtils.rm_rf(f) }
end

#secure?Boolean

Returns:

  • (Boolean)


221
222
223
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 221

def secure?
  message_server_port == 9_093
end

#secure_client_properties_content(algorithm, protocol) ⇒ Object



89
90
91
92
93
94
95
96
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 89

def secure_client_properties_content(algorithm, protocol)
  secure_content = <<~CLIENT_PROPERTIES
    ssl.truststore.location=#{truststore_path}
    ssl.truststore.password=#{message_keystore_password}
  CLIENT_PROPERTIES

  unsecure_client_properties_content(algorithm, protocol) + secure_content
end

#unconfigureObject



217
218
219
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 217

def unconfigure
  remove_installed_files
end

#unsecure_client_properties_content(algorithm, protocol) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 98

def unsecure_client_properties_content(algorithm, protocol)
  <<~CLIENT_PROPERTIES
    ssl.endpoint.identification.algorithm=#{algorithm}

    sasl.mechanism=PLAIN
    security.protocol=#{protocol}
    sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \\
      username=#{message_keystore_username} \\
      password=#{message_keystore_password} ;
  CLIENT_PROPERTIES
end

#valid_environment?Boolean

Returns:

  • (Boolean)


147
148
149
150
151
152
153
# File 'lib/manageiq/appliance_console/message_configuration.rb', line 147

def valid_environment?
  if already_configured?
    unconfigure if agree("\nAlready configured on this Appliance, Un-Configure first? (Y/N): ")
    return false unless agree("\nProceed with Configuration? (Y/N): ")
  end
  true
end