manageiq-appliance_console 9.0.3 → 9.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2e3543b11c78c8759bbec5fce9e2ccda935b6bd40f072f72a252fb9d7ae49fa
4
- data.tar.gz: 2242da455964838d4cb1c1801136a43dd3ec100986bf8d427c292729b548163f
3
+ metadata.gz: 2d0ec5457c80696cb57975c7b90ed74b04b6b8f9732686776524c9a19a63d6b9
4
+ data.tar.gz: 934f6a498b9d3916be9618d7a22ce98cc2f71800a099edbc12ac8a400e6a214a
5
5
  SHA512:
6
- metadata.gz: 98ae6fea30f0a22d71df4a61dacc9a9e4f19820f0f047ebe5ef72f062ae78c46fde41513fae2a5f5be74d62ded807bdf8d67e6aa4fa2f9e21c6e8815eca11c32
7
- data.tar.gz: 2cb850cb2873ce65c7ce1cfd7f0010272d6d4879576cc31c4df2bc17ed2faf1b501ff0406d010c02116eeaa91f4c0c23cb2002562bda3bb3b652868ddf8a7202
6
+ metadata.gz: 4a47aedb1dfe010537e0e015ad67b65e3d5a2402375d3cd667a007d52396bb7a24b18ad652f5da0f91f895740331faac6fbf0c3859fc64e419957be81419651f
7
+ data.tar.gz: 7e8c13d6558303e7028917ca58d3e85635088eaca14de87222f5fe9e38a9019d599203d9b94a3c8ed418038e47cc52b47c694c3d12b3c9b5120d51ec63a95be7
@@ -44,4 +44,4 @@ jobs:
44
44
  - name: Report code coverage
45
45
  if: "${{ github.ref == 'refs/heads/master' && matrix.ruby-version == '3.0' && matrix.rails-version == '6.1' }}"
46
46
  continue-on-error: true
47
- uses: paambaati/codeclimate-action@v6
47
+ uses: paambaati/codeclimate-action@v8
data/.whitesource CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
2
  "settingsInheritedFrom": "ManageIQ/whitesource-config@master"
