manageiq-appliance_console 6.1.0 → 7.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/README.md +1 -1
- data/lib/manageiq/appliance_console/cli.rb +116 -65
- data/lib/manageiq/appliance_console/database_admin.rb +35 -206
- data/lib/manageiq/appliance_console/database_configuration.rb +8 -1
- data/lib/manageiq/appliance_console/external_auth_options.rb +3 -13
- data/lib/manageiq/appliance_console/internal_database_configuration.rb +3 -11
- data/lib/manageiq/appliance_console/key_configuration.rb +8 -1
- data/lib/manageiq/appliance_console/manageiq_user_mixin.rb +15 -0
- data/lib/manageiq/appliance_console/message_configuration.rb +9 -3
- data/lib/manageiq/appliance_console/message_configuration_client.rb +2 -0
- data/lib/manageiq/appliance_console/message_configuration_server.rb +2 -0
- data/lib/manageiq/appliance_console/postgres_admin.rb +93 -6
- data/lib/manageiq/appliance_console/utilities.rb +16 -1
- data/lib/manageiq/appliance_console/version.rb +1 -1
- data/locales/appliance/en.yml +0 -16
- data/manageiq-appliance_console.gemspec +4 -3
- metadata +42 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bd1a3dd9e162ed9ac08eb8ff6b19cdee44dc53ceefd0264f1634b2969e4280b
|
4
|
+
data.tar.gz: 7a67c4fadf2f58b10a147e9aa1e8868be5d546eb4dcbab5a20c787bf7fd04594
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73a9f64122a24403e2914ff6505d9b7266dc672a1569d4c3c9289fe999f95adc54be4051299e3bf95c1643c3e48eaa8ebc21cc8d63bb7b6fdedb22f7e00e54e1
|
7
|
+
data.tar.gz: 5bc8dcd47e5d82b4e2eb2aad8294b73b369c1119b0af08652d83f3733c7ff6e92b97542ba6bf9fafbc2344482af996a7d1ef2238223de87f0147b04d6412db45
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# ManageIQ::ApplianceConsole
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/manageiq-appliance_console.svg)](http://badge.fury.io/rb/manageiq-appliance_console)
|
4
|
-
[![Build Status](https://travis-ci.com/ManageIQ/manageiq-appliance_console.svg?branch=master)](https://travis-ci.com/ManageIQ/manageiq-appliance_console)
|
4
|
+
[![Build Status](https://travis-ci.com/ManageIQ/manageiq-appliance_console.svg?branch=master)](https://travis-ci.com/github/ManageIQ/manageiq-appliance_console)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/ManageIQ/manageiq-appliance_console.svg)](https://codeclimate.com/github/ManageIQ/manageiq-appliance_console)
|
6
6
|
[![Test Coverage](https://codeclimate.com/github/ManageIQ/manageiq-appliance_console/badges/coverage.svg)](https://codeclimate.com/github/ManageIQ/manageiq-appliance_console/coverage)
|
7
7
|
[![Security](https://hakiri.io/github/ManageIQ/manageiq-appliance_console/master.svg)](https://hakiri.io/github/ManageIQ/manageiq-appliance_console/master)
|
@@ -38,7 +38,23 @@ module ApplianceConsole
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def database?
|
41
|
-
options[:standalone] || hostname
|
41
|
+
(options[:standalone] || hostname) && !database_admin?
|
42
|
+
end
|
43
|
+
|
44
|
+
def database_admin?
|
45
|
+
db_dump? || db_backup? || db_restore?
|
46
|
+
end
|
47
|
+
|
48
|
+
def db_dump?
|
49
|
+
options[:dump]
|
50
|
+
end
|
51
|
+
|
52
|
+
def db_backup?
|
53
|
+
options[:backup]
|
54
|
+
end
|
55
|
+
|
56
|
+
def db_restore?
|
57
|
+
options[:restore]
|
42
58
|
end
|
43
59
|
|
44
60
|
def local_database?
|
@@ -139,68 +155,72 @@ module ApplianceConsole
|
|
139
155
|
self.options = Optimist.options(args) do
|
140
156
|
banner "Usage: appliance_console_cli [options]"
|
141
157
|
|
142
|
-
opt :host,
|
143
|
-
opt :region,
|
144
|
-
opt :internal,
|
145
|
-
opt :hostname,
|
146
|
-
opt :port,
|
147
|
-
opt :username,
|
148
|
-
opt :password,
|
149
|
-
opt :dbname,
|
150
|
-
opt :
|
151
|
-
opt :
|
152
|
-
opt :
|
153
|
-
opt :
|
154
|
-
opt :
|
155
|
-
opt :
|
156
|
-
opt :
|
157
|
-
opt :
|
158
|
-
opt :
|
159
|
-
opt :
|
160
|
-
opt :
|
161
|
-
opt :
|
162
|
-
opt :
|
163
|
-
opt :
|
164
|
-
opt :
|
165
|
-
opt :
|
166
|
-
opt :
|
167
|
-
opt :
|
168
|
-
opt :
|
169
|
-
opt :
|
170
|
-
opt :
|
171
|
-
opt :
|
172
|
-
opt :
|
173
|
-
opt :
|
174
|
-
opt :
|
175
|
-
opt :
|
176
|
-
opt :
|
177
|
-
opt :
|
178
|
-
opt :
|
179
|
-
opt :
|
180
|
-
opt :
|
181
|
-
opt :
|
182
|
-
opt :
|
183
|
-
opt :
|
184
|
-
opt :
|
185
|
-
opt :
|
186
|
-
opt :
|
187
|
-
opt :
|
188
|
-
opt :
|
189
|
-
opt :
|
190
|
-
opt :
|
191
|
-
opt :
|
192
|
-
opt :
|
193
|
-
opt :
|
194
|
-
opt :
|
195
|
-
opt :
|
196
|
-
opt :
|
197
|
-
opt :
|
198
|
-
opt :
|
199
|
-
opt :
|
200
|
-
opt :
|
201
|
-
opt :
|
202
|
-
opt :
|
203
|
-
opt :
|
158
|
+
opt :host, "/etc/hosts name", :type => :string, :short => 'H'
|
159
|
+
opt :region, "Region Number", :type => :integer, :short => "r"
|
160
|
+
opt :internal, "Internal Database", :short => 'i'
|
161
|
+
opt :hostname, "Database Hostname", :type => :string, :short => 'h'
|
162
|
+
opt :port, "Database Port", :type => :integer, :default => 5432
|
163
|
+
opt :username, "Database Username", :type => :string, :short => 'U', :default => "root"
|
164
|
+
opt :password, "Database Password", :type => :string, :short => "p"
|
165
|
+
opt :dbname, "Database Name", :type => :string, :short => "d", :default => "vmdb_production"
|
166
|
+
opt :local_file, "Source/Destination file for DB dump/backup/restore", :type => :string, :shoft => "l"
|
167
|
+
opt :dump, "Perform a pg-dump"
|
168
|
+
opt :backup, "Perform a pg-basebackup"
|
169
|
+
opt :restore, "Restore a database dump/backup"
|
170
|
+
opt :standalone, "Run this server as a standalone database server", :type => :bool, :short => 'S'
|
171
|
+
opt :key, "Create encryption key", :type => :boolean, :short => "k"
|
172
|
+
opt :fetch_key, "SSH host with encryption key", :type => :string, :short => "K"
|
173
|
+
opt :force_key, "Forcefully create encryption key", :type => :boolean, :short => "f"
|
174
|
+
opt :sshlogin, "SSH login", :type => :string, :default => "root"
|
175
|
+
opt :sshpassword, "SSH password", :type => :string
|
176
|
+
opt :replication, "Configure database replication as primary or standby", :type => :string, :short => :none
|
177
|
+
opt :primary_host, "Primary database host IP address", :type => :string, :short => :none
|
178
|
+
opt :standby_host, "Standby database host IP address", :type => :string, :short => :none
|
179
|
+
opt :auto_failover, "Configure Replication Manager (repmgrd) for automatic failover", :type => :bool, :short => :none
|
180
|
+
opt :cluster_node_number, "Database unique cluster node number", :type => :integer, :short => :none
|
181
|
+
opt :verbose, "Verbose", :type => :boolean, :short => "v"
|
182
|
+
opt :dbdisk, "Database Disk Path", :type => :string
|
183
|
+
opt :logdisk, "Log Disk Path", :type => :string
|
184
|
+
opt :tmpdisk, "Temp storage Disk Path", :type => :string
|
185
|
+
opt :uninstall_ipa, "Uninstall IPA Client", :type => :boolean, :default => false
|
186
|
+
opt :ipaserver, "IPA Server FQDN", :type => :string
|
187
|
+
opt :ipaprincipal, "IPA Server principal", :type => :string, :default => "admin"
|
188
|
+
opt :ipapassword, "IPA Server password", :type => :string
|
189
|
+
opt :ipadomain, "IPA Server domain (optional)", :type => :string
|
190
|
+
opt :iparealm, "IPA Server realm (optional)", :type => :string
|
191
|
+
opt :ca, "CA name used for certmonger", :type => :string, :default => "ipa"
|
192
|
+
opt :http_cert, "install certs for http server", :type => :boolean
|
193
|
+
opt :extauth_opts, "External Authentication Options", :type => :string
|
194
|
+
opt :saml_config, "Configure Appliance for SAML Authentication", :type => :boolean, :default => false
|
195
|
+
opt :saml_client_host, "Optional Appliance host used for SAML registration", :type => :string
|
196
|
+
opt :saml_idp_metadata, "The file path or URL of the SAML IDP Metadata", :type => :string
|
197
|
+
opt :saml_enable_sso, "Optionally enable SSO with SAML Authentication", :type => :boolean, :default => false
|
198
|
+
opt :saml_unconfig, "Unconfigure Appliance SAML Authentication", :type => :boolean, :default => false
|
199
|
+
opt :oidc_config, "Configure Appliance for OpenID-Connect Authentication", :type => :boolean, :default => false
|
200
|
+
opt :oidc_url, "The OpenID-Connect Provider URL", :type => :string
|
201
|
+
opt :oidc_client_host, "Optional Appliance host used for OpenID-Connect Authentication", :type => :string
|
202
|
+
opt :oidc_client_id, "The OpenID-Connect Provider Client ID", :type => :string
|
203
|
+
opt :oidc_client_secret, "The OpenID-Connect Provider Client Secret", :type => :string
|
204
|
+
opt :oidc_insecure, "OpenID-Connect Insecure No SSL Verify (development)", :type => :boolean, :default => false
|
205
|
+
opt :oidc_introspection_endpoint, "The OpenID-Connect Provider Introspect Endpoint", :type => :string
|
206
|
+
opt :oidc_enable_sso, "Optionally enable SSO with OpenID-Connect Authentication", :type => :boolean, :default => false
|
207
|
+
opt :oidc_unconfig, "Unconfigure Appliance OpenID-Connect Authentication", :type => :boolean, :default => false
|
208
|
+
opt :server, "{start|stop|restart} actions on evmserverd Server", :type => :string
|
209
|
+
opt :openscap, "Setup OpenScap", :type => :boolean, :default => false
|
210
|
+
opt :message_server_config, "Subcommand to Configure Appliance as a Kafka Message Server", :type => :boolean, :default => false
|
211
|
+
opt :message_server_unconfig, "Subcommand to Unconfigure Appliance as a Kafka Message Server", :type => :boolean, :default => false
|
212
|
+
opt :message_client_config, "Subcommand to Configure Appliance as a Kafka Message Client", :type => :boolean, :default => false
|
213
|
+
opt :message_client_unconfig, "Subcommand to Unconfigure Appliance as a Kafka Message Client", :type => :boolean, :default => false
|
214
|
+
opt :message_keystore_username, "Message Server Keystore Username", :type => :string
|
215
|
+
opt :message_keystore_password, "Message Server Keystore Password", :type => :string
|
216
|
+
opt :message_server_username, "Message Server Username", :type => :string
|
217
|
+
opt :message_server_password, "Message Server password", :type => :string
|
218
|
+
opt :message_server_port, "Message Server Port", :type => :integer
|
219
|
+
opt :message_server_use_ipaddr, "Message Server Use Address", :type => :boolean, :default => false
|
220
|
+
opt :message_server_host, "Message Server Hostname or IP Address", :type => :string
|
221
|
+
opt :message_truststore_path_src, "Message Server Truststore Path", :type => :string
|
222
|
+
opt :message_ca_cert_path_src, "Message Server CA Cert Path", :type => :string
|
223
|
+
opt :message_persistent_disk, "Message Persistent Disk Path", :type => :string
|
204
224
|
end
|
205
225
|
Optimist.die :region, "needed when setting up a local database" if region_number_required? && options[:region].nil?
|
206
226
|
Optimist.die "Supply only one of --message-server-host or --message-server-use-ipaddr=true" if both_host_and_use_ip_addr_specified?
|
@@ -218,11 +238,12 @@ module ApplianceConsole
|
|
218
238
|
end
|
219
239
|
|
220
240
|
def region_number_required?
|
221
|
-
!options[:standalone] && local_database?
|
241
|
+
!options[:standalone] && local_database? && !database_admin?
|
222
242
|
end
|
223
243
|
|
224
244
|
def run
|
225
|
-
Optimist.educate unless set_host? || key? || database? ||
|
245
|
+
Optimist.educate unless set_host? || key? || database? || db_dump? || db_backup? ||
|
246
|
+
db_restore? || tmp_disk? || log_disk? ||
|
226
247
|
uninstall_ipa? || install_ipa? || certs? || extauth_opts? ||
|
227
248
|
set_server_state? || set_replication? || openscap? ||
|
228
249
|
saml_config? || saml_unconfig? ||
|
@@ -240,6 +261,9 @@ module ApplianceConsole
|
|
240
261
|
create_key if key?
|
241
262
|
set_db if database?
|
242
263
|
set_replication if set_replication?
|
264
|
+
db_dump if db_dump?
|
265
|
+
db_backup if db_backup?
|
266
|
+
db_restore if db_restore?
|
243
267
|
config_tmp_disk if tmp_disk?
|
244
268
|
config_log_disk if log_disk?
|
245
269
|
uninstall_ipa if uninstall_ipa?
|
@@ -344,6 +368,33 @@ module ApplianceConsole
|
|
344
368
|
db_replication.activate
|
345
369
|
end
|
346
370
|
|
371
|
+
def db_dump
|
372
|
+
PostgresAdmin.backup_pg_dump(extract_db_opts(options))
|
373
|
+
end
|
374
|
+
|
375
|
+
def db_backup
|
376
|
+
PostgresAdmin.backup(extract_db_opts(options))
|
377
|
+
end
|
378
|
+
|
379
|
+
def db_restore
|
380
|
+
PostgresAdmin.restore(extract_db_opts(options))
|
381
|
+
end
|
382
|
+
|
383
|
+
DB_OPT_KEYS = %i[dbname username password hostname port local_file].freeze
|
384
|
+
def extract_db_opts(options)
|
385
|
+
require 'manageiq/appliance_console/postgres_admin'
|
386
|
+
|
387
|
+
db_opts = {}
|
388
|
+
|
389
|
+
DB_OPT_KEYS.each { |k| db_opts[k] = options[k] if options[k] }
|
390
|
+
|
391
|
+
if db_dump? && options[:exclude_table_data]
|
392
|
+
db_opts[:exclude_table_data] = options[:exclude_table_data]
|
393
|
+
end
|
394
|
+
|
395
|
+
db_opts
|
396
|
+
end
|
397
|
+
|
347
398
|
def key_configuration
|
348
399
|
@key_configuration ||= KeyConfiguration.new(
|
349
400
|
:action => options[:fetch_key] ? :fetch : :create,
|
@@ -23,22 +23,17 @@ module ManageIQ
|
|
23
23
|
|
24
24
|
WARN
|
25
25
|
|
26
|
-
|
27
|
-
attr_reader :action, :backup_type, :task, :task_params, :delete_agree, :filename
|
26
|
+
attr_reader :action, :backup_type, :database_opts, :delete_agree, :filename
|
28
27
|
|
29
28
|
def initialize(action = :restore, input = $stdin, output = $stdout)
|
30
29
|
super(input, output)
|
31
30
|
|
32
|
-
@action
|
33
|
-
@
|
31
|
+
@action = action
|
32
|
+
@database_opts = {:dbname => DatabaseConfiguration.database_name}
|
34
33
|
end
|
35
34
|
|
36
|
-
def
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
def object_store_backup?
|
41
|
-
backup_type == "s3".freeze || backup_type == "swift".freeze
|
35
|
+
def uri
|
36
|
+
@database_opts[:local_file]
|
42
37
|
end
|
43
38
|
|
44
39
|
def ask_questions
|
@@ -51,7 +46,6 @@ module ManageIQ
|
|
51
46
|
say(DB_DUMP_WARNING) if action == :dump
|
52
47
|
ask_file_location
|
53
48
|
ask_for_tables_to_exclude_in_dump
|
54
|
-
ask_to_split_up_output
|
55
49
|
end
|
56
50
|
|
57
51
|
def activate
|
@@ -63,144 +57,11 @@ module ManageIQ
|
|
63
57
|
end
|
64
58
|
|
65
59
|
def ask_file_location
|
66
|
-
@
|
67
|
-
menu.choice(CANCEL) { |_| raise MiqSignalError }
|
68
|
-
end
|
69
|
-
if URI(backup_type).scheme
|
70
|
-
ask_custom_file_options(backup_type)
|
71
|
-
else
|
72
|
-
# calling methods like ask_ftp_file_options and ask_s3_file_options
|
73
|
-
send("ask_#{backup_type}_file_options")
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def ask_local_file_options
|
78
|
-
@uri = just_ask(*filename_prompt_args)
|
79
|
-
@task = "evm:db:#{action}:local"
|
80
|
-
@task_params = ["--", {:local_file => uri}]
|
81
|
-
end
|
82
|
-
|
83
|
-
def ask_nfs_file_options
|
84
|
-
@filename = just_ask(*filename_prompt_args) unless action == :restore
|
85
|
-
@uri = ask_for_uri(*remote_file_prompt_args_for("nfs"))
|
86
|
-
@task = "evm:db:#{action}:remote"
|
87
|
-
|
88
|
-
params = {:uri => uri}
|
89
|
-
params[:remote_file_name] = filename if filename
|
90
|
-
|
91
|
-
@task_params = ["--", params]
|
92
|
-
end
|
93
|
-
|
94
|
-
def ask_smb_file_options
|
95
|
-
@filename = just_ask(*filename_prompt_args) unless action == :restore
|
96
|
-
@uri = ask_for_uri(*remote_file_prompt_args_for("smb"))
|
97
|
-
user = just_ask(USER_PROMPT)
|
98
|
-
pass = ask_for_password("password for #{user}")
|
99
|
-
|
100
|
-
params = {
|
101
|
-
:uri => uri,
|
102
|
-
:uri_username => user,
|
103
|
-
:uri_password => pass
|
104
|
-
}
|
105
|
-
params[:remote_file_name] = filename if filename
|
106
|
-
|
107
|
-
@task = "evm:db:#{action}:remote"
|
108
|
-
@task_params = ["--", params]
|
109
|
-
end
|
110
|
-
|
111
|
-
def ask_s3_file_options
|
112
|
-
access_key_prompt = <<-PROMPT.strip_heredoc.chomp
|
113
|
-
Access Key ID with access to this file.
|
114
|
-
Example: 'amazon_aws_user'
|
115
|
-
PROMPT
|
116
|
-
|
117
|
-
@filename = just_ask(*filename_prompt_args) unless action == :restore
|
118
|
-
@uri = ask_for_uri(*remote_file_prompt_args_for("s3"), :optional_path => true)
|
119
|
-
region = just_ask("Amazon Region for database file", "us-east-1")
|
120
|
-
user = just_ask(access_key_prompt)
|
121
|
-
pass = ask_for_password("Secret Access Key for #{user}")
|
122
|
-
|
123
|
-
params = {
|
124
|
-
:uri => uri,
|
125
|
-
:uri_username => user,
|
126
|
-
:uri_password => pass,
|
127
|
-
:aws_region => region
|
128
|
-
}
|
129
|
-
params[:remote_file_name] = filename if filename
|
130
|
-
|
131
|
-
@task = "evm:db:#{action}:remote"
|
132
|
-
@task_params = ["--", params]
|
133
|
-
end
|
134
|
-
|
135
|
-
def ask_ftp_file_options
|
136
|
-
@filename = just_ask(*filename_prompt_args) unless action == :restore
|
137
|
-
@uri = ask_for_uri(*remote_file_prompt_args_for("ftp"), :optional_path => true)
|
138
|
-
user = just_ask(USER_PROMPT)
|
139
|
-
pass = ask_for_password("password for #{user}")
|
140
|
-
|
141
|
-
params = { :uri => uri }
|
142
|
-
params[:uri_username] = user if user.present?
|
143
|
-
params[:uri_password] = pass if pass.present?
|
144
|
-
params[:remote_file_name] = filename if filename
|
145
|
-
|
146
|
-
@task = "evm:db:#{action}:remote"
|
147
|
-
@task_params = ["--", params]
|
148
|
-
end
|
149
|
-
|
150
|
-
def ask_custom_file_options(server_uri)
|
151
|
-
hostname = URI(server_uri).host
|
152
|
-
@filename = ask_custom_file_prompt(hostname)
|
153
|
-
@uri = server_uri
|
154
|
-
|
155
|
-
params = {:uri => uri, :remote_file_name => filename}
|
156
|
-
|
157
|
-
if (custom_params = custom_endpoint_config_for(hostname))
|
158
|
-
params.merge!(custom_params[:rake_options]) if custom_params[:rake_options]
|
159
|
-
end
|
160
|
-
|
161
|
-
@task = "evm:db:#{action}:remote"
|
162
|
-
@task_params = ["--", params]
|
163
|
-
end
|
164
|
-
|
165
|
-
def ask_swift_file_options
|
166
|
-
require 'uri'
|
167
|
-
swift_user_prompt = <<-PROMPT.strip_heredoc.chomp
|
168
|
-
User Name with access to this file.
|
169
|
-
Example: 'openstack_user'
|
170
|
-
PROMPT
|
171
|
-
|
172
|
-
@filename = just_ask(*filename_prompt_args) { |q| q.readline = false } unless action == :restore
|
173
|
-
@uri = URI(ask_for_uri(*remote_file_prompt_args_for("swift")) { |q| q.readline = false })
|
174
|
-
@task = "evm:db:#{action}:remote"
|
175
|
-
user = just_ask(swift_user_prompt) { |q| q.readline = false }
|
176
|
-
pass = ask_for_password("password for #{user}") { |q| q.readline = false }
|
177
|
-
@uri.query = swift_query_elements.join('&').presence
|
178
|
-
|
179
|
-
params = {
|
180
|
-
:uri => @uri.to_s,
|
181
|
-
:uri_username => user,
|
182
|
-
:uri_password => pass
|
183
|
-
}
|
184
|
-
params[:remote_file_name] = filename if filename
|
185
|
-
@task = "evm:db:#{action}:remote"
|
186
|
-
@task_params = ["--", params]
|
187
|
-
end
|
188
|
-
|
189
|
-
def swift_query_elements
|
190
|
-
region = just_ask("OpenStack Swift Region") { |q| q.readline = false }
|
191
|
-
@uri.port = just_ask("OpenStack Swift Port", "5000") { |q| q.readline = false }
|
192
|
-
security_protocol = ask_with_menu(*security_protocol_menu_args)
|
193
|
-
api_version = ask_with_menu(*api_version_menu_args) { |q| q.readline = false }
|
194
|
-
domain_ident = just_ask("OpenStack V3 Domain Identifier") { |q| q.readline = false } if api_version == "v3"
|
195
|
-
query_elements = []
|
196
|
-
query_elements << "region=#{region}" if region.present?
|
197
|
-
query_elements << "api_version=#{api_version}" if api_version.present?
|
198
|
-
query_elements << "domain_id=#{domain_ident}" if domain_ident.present?
|
199
|
-
query_elements << "security_protocol=#{security_protocol}" if security_protocol.present?
|
60
|
+
@database_opts[:local_file] = just_ask(*filename_prompt_args)
|
200
61
|
end
|
201
62
|
|
202
63
|
def ask_to_delete_backup_after_restore
|
203
|
-
if action == :restore
|
64
|
+
if action == :restore
|
204
65
|
say("The local database restore file is located at: '#{uri}'.\n")
|
205
66
|
@delete_agree = agree("Should this file be deleted after completing the restore? (Y/N): ")
|
206
67
|
end
|
@@ -222,20 +83,14 @@ module ManageIQ
|
|
222
83
|
255,
|
223
84
|
Float::INFINITY)
|
224
85
|
|
225
|
-
@
|
226
|
-
end || true
|
227
|
-
end
|
228
|
-
|
229
|
-
def ask_to_split_up_output
|
230
|
-
if action == :dump && should_split_output?
|
231
|
-
@task_params.last[:byte_count] = ask_for_string("byte size to split by", "500M")
|
86
|
+
@database_opts[:exclude_table_data] = table_excludes
|
232
87
|
end || true
|
233
88
|
end
|
234
89
|
|
235
90
|
def confirm_and_execute
|
236
91
|
if allowed_to_execute?
|
237
92
|
processing_message
|
238
|
-
|
93
|
+
run_action
|
239
94
|
end
|
240
95
|
press_any_key
|
241
96
|
end
|
@@ -259,58 +114,18 @@ module ManageIQ
|
|
259
114
|
end
|
260
115
|
end
|
261
116
|
|
262
|
-
def api_version_menu_args
|
263
|
-
[
|
264
|
-
"OpenStack API Version",
|
265
|
-
[["Keystone v2".freeze, "v2".freeze], ["Keystone v3".freeze, "v3".freeze], ["None".freeze, nil]].freeze,
|
266
|
-
["Keystone v2".freeze, "v2".freeze],
|
267
|
-
nil
|
268
|
-
]
|
269
|
-
end
|
270
|
-
|
271
|
-
def file_menu_args
|
272
|
-
[
|
273
|
-
action == :restore ? "Restore Database File Source" : "#{action.capitalize} Output File Destination",
|
274
|
-
file_options,
|
275
|
-
"local",
|
276
|
-
nil
|
277
|
-
]
|
278
|
-
end
|
279
|
-
|
280
|
-
def security_protocol_menu_args
|
281
|
-
[
|
282
|
-
"OpenStack Security Protocol",
|
283
|
-
[["SSL without validation".freeze, "ssl".freeze], ["SSL".freeze, "ssl-with-validation".freeze], ["Non-SSL".freeze, "non-ssl".freeze], ["None".freeze, nil]].freeze,
|
284
|
-
["Non-SSL".freeze, "non-ssl".freeze],
|
285
|
-
nil
|
286
|
-
]
|
287
|
-
end
|
288
|
-
|
289
117
|
def setting_header
|
290
118
|
say("#{I18n.t("advanced_settings.db#{action}")}\n\n")
|
291
119
|
end
|
292
120
|
|
293
121
|
private
|
294
122
|
|
295
|
-
def ask_custom_file_prompt(hostname)
|
296
|
-
prompts = custom_endpoint_config_for(hostname)
|
297
|
-
prompt_text = prompts && prompts[:filename_text] || "Target filename for backup".freeze
|
298
|
-
prompt_regex = prompts && prompts[:filename_validator]
|
299
|
-
validator = prompt_regex ? ->(x) { x.to_s =~ /#{prompt_regex}/ } : ->(x) { x.to_s.present? }
|
300
|
-
just_ask(prompt_text, nil, validator)
|
301
|
-
end
|
302
|
-
|
303
123
|
def skip_file_location?(hostname)
|
304
124
|
config = custom_endpoint_config_for(hostname)
|
305
125
|
return false unless config && config[:enabled_for].present?
|
306
126
|
!Array(config[:enabled_for]).include?(action.to_s)
|
307
127
|
end
|
308
128
|
|
309
|
-
def custom_endpoint_config_for(hostname)
|
310
|
-
# hostname has a period in it, so we need to look it up by [] instead of the traditional i18n method
|
311
|
-
I18n.t("database_admin.prompts", :default => {})[hostname.to_sym]
|
312
|
-
end
|
313
|
-
|
314
129
|
def should_exclude_tables?
|
315
130
|
ask_yn?("Would you like to exclude tables in the dump") do |q|
|
316
131
|
q.readline = true
|
@@ -327,16 +142,12 @@ module ManageIQ
|
|
327
142
|
return restore_prompt_args if action == :restore
|
328
143
|
default = action == :dump ? DB_DEFAULT_DUMP_FILE : DB_RESTORE_FILE
|
329
144
|
prompt = "location to save the #{action} file to"
|
330
|
-
if object_store_backup?
|
331
|
-
prompt = "name for the remote #{action} file"
|
332
|
-
default = File.basename(default)
|
333
|
-
end
|
334
145
|
[prompt, default, nil, "file that exists"]
|
335
146
|
end
|
336
147
|
|
337
148
|
def restore_prompt_args
|
338
149
|
default = DB_RESTORE_FILE
|
339
|
-
validator = LOCAL_FILE_VALIDATOR
|
150
|
+
validator = LOCAL_FILE_VALIDATOR
|
340
151
|
prompt = "location of the local restore file"
|
341
152
|
[prompt, default, validator, "file that exists"]
|
342
153
|
end
|
@@ -347,12 +158,12 @@ module ManageIQ
|
|
347
158
|
else
|
348
159
|
"location to save the remote #{action} file to"
|
349
160
|
end
|
350
|
-
prompt += "\nExample: #{sample_url
|
161
|
+
prompt += "\nExample: #{sample_url}"
|
351
162
|
[prompt, remote_type]
|
352
163
|
end
|
353
164
|
|
354
|
-
def sample_url
|
355
|
-
I18n.t("database_admin.sample_url
|
165
|
+
def sample_url
|
166
|
+
I18n.t("database_admin.sample_url.nfs")
|
356
167
|
end
|
357
168
|
|
358
169
|
def processing_message
|
@@ -364,15 +175,33 @@ module ManageIQ
|
|
364
175
|
say(msg)
|
365
176
|
end
|
366
177
|
|
367
|
-
def
|
368
|
-
|
369
|
-
if
|
178
|
+
def run_action
|
179
|
+
success = send(action)
|
180
|
+
if success && action == :restore && delete_agree
|
370
181
|
say("\nRemoving the database restore file #{uri}...")
|
371
182
|
File.delete(uri)
|
372
|
-
elsif !
|
183
|
+
elsif !success
|
373
184
|
say("\nDatabase #{action} failed. Check the logs for more information")
|
374
185
|
end
|
375
186
|
end
|
187
|
+
|
188
|
+
def backup
|
189
|
+
result = PostgresAdmin.backup(database_opts)
|
190
|
+
ManageIQ::ApplianceConsole.logger.info("[#{@database_opts[:dbname]}] database has been backed up to file: [#{uri}]")
|
191
|
+
result
|
192
|
+
end
|
193
|
+
|
194
|
+
def dump
|
195
|
+
result = PostgresAdmin.backup_pg_dump(database_opts)
|
196
|
+
ManageIQ::ApplianceConsole.logger.info("[#{@database_opts[:dbname]}] database has been dumped up to file: [#{uri}]")
|
197
|
+
result
|
198
|
+
end
|
199
|
+
|
200
|
+
def restore
|
201
|
+
result = PostgresAdmin.restore(database_opts.merge(:backup_type => backup_type))
|
202
|
+
ManageIQ::ApplianceConsole.logger.info("[#{@database_opts[:dbname]}] database has been restored from file: [#{uri}]")
|
203
|
+
result
|
204
|
+
end
|
376
205
|
end
|
377
206
|
end
|
378
207
|
end
|
@@ -5,9 +5,13 @@ require 'manageiq-password'
|
|
5
5
|
require 'pathname'
|
6
6
|
require 'fileutils'
|
7
7
|
|
8
|
+
require_relative './manageiq_user_mixin'
|
9
|
+
|
8
10
|
module ManageIQ
|
9
11
|
module ApplianceConsole
|
10
12
|
class DatabaseConfiguration
|
13
|
+
include ManageIQ::ApplianceConsole::ManageiqUserMixin
|
14
|
+
|
11
15
|
attr_accessor :adapter, :host, :username, :database, :port, :region
|
12
16
|
attr_reader :password
|
13
17
|
|
@@ -275,7 +279,10 @@ FRIENDLY
|
|
275
279
|
|
276
280
|
def do_save(settings)
|
277
281
|
require 'yaml'
|
278
|
-
File.
|
282
|
+
File.open(DB_YML, "w") do |f|
|
283
|
+
f.write(YAML.dump(settings))
|
284
|
+
f.chown(manageiq_uid, manageiq_gid)
|
285
|
+
end
|
279
286
|
end
|
280
287
|
|
281
288
|
def initialize_from_hash(hash)
|
@@ -82,8 +82,7 @@ module ApplianceConsole
|
|
82
82
|
say("\nUpdating external authentication options on appliance ...")
|
83
83
|
params = update_hash.collect { |key, value| "#{key}=#{value}" }
|
84
84
|
params = configure_provider_type!(params)
|
85
|
-
|
86
|
-
raise parse_errors(result).join(', ') if result.failure?
|
85
|
+
ManageIQ::ApplianceConsole::Utilities.rake_run!("evm:settings:set", params)
|
87
86
|
end
|
88
87
|
end
|
89
88
|
|
@@ -152,17 +151,8 @@ module ApplianceConsole
|
|
152
151
|
|
153
152
|
def load_current
|
154
153
|
say("\nFetching external authentication options from appliance ...")
|
155
|
-
result = ManageIQ::ApplianceConsole::Utilities.rake_run("evm:settings:get", EXT_AUTH_OPTIONS.keys)
|
156
|
-
|
157
|
-
if result.success?
|
158
|
-
return parse_response(result)
|
159
|
-
else
|
160
|
-
raise parse_errors(result).join(', ')
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
def parse_errors(result)
|
165
|
-
result.error.split("\n").collect { |line| line if line =~ /^error: /i }.compact
|
154
|
+
result = ManageIQ::ApplianceConsole::Utilities.rake_run!("evm:settings:get", EXT_AUTH_OPTIONS.keys)
|
155
|
+
parse_response(result)
|
166
156
|
end
|
167
157
|
|
168
158
|
def normalize_key(key)
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require "pathname"
|
2
2
|
require "manageiq/appliance_console/postgres_admin"
|
3
|
-
require "pg"
|
4
3
|
require "linux_admin"
|
5
4
|
|
6
5
|
module ManageIQ
|
@@ -149,14 +148,14 @@ module ApplianceConsole
|
|
149
148
|
end
|
150
149
|
|
151
150
|
def create_postgres_root_user
|
152
|
-
with_pg_connection do |conn|
|
151
|
+
PostgresAdmin.with_pg_connection do |conn|
|
153
152
|
esc_pass = conn.escape_string(password)
|
154
153
|
conn.exec("CREATE ROLE #{username} WITH LOGIN CREATEDB SUPERUSER PASSWORD '#{esc_pass}'")
|
155
154
|
end
|
156
155
|
end
|
157
156
|
|
158
157
|
def create_postgres_database
|
159
|
-
with_pg_connection do |conn|
|
158
|
+
PostgresAdmin.with_pg_connection do |conn|
|
160
159
|
conn.exec("CREATE DATABASE #{database} OWNER #{username} ENCODING 'utf8'")
|
161
160
|
end
|
162
161
|
end
|
@@ -165,16 +164,9 @@ module ApplianceConsole
|
|
165
164
|
AwesomeSpawn.run!("/sbin/restorecon -R -v #{mount_point}")
|
166
165
|
end
|
167
166
|
|
168
|
-
def with_pg_connection
|
169
|
-
conn = PG.connect(:user => "postgres", :dbname => "postgres")
|
170
|
-
yield conn
|
171
|
-
ensure
|
172
|
-
conn.close
|
173
|
-
end
|
174
|
-
|
175
167
|
def apply_initial_configuration
|
176
168
|
shared_buffers = run_as_evm_server ? SHARED_DB_SHARED_BUFFERS : DEDICATED_DB_SHARED_BUFFERS
|
177
|
-
with_pg_connection { |conn| conn.exec("ALTER SYSTEM SET shared_buffers TO #{shared_buffers}") }
|
169
|
+
PostgresAdmin.with_pg_connection { |conn| conn.exec("ALTER SYSTEM SET shared_buffers TO #{shared_buffers}") }
|
178
170
|
|
179
171
|
restart_postgres
|
180
172
|
end
|
@@ -4,6 +4,8 @@ require 'net/scp'
|
|
4
4
|
require 'active_support/all'
|
5
5
|
require 'manageiq-password'
|
6
6
|
|
7
|
+
require_relative './manageiq_user_mixin'
|
8
|
+
|
7
9
|
module ManageIQ
|
8
10
|
module ApplianceConsole
|
9
11
|
CERT_DIR = ENV['KEY_ROOT'] || ManageIQ::ApplianceConsole::RAILS_ROOT.join("certs")
|
@@ -11,6 +13,8 @@ module ApplianceConsole
|
|
11
13
|
NEW_KEY_FILE = "#{KEY_FILE}.tmp".freeze
|
12
14
|
|
13
15
|
class KeyConfiguration
|
16
|
+
include ManageIQ::ApplianceConsole::ManageiqUserMixin
|
17
|
+
|
14
18
|
attr_accessor :host, :login, :password, :key_path, :action, :force
|
15
19
|
|
16
20
|
def initialize(options = {})
|
@@ -89,7 +93,9 @@ module ApplianceConsole
|
|
89
93
|
end
|
90
94
|
|
91
95
|
def create_key
|
92
|
-
ManageIQ::Password.generate_symmetric(NEW_KEY_FILE)
|
96
|
+
return unless !!ManageIQ::Password.generate_symmetric(NEW_KEY_FILE)
|
97
|
+
|
98
|
+
File.chown(manageiq_uid, manageiq_gid, NEW_KEY_FILE)
|
93
99
|
end
|
94
100
|
|
95
101
|
def fetch_key
|
@@ -97,6 +103,7 @@ module ApplianceConsole
|
|
97
103
|
Net::SCP.start(host, login, :password => password) do |scp|
|
98
104
|
scp.download!(key_path, NEW_KEY_FILE)
|
99
105
|
end
|
106
|
+
File.chown(manageiq_uid, manageiq_gid, NEW_KEY_FILE)
|
100
107
|
File.exist?(NEW_KEY_FILE)
|
101
108
|
rescue => e
|
102
109
|
say("Failed to fetch key: #{e.message}")
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ManageIQ
|
2
|
+
module ApplianceConsole
|
3
|
+
module ManageiqUserMixin
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def manageiq_uid
|
7
|
+
@manageiq_uid ||= Process::UID.from_name("manageiq")
|
8
|
+
end
|
9
|
+
|
10
|
+
def manageiq_gid
|
11
|
+
@manageiq_gid ||= Process::GID.from_name("manageiq")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'active_support/core_ext/module/delegation'
|
2
2
|
require 'pathname'
|
3
3
|
|
4
|
+
require_relative './manageiq_user_mixin'
|
5
|
+
|
4
6
|
module ManageIQ
|
5
7
|
module ApplianceConsole
|
6
8
|
class MessageConfiguration
|
9
|
+
include ManageIQ::ApplianceConsole::ManageiqUserMixin
|
10
|
+
|
7
11
|
attr_reader :message_keystore_username, :message_keystore_password,
|
8
12
|
:message_server_host, :message_server_port,
|
9
13
|
:miq_config_dir_path, :config_dir_path, :sample_config_dir_path,
|
@@ -116,7 +120,10 @@ module ManageIQ
|
|
116
120
|
messaging_yaml["production"]["security.protocol"] = "PLAINTEXT"
|
117
121
|
end
|
118
122
|
|
119
|
-
File.
|
123
|
+
File.open(messaging_yaml_path, "w") do |f|
|
124
|
+
f.write(messaging_yaml.to_yaml)
|
125
|
+
f.chown(manageiq_uid, manageiq_gid)
|
126
|
+
end
|
120
127
|
end
|
121
128
|
|
122
129
|
def remove_installed_files
|
@@ -175,8 +182,7 @@ module ManageIQ
|
|
175
182
|
def configure_messaging_type(value)
|
176
183
|
say(__method__.to_s.tr("_", " ").titleize)
|
177
184
|
|
178
|
-
|
179
|
-
raise parse_errors(result).join(', ') if result.failure?
|
185
|
+
ManageIQ::ApplianceConsole::Utilities.rake_run!("evm:settings:set", ["/prototype/messaging_type=#{value}"])
|
180
186
|
end
|
181
187
|
|
182
188
|
def restart_evmserverd
|
@@ -82,6 +82,8 @@ module ManageIQ
|
|
82
82
|
def fetch_from_server(src_file, dst_file)
|
83
83
|
return if file_found?(dst_file)
|
84
84
|
|
85
|
+
FileUtils.mkdir_p(dst_file.dirname) unless dst_file.dirname.directory?
|
86
|
+
|
85
87
|
Net::SCP.start(message_server_host, message_server_username, :password => message_server_password) do |scp|
|
86
88
|
scp.download!(src_file, dst_file)
|
87
89
|
end
|
@@ -184,6 +184,8 @@ module ManageIQ
|
|
184
184
|
|
185
185
|
keystore_params = assemble_keystore_params
|
186
186
|
|
187
|
+
FileUtils.mkdir_p(keystore_dir_path) unless keystore_dir_path.directory?
|
188
|
+
|
187
189
|
# Generte a Java keystore and key pair, creating keystore.jks
|
188
190
|
# :stdin_data provides the -storepass twice to confirm and an extra CR to accept the same password for -keypass
|
189
191
|
AwesomeSpawn.run!("keytool", :params => keystore_params, :stdin_data => "#{message_keystore_password}\n#{message_keystore_password}\n\n")
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'awesome_spawn'
|
2
2
|
require 'pathname'
|
3
3
|
require 'linux_admin'
|
4
|
+
require 'pg'
|
4
5
|
|
5
6
|
module ManageIQ
|
6
7
|
module ApplianceConsole
|
@@ -46,6 +47,13 @@ module ApplianceConsole
|
|
46
47
|
"xfs".freeze
|
47
48
|
end
|
48
49
|
|
50
|
+
def self.with_pg_connection(db_opts = {:user => user, :dbname => user})
|
51
|
+
conn = PG.connect(db_opts)
|
52
|
+
yield conn
|
53
|
+
ensure
|
54
|
+
conn.close if conn
|
55
|
+
end
|
56
|
+
|
49
57
|
def self.initialized?
|
50
58
|
!Dir[data_directory.join("*")].empty?
|
51
59
|
end
|
@@ -100,13 +108,13 @@ module ApplianceConsole
|
|
100
108
|
|
101
109
|
def self.restore(opts)
|
102
110
|
file = opts[:local_file]
|
103
|
-
backup_type = opts.delete(:backup_type)
|
111
|
+
backup_type = opts.delete(:backup_type) || validate_backup_file_type(file)
|
112
|
+
|
113
|
+
prepare_restore(backup_type, opts[:dbname])
|
104
114
|
|
105
|
-
case
|
106
|
-
when
|
107
|
-
when
|
108
|
-
when pg_dump_file?(file) then restore_pg_dump(opts)
|
109
|
-
when base_backup_file?(file) then restore_pg_basebackup(file)
|
115
|
+
case backup_type
|
116
|
+
when :pgdump then restore_pg_dump(opts)
|
117
|
+
when :basebackup then restore_pg_basebackup(file)
|
110
118
|
else
|
111
119
|
raise "#{file} is not a database backup"
|
112
120
|
end
|
@@ -142,6 +150,7 @@ module ApplianceConsole
|
|
142
150
|
args = combine_command_args(opts, :format => "c", :file => opts[:local_file], nil => dbname)
|
143
151
|
args = handle_multi_value_pg_dump_args!(opts, args)
|
144
152
|
|
153
|
+
FileUtils.mkdir_p(File.dirname(opts.fetch(:local_file, "")))
|
145
154
|
run_command_with_logging("pg_dump", opts, args)
|
146
155
|
opts[:local_file]
|
147
156
|
end
|
@@ -320,6 +329,84 @@ module ApplianceConsole
|
|
320
329
|
ensure
|
321
330
|
File.delete(error_path) if File.exist?(error_path)
|
322
331
|
end
|
332
|
+
|
333
|
+
private_class_method def self.prepare_restore(backup_type, dbname)
|
334
|
+
if application_connections?
|
335
|
+
message = "Database restore failed. Shut down all evmserverd processes before attempting a database restore"
|
336
|
+
ManageIQ::ApplianceConsole.logger.error(message)
|
337
|
+
raise message
|
338
|
+
end
|
339
|
+
|
340
|
+
disable_replication(dbname)
|
341
|
+
|
342
|
+
conn_count = connection_count(backup_type, dbname)
|
343
|
+
if conn_count > 1
|
344
|
+
message = "Database restore failed. #{conn_count - 1} connections remain to the database."
|
345
|
+
ManageIQ::ApplianceConsole.logger.error(message)
|
346
|
+
raise message
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
private_class_method def self.application_connections?
|
351
|
+
result = [{"count" => 0}]
|
352
|
+
|
353
|
+
with_pg_connection do |conn|
|
354
|
+
result = conn.exec("SELECT COUNT(pid) FROM pg_stat_activity WHERE application_name LIKE '%MIQ%'")
|
355
|
+
end
|
356
|
+
|
357
|
+
result[0]["count"].to_i > 0
|
358
|
+
end
|
359
|
+
|
360
|
+
private_class_method def self.disable_replication(dbname)
|
361
|
+
require 'pg/logical_replication'
|
362
|
+
|
363
|
+
with_pg_connection do |conn|
|
364
|
+
pglogical = PG::LogicalReplication::Client.new(conn)
|
365
|
+
|
366
|
+
if pglogical.subscriber?
|
367
|
+
pglogical.subcriptions(dbname).each do |subscriber|
|
368
|
+
sub_id = subscriber["subscription_name"]
|
369
|
+
begin
|
370
|
+
pglogical.drop_subscription(sub_id, true)
|
371
|
+
rescue PG::InternalError => e
|
372
|
+
raise unless e.message.include?("could not connect to publisher")
|
373
|
+
raise unless e.message.match?(/replication slot .* does not exist/)
|
374
|
+
|
375
|
+
pglogical.disable_subscription(sub_id).check
|
376
|
+
pglogical.alter_subscription_options(sub_id, "slot_name" => "NONE")
|
377
|
+
pglogical.drop_subscription(sub_id, true)
|
378
|
+
end
|
379
|
+
end
|
380
|
+
elsif pglogical.publishes?('miq')
|
381
|
+
pglogical.drop_publication('miq')
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
private_class_method def self.connection_count(backup_type, dbname)
|
387
|
+
result = nil
|
388
|
+
|
389
|
+
with_pg_connection do |conn|
|
390
|
+
query = "SELECT COUNT(pid) FROM pg_stat_activity"
|
391
|
+
query << " WHERE backend_type = 'client backend'" if backup_type == :basebackup
|
392
|
+
query << " WHERE datname = '#{dbname}'" if backup_type == :pgdump
|
393
|
+
result = conn.exec(query)
|
394
|
+
end
|
395
|
+
|
396
|
+
result[0]["count"].to_i
|
397
|
+
end
|
398
|
+
|
399
|
+
private_class_method def self.validate_backup_file_type(file)
|
400
|
+
if base_backup_file?(file)
|
401
|
+
:basebackup
|
402
|
+
elsif pg_dump_file?(file)
|
403
|
+
:pgdump
|
404
|
+
else
|
405
|
+
message = "#{filename} is not in a recognized database backup format"
|
406
|
+
ManageIQ::ApplianceConsole.error(message)
|
407
|
+
raise message
|
408
|
+
end
|
409
|
+
end
|
323
410
|
end
|
324
411
|
end
|
325
412
|
end
|
@@ -16,9 +16,24 @@ module ApplianceConsole
|
|
16
16
|
result
|
17
17
|
end
|
18
18
|
|
19
|
+
def self.rake_run!(task, params)
|
20
|
+
result = rake_run(task, params)
|
21
|
+
if result.failure?
|
22
|
+
parsed_errors = result.error.split("\n").select { |line| line.match?(/^error: /i) }.join(', ')
|
23
|
+
raise parsed_errors
|
24
|
+
end
|
25
|
+
|
26
|
+
result
|
27
|
+
end
|
28
|
+
|
19
29
|
def self.db_connections
|
30
|
+
code = [
|
31
|
+
"database ||= ActiveRecord::Base.configurations[Rails.env]['database']",
|
32
|
+
"conn = ActiveRecord::Base.connection",
|
33
|
+
"exit conn.client_connections.count { |c| c['database'] == database }"
|
34
|
+
]
|
20
35
|
result = AwesomeSpawn.run("bin/rails runner",
|
21
|
-
:params => ["
|
36
|
+
:params => [code.join("; ")],
|
22
37
|
:chdir => ManageIQ::ApplianceConsole::RAILS_ROOT
|
23
38
|
)
|
24
39
|
Integer(result.exit_status)
|
data/locales/appliance/en.yml
CHANGED
@@ -39,22 +39,6 @@ en:
|
|
39
39
|
summary: Summary Information
|
40
40
|
quit: Quit
|
41
41
|
database_admin:
|
42
|
-
menu_order:
|
43
|
-
- local
|
44
|
-
- nfs
|
45
|
-
- smb
|
46
|
-
- s3
|
47
|
-
- ftp
|
48
|
-
- swift
|
49
42
|
local: Local file
|
50
|
-
nfs: Network File System (NFS)
|
51
|
-
smb: Samba (SMB)
|
52
|
-
s3: Amazon S3 (S3)
|
53
|
-
ftp: File Transfer Protocol (FTP)
|
54
|
-
swift: OpenStack Swift (Swift)
|
55
43
|
sample_url:
|
56
44
|
nfs: nfs://host.mydomain.com/exported/my_exported_folder/db.backup
|
57
|
-
smb: smb://host.mydomain.com/my_share/daily_backup/db.backup
|
58
|
-
s3: s3://mybucket/my_subdirectory/daily_backup/db.backup
|
59
|
-
ftp: ftp://host.mydomain.com/path/to/daily_backup/db.backup
|
60
|
-
swift: swift://host.mydomain.com/path/to/daily_backup/db.backup
|
@@ -20,18 +20,19 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_runtime_dependency "activerecord", "~> 6.0.
|
24
|
-
spec.add_runtime_dependency "activesupport", "~> 6.0.
|
23
|
+
spec.add_runtime_dependency "activerecord", "~> 6.0.4", ">= 6.0.4.1"
|
24
|
+
spec.add_runtime_dependency "activesupport", "~> 6.0.4", ">= 6.0.4.1"
|
25
25
|
spec.add_runtime_dependency "awesome_spawn", "~> 1.4"
|
26
26
|
spec.add_runtime_dependency "bcrypt", "~> 3.1.10"
|
27
27
|
spec.add_runtime_dependency "bcrypt_pbkdf", ">= 1.0", "< 2.0"
|
28
28
|
spec.add_runtime_dependency "highline", "~> 1.6.21"
|
29
29
|
spec.add_runtime_dependency "i18n", "~> 0.8"
|
30
30
|
spec.add_runtime_dependency "linux_admin", "~> 2.0"
|
31
|
-
spec.add_runtime_dependency "manageiq-password", "
|
31
|
+
spec.add_runtime_dependency "manageiq-password", "< 2"
|
32
32
|
spec.add_runtime_dependency "net-scp", "~> 1.2.1"
|
33
33
|
spec.add_runtime_dependency "optimist", "~> 3.0"
|
34
34
|
spec.add_runtime_dependency "pg"
|
35
|
+
spec.add_runtime_dependency "pg-logical_replication"
|
35
36
|
spec.add_runtime_dependency "rbnacl", ">= 3.2", "< 5.0"
|
36
37
|
|
37
38
|
spec.add_development_dependency "bundler"
|
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:
|
4
|
+
version: 7.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ManageIQ Developers
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03
|
11
|
+
date: 2021-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,28 +16,40 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0.
|
19
|
+
version: 6.0.4
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 6.0.4.1
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - "~>"
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.0.
|
29
|
+
version: 6.0.4
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 6.0.4.1
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: activesupport
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
37
|
- - "~>"
|
32
38
|
- !ruby/object:Gem::Version
|
33
|
-
version: 6.0.
|
39
|
+
version: 6.0.4
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 6.0.4.1
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
38
47
|
- - "~>"
|
39
48
|
- !ruby/object:Gem::Version
|
40
|
-
version: 6.0.
|
49
|
+
version: 6.0.4
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 6.0.4.1
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: awesome_spawn
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,16 +144,16 @@ dependencies:
|
|
132
144
|
name: manageiq-password
|
133
145
|
requirement: !ruby/object:Gem::Requirement
|
134
146
|
requirements:
|
135
|
-
- - "
|
147
|
+
- - "<"
|
136
148
|
- !ruby/object:Gem::Version
|
137
|
-
version: '
|
149
|
+
version: '2'
|
138
150
|
type: :runtime
|
139
151
|
prerelease: false
|
140
152
|
version_requirements: !ruby/object:Gem::Requirement
|
141
153
|
requirements:
|
142
|
-
- - "
|
154
|
+
- - "<"
|
143
155
|
- !ruby/object:Gem::Version
|
144
|
-
version: '
|
156
|
+
version: '2'
|
145
157
|
- !ruby/object:Gem::Dependency
|
146
158
|
name: net-scp
|
147
159
|
requirement: !ruby/object:Gem::Requirement
|
@@ -184,6 +196,20 @@ dependencies:
|
|
184
196
|
- - ">="
|
185
197
|
- !ruby/object:Gem::Version
|
186
198
|
version: '0'
|
199
|
+
- !ruby/object:Gem::Dependency
|
200
|
+
name: pg-logical_replication
|
201
|
+
requirement: !ruby/object:Gem::Requirement
|
202
|
+
requirements:
|
203
|
+
- - ">="
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
type: :runtime
|
207
|
+
prerelease: false
|
208
|
+
version_requirements: !ruby/object:Gem::Requirement
|
209
|
+
requirements:
|
210
|
+
- - ">="
|
211
|
+
- !ruby/object:Gem::Version
|
212
|
+
version: '0'
|
187
213
|
- !ruby/object:Gem::Dependency
|
188
214
|
name: rbnacl
|
189
215
|
requirement: !ruby/object:Gem::Requirement
|
@@ -303,7 +329,7 @@ dependencies:
|
|
303
329
|
- !ruby/object:Gem::Version
|
304
330
|
version: '0'
|
305
331
|
description: ManageIQ Appliance Console
|
306
|
-
email:
|
332
|
+
email:
|
307
333
|
executables:
|
308
334
|
- appliance_console
|
309
335
|
- appliance_console_cli
|
@@ -347,6 +373,7 @@ files:
|
|
347
373
|
- lib/manageiq/appliance_console/logger.rb
|
348
374
|
- lib/manageiq/appliance_console/logging.rb
|
349
375
|
- lib/manageiq/appliance_console/logical_volume_management.rb
|
376
|
+
- lib/manageiq/appliance_console/manageiq_user_mixin.rb
|
350
377
|
- lib/manageiq/appliance_console/message_configuration.rb
|
351
378
|
- lib/manageiq/appliance_console/message_configuration_client.rb
|
352
379
|
- lib/manageiq/appliance_console/message_configuration_server.rb
|
@@ -367,7 +394,7 @@ homepage: https://github.com/ManageIQ/manageiq-appliance_console
|
|
367
394
|
licenses:
|
368
395
|
- Apache-2.0
|
369
396
|
metadata: {}
|
370
|
-
post_install_message:
|
397
|
+
post_install_message:
|
371
398
|
rdoc_options: []
|
372
399
|
require_paths:
|
373
400
|
- lib
|
@@ -382,8 +409,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
382
409
|
- !ruby/object:Gem::Version
|
383
410
|
version: '0'
|
384
411
|
requirements: []
|
385
|
-
rubygems_version: 3.
|
386
|
-
signing_key:
|
412
|
+
rubygems_version: 3.1.6
|
413
|
+
signing_key:
|
387
414
|
specification_version: 4
|
388
415
|
summary: ManageIQ Appliance Console
|
389
416
|
test_files: []
|