3
- }
3
+ }
data/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [9.1.0] - 2024-07-24
8
+ ### Added
9
+ - Add a common method for asking for a password [[#251](https://github.com/ManageIQ/manageiq-appliance_console/pull/251)]
10
+ - Add messaging hostname validation [[#254](https://github.com/ManageIQ/manageiq-appliance_console/pull/254)]
11
+ - Indicate that messaging persistent disk is optional [[#256](https://github.com/ManageIQ/manageiq-appliance_console/pull/256)]
12
+ - Add messaging password validation [[#255](https://github.com/ManageIQ/manageiq-appliance_console/pull/255)]
13
+
14
+ ### Changed
15
+ - Deprecate message-server-use-ipaddr option from cli [[#257](https://github.com/ManageIQ/manageiq-appliance_console/pull/257)]
16
+
17
+ ### Fixed
18
+ - Add ca-cert to messaging client installed_files [[#258](https://github.com/ManageIQ/manageiq-appliance_console/pull/258)]
19
+
7
20
  ## [9.0.3] - 2023-05-06
8
21
  ### Fixed
9
22
  - Fix missing kafka client ca-cert [[#250]](https://github.com/ManageIQ/manageiq-appliance_console/pull/250)
@@ -272,8 +285,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
272
285
 
273
286
  ## [1.0.0] - 2017-10-19
274
287
 
275
- [Unreleased]: https://github.com/ManageIQ/manageiq-appliance_console/compare/v9.0.2...HEAD
276
- [9.0.1]: https://github.com/ManageIQ/manageiq-appliance_console/compare/v9.0.1...v9.0.2
288
+ [Unreleased]: https://github.com/ManageIQ/manageiq-appliance_console/compare/v9.1.0...HEAD
289
+ [9.1.0]: https://github.com/ManageIQ/manageiq-appliance_console/compare/v9.0.3...v9.1.0
290
+ [9.0.3]: https://github.com/ManageIQ/manageiq-appliance_console/compare/v9.0.2...v9.0.3
291
+ [9.0.2]: https://github.com/ManageIQ/manageiq-appliance_console/compare/v9.0.1...v9.0.2
277
292
  [9.0.1]: https://github.com/ManageIQ/manageiq-appliance_console/compare/v9.0.0...v9.0.1
278
293
  [9.0.0]: https://github.com/ManageIQ/manageiq-appliance_console/compare/v8.1.0...v9.0.0
279
294
  [8.1.0]: https://github.com/ManageIQ/manageiq-appliance_console/compare/v8.0.0...v8.1.0
@@ -216,22 +216,18 @@ module ApplianceConsole
216
216
  opt :message_server_username, "Message Server Username", :type => :string
217
217
  opt :message_server_password, "Message Server password", :type => :string
218
218
  opt :message_server_port, "Message Server Port", :type => :integer
219
- opt :message_server_use_ipaddr, "Message Server Use Address", :type => :boolean, :default => false
219
+ opt :message_server_use_ipaddr, "Deprecated: Message Server Use Address", :type => :boolean, :default => false
220
220
  opt :message_server_host, "Message Server Hostname or IP Address", :type => :string
221
221
  opt :message_truststore_path_src, "Message Server Truststore Path", :type => :string
222
222
  opt :message_ca_cert_path_src, "Message Server CA Cert Path", :type => :string
223
223
  opt :message_persistent_disk, "Message Persistent Disk Path", :type => :string
224
224
  end
225
225
  Optimist.die :region, "needed when setting up a local database" if region_number_required? && options[:region].nil?
226
- Optimist.die "Supply only one of --message-server-host or --message-server-use-ipaddr=true" if both_host_and_use_ip_addr_specified?
227
226
  Optimist.die "Supply only one of --message-server-config, --message-server-unconfig, --message-client-config or --message-client-unconfig" if multiple_message_subcommands?
227
+ warn("--message_server_use_ipaddr is deprecated and will be ignored") if options[:message_server_use_ipaddr]
228
228
  self
229
229
  end
230
230
 
231
- def both_host_and_use_ip_addr_specified?
232
- !options[:message_server_host].nil? && options[:message_server_use_ipaddr] == true
233
- end
234
-
235
231
  def multiple_message_subcommands?
236
232
  a = [options[:message_server_config], options[:message_server_unconfig], options[:message_client_config], options[:message_client_unconfig]]
237
233
  a.each_with_object(Hash.new(0)) { |o, h| h[o] += 1 }[true] > 1
@@ -121,32 +121,7 @@ module ApplianceConsole
121
121
  self.port = ask_for_integer("port number", nil, port) unless local?
122
122
  self.database = just_ask("name of the database on #{host}", database) unless local?
123
123
  self.username = just_ask("username", username) unless local?
124
- count = 0
125
- loop do
126
- password1 = ask_for_password("database password on #{host}", password)
127
- # if they took the default, just bail
128
- break if (password1 == password)
129
-
130
- if password1.strip.length == 0
131
- say("\nPassword can not be empty, please try again")
132
- next
133
- end
134
- if password_twice
135
- password2 = ask_for_password("database password again")
136
- if password1 == password2
137
- self.password = password1
138
- break
139
- elsif count > 0 # only reprompt password once
140
- raise "passwords did not match"
141
- else
142
- count += 1
143
- say("\nThe passwords did not match, please try again")
144
- end
145
- else
146
- self.password = password1
147
- break
148
- end
149
- end
124
+ self.password = ask_for_new_password("database password on #{host}", :default => password, :confirm_password => password_twice)
150
125
  end
151
126
 
152
127
  def friendly_inspect
@@ -6,6 +6,7 @@ module ManageIQ
6
6
  module ApplianceConsole
7
7
  class DatabaseReplication
8
8
  include ManageIQ::ApplianceConsole::Logging
9
+ include ManageIQ::ApplianceConsole::Prompts
9
10
 
10
11
  PGPASS_FILE = '/var/lib/pgsql/.pgpass'.freeze
11
12
  NETWORK_INTERFACE = 'eth0'.freeze
@@ -115,25 +116,9 @@ Replication Server Configuration
115
116
  private
116
117
 
117
118
  def ask_for_cluster_database_credentials
118
- self.database_name = just_ask("cluster database name", database_name)
119
- self.database_user = just_ask("cluster database username", database_user)
120
-
121
- count = 0
122
- loop do
123
- count += 1
124
- password1 = ask_for_password("cluster database password", database_password)
125
- # if they took the default, just bail
126
- break if password1 == database_password
127
- password2 = ask_for_password("cluster database password")
128
- if password1 == password2
129
- self.database_password = password1
130
- break
131
- elsif count > 1 # only reprompt password once
132
- raise RuntimeError, "passwords did not match"
133
- else
134
- say("\nThe passwords did not match, please try again")
135
- end
136
- end
119
+ self.database_name = just_ask("cluster database name", database_name)
120
+ self.database_user = just_ask("cluster database username", database_user)
121
+ self.database_password = ask_for_new_password("cluster database password", :default => database_password)
137
122
  end
138
123
 
139
124
  def run_repmgr_command(cmd, params = {})
@@ -7,6 +7,7 @@ module ManageIQ
7
7
  module ApplianceConsole
8
8
  class MessageConfiguration
9
9
  include ManageIQ::ApplianceConsole::ManageiqUserMixin
10
+ include ManageIQ::ApplianceConsole::Prompts
10
11
 
11
12
  attr_reader :message_keystore_username, :message_keystore_password,
12
13
  :message_server_host, :message_server_port,
@@ -67,7 +68,7 @@ module ManageIQ
67
68
  show_parameters
68
69
  return false unless agree("\nProceed? (Y/N): ")
69
70
 
70
- return false unless host_reachable?(message_server_host, "Message Server Host:")
71
+ return false unless host_resolvable?(message_server_host) && host_reachable?(message_server_host, "Message Server Host:")
71
72
 
72
73
  true
73
74
  end
@@ -189,6 +190,29 @@ module ManageIQ
189
190
  true
190
191
  end
191
192
 
193
+ def host_resolvable?(host)
194
+ require 'ipaddr'
195
+ require 'resolv'
196
+
197
+ say("Checking if #{host} is resolvable ... ")
198
+ begin
199
+ ip_address = Resolv.getaddress(host)
200
+
201
+ if IPAddr.new("127.0.0.1/8").include?(ip_address) || IPAddr.new("::1/128").include?(ip_address)
202
+ say("Failed.\nThe hostname must not resolve to a link-local address")
203
+
204
+ return false
205
+ end
206
+ rescue Resolv::ResolvError => e
207
+ say("Failed.\nHostname #{host} is not resolvable: #{e.message}")
208
+
209
+ return false
210
+ end
211
+
212
+ say("Succeeded.")
213
+ true
214
+ end
215
+
192
216
  def unconfigure
193
217
  remove_installed_files
194
218
  end
@@ -20,7 +20,7 @@ module ManageIQ
20
20
  @message_truststore_path_src = options[:message_truststore_path_src] || truststore_path
21
21
  @message_ca_cert_path_src = options[:message_ca_cert_path_src] || ca_cert_path
22
22
 
23
- @installed_files = [client_properties_path, messaging_yaml_path, truststore_path]
23
+ @installed_files = [client_properties_path, messaging_yaml_path, truststore_path, ca_cert_path]
24
24
  end
25
25
 
26
26
  def configure
@@ -46,14 +46,14 @@ module ManageIQ
46
46
  def ask_for_parameters
47
47
  say("\nMessage Client Parameters:\n\n")
48
48
 
49
- @message_server_host = ask_for_string("Message Server Hostname or IP address")
49
+ @message_server_host = ask_for_messaging_hostname("Message Server Hostname")
50
50
  @message_server_port = ask_for_integer("Message Server Port number", (1..65_535), 9_093).to_i
51
51
  @message_server_username = ask_for_string("Message Server Username", message_server_username)
52
52
  @message_server_password = ask_for_password("Message Server Password")
53
53
  @message_truststore_path_src = ask_for_string("Message Server Truststore Path", truststore_path)
54
54
  @message_ca_cert_path_src = ask_for_string("Message Server CA Cert Path", ca_cert_path)
55
55
  @message_keystore_username = ask_for_string("Message Keystore Username", message_keystore_username) if secure?
56
- @message_keystore_password = ask_for_password("Message Keystore Password") if secure?
56
+ @message_keystore_password = ask_for_messaging_password("Message Keystore Password") if secure?
57
57
  end
58
58
 
59
59
  def show_parameters
@@ -17,7 +17,7 @@ module ManageIQ
17
17
  def initialize(options = {})
18
18
  super(options)
19
19
 
20
- @message_server_host = options[:message_server_use_ipaddr] == true ? my_ipaddr : options[:message_server_host] || my_hostname
20
+ @message_server_host = options[:message_server_host] || my_hostname
21
21
  @message_persistent_disk = LinuxAdmin::Disk.new(:path => options[:message_persistent_disk]) unless options[:message_persistent_disk].nil?
22
22
 
23
23
  @jaas_config_path = config_dir_path.join("kafka_server_jaas.conf")
@@ -68,14 +68,10 @@ module ManageIQ
68
68
  def ask_for_parameters
69
69
  say("\nMessage Server Parameters:\n\n")
70
70
 
71
- @message_server_host = ask_for_string("Message Server Hostname or IP address", message_server_host)
72
-
73
- # SSL Validation for Kafka does not work for hostnames containing "localhost"
74
- # Therefore we replace with the equivalent IP "127.0.0.1" if a /localhost*/ hostname was entered
75
- @message_server_host = "127.0.0.1" if @message_server_host.include?("localhost")
71
+ @message_server_host = ask_for_messaging_hostname("Message Server Hostname", message_server_host)
76
72
 
77
73
  @message_keystore_username = ask_for_string("Message Keystore Username", message_keystore_username)
78
- @message_keystore_password = ask_for_password("Message Keystore Password")
74
+ @message_keystore_password = ask_for_messaging_password("Message Keystore Password")
79
75
  @message_persistent_disk = ask_for_persistent_disk
80
76
  end
81
77
 
@@ -84,7 +80,7 @@ module ManageIQ
84
80
  end
85
81
 
86
82
  def use_new_disk
87
- agree("Configure a new persistent disk volume? (Y/N): ")
83
+ agree("Configure a new persistent disk volume? (optional) (Y/N): ")
88
84
  end
89
85
 
90
86
  def choose_disk
@@ -301,13 +297,8 @@ module ManageIQ
301
297
  "-genkey" => nil,
302
298
  "-keyalg" => "RSA"}
303
299
 
304
- if message_server_host.ipaddress?
305
- keystore_params["-alias"] = "localhost"
306
- keystore_params["-ext"] = "san=ip:#{message_server_host}"
307
- else
308
- keystore_params["-alias"] = message_server_host
309
- keystore_params["-ext"] = "san=dns:#{message_server_host}"
310
- end
300
+ keystore_params["-alias"] = message_server_host
301
+ keystore_params["-ext"] = "san=dns:#{message_server_host}"
311
302
 
312
303
  keystore_params["-dname"] = "cn=#{keystore_params["-alias"]}"
313
304
 
@@ -14,6 +14,8 @@ module ApplianceConsole
14
14
  INT_REGEXP = /^[0-9]+$/
15
15
  NONE_REGEXP = /^('?NONE'?)?$/i.freeze
16
16
  HOSTNAME_REGEXP = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/.freeze
17
+ MESSAGING_HOSTNAME_REGEXP = /^(?!.*localhost)(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/.freeze
18
+ MESSAGING_PASSWORD_REGEXP = /\A[a-zA-Z0-9_\-\.\$\*]+\z/.freeze
17
19
 
18
20
  def ask_for_uri(prompt, expected_scheme, opts = {})
19
21
  require 'uri'
@@ -71,6 +73,11 @@ module ApplianceConsole
71
73
  just_ask(prompt, default, validate, error_text, &block)
72
74
  end
73
75
 
76
+ def ask_for_messaging_hostname(prompt, default = nil, error_text = "a valid Messaging Hostname (not an IP or localhost)", &block)
77
+ validation = ->(h) { h =~ MESSAGING_HOSTNAME_REGEXP && h !~ IP_REGEXP }
78
+ just_ask(prompt, default, validation, error_text, &block)
79
+ end
80
+
74
81
  def ask_for_ip_or_hostname(prompt, default = nil)
75
82
  validation = ->(h) { (h =~ HOSTNAME_REGEXP || h =~ IP_REGEXP) && h.length > 0 }
76
83
  ask_for_ip(prompt, default, validation, "a valid Hostname or IP Address.")
@@ -113,6 +120,36 @@ module ApplianceConsole
113
120
  pass == "********" ? (default || "") : pass
114
121
  end
115
122
 
123
+ def ask_for_new_password(prompt, default: nil, allow_empty: false, retry_limit: 1, confirm_password: true, validation: nil, validation_err: nil)
124
+ count = 0
125
+ loop do
126
+ password1 = ask_for_password(prompt, default)
127
+ if password1.strip.empty? && !allow_empty
128
+ say("\nPassword can not be empty, please try again")
129
+ next
130
+ end
131
+
132
+ if validation && password1 !~ validation
133
+ say("\nPassword is invalid: #{validation_err}, please try again")
134
+ next
135
+ end
136
+
137
+ return password1 if password1 == default || !confirm_password
138
+
139
+ password2 = ask_for_password(prompt)
140
+ return password1 if password1 == password2
141
+
142
+ raise "passwords did not match" if count >= retry_limit
143
+
144
+ count += 1
145
+ say("\nThe passwords did not match, please try again")
146
+ end
147
+ end
148
+
149
+ def ask_for_messaging_password(prompt)
150
+ ask_for_new_password(prompt, :validation => MESSAGING_PASSWORD_REGEXP, :validation_err => "allowed characters are a-z, A-Z, 0-9, -, _, ., $, and *")
151
+ end
152
+
116
153
  def ask_for_string(prompt, default = nil)
117
154
  just_ask(prompt, default)
118
155
  end
@@ -1,5 +1,5 @@
1
1
  module ManageIQ
2
2
  module ApplianceConsole
3
- VERSION = '9.0.3'.freeze
3
+ VERSION = '9.1.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manageiq-appliance_console
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.0.3
4
+ version: 9.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ManageIQ Developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-06 00:00:00.000000000 Z
11
+ date: 2024-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord