Class: ManageIQ::ApplianceConsole::DatabaseAdmin

Inherits:
HighLine
  • Object
show all
Includes:
Prompts
Defined in:
lib/manageiq/appliance_console/database_admin.rb

Constant Summary collapse

DB_RESTORE_FILE =
"/tmp/evm_db.backup".freeze
DB_DEFAULT_DUMP_FILE =
"/tmp/evm_db.dump".freeze
LOCAL_FILE_VALIDATOR =
->(a) { File.exist?(a) }.freeze
USER_PROMPT =
<<-PROMPT.strip_heredoc.chomp
  username with access to this file.
  Example: 'mydomain.com/user'
PROMPT
DB_DUMP_WARNING =
<<-WARN.strip_heredoc
  WARNING:  This is not the recommended and supported way of running a
  database backup, and is strictly meant for exporting a database for
  support/debugging purposes!


WARN

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::NONE_REGEXP

Instance Attribute 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_ip_or_none, #ask_for_ipv4, #ask_for_ipv4_or_none, #ask_for_ipv6, #ask_for_ipv6_or_none, #ask_for_many, #ask_for_month_day_number, #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

Constructor Details

#initialize(action = :restore, input = $stdin, output = $stdout) ⇒ DatabaseAdmin

Returns a new instance of DatabaseAdmin.



29
30
31
32
33
34
# File 'lib/manageiq/appliance_console/database_admin.rb', line 29

def initialize(action = :restore, input = $stdin, output = $stdout)
  super(input, output)

  @action      = action
  @task_params = []
end

Instance Attribute Details

#actionObject (readonly)

Returns the value of attribute action.



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

def action
  @action
end

#backup_typeObject (readonly)

Returns the value of attribute backup_type.



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

def backup_type
  @backup_type
end

#delete_agreeObject (readonly)

Returns the value of attribute delete_agree.



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

def delete_agree
  @delete_agree
end

#filenameObject (readonly)

Returns the value of attribute filename.



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

def filename
  @filename
end

#taskObject (readonly)

Returns the value of attribute task.



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

def task
  @task
end

#task_paramsObject (readonly)

Returns the value of attribute task_params.



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

def task_params
  @task_params
end

#uriObject

Returns the value of attribute uri.



26
27
28
# File 'lib/manageiq/appliance_console/database_admin.rb', line 26

def uri
  @uri
end

Instance Method Details

#activateObject



57
58
59
60
61
62
63
# File 'lib/manageiq/appliance_console/database_admin.rb', line 57

def activate
  clear_screen
  setting_header

  ask_to_delete_backup_after_restore
  confirm_and_execute
end

#allowed_to_execute?Boolean

Returns:

  • (Boolean)


243
244
245
246
247
248
# File 'lib/manageiq/appliance_console/database_admin.rb', line 243

def allowed_to_execute?
  return true unless action == :restore

  say("\nNote: A database restore cannot be undone.  The restore will use the file: #{uri}.\n")
  agree("Are you sure you would like to restore the database? (Y/N): ")
end

#api_version_menu_argsObject



262
263
264
265
266
267
268
269
# File 'lib/manageiq/appliance_console/database_admin.rb', line 262

def api_version_menu_args
  [
    "OpenStack API Version",
    [["Keystone v2".freeze, "v2".freeze], ["Keystone v3".freeze, "v3".freeze], ["None".freeze, nil]].freeze,
    ["Keystone v2".freeze, "v2".freeze],
    nil
  ]
end

#ask_custom_file_options(server_uri) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/manageiq/appliance_console/database_admin.rb', line 150

def ask_custom_file_options(server_uri)
  hostname  = URI(server_uri).host
  @filename = ask_custom_file_prompt(hostname)
  @uri      = server_uri

  params = {:uri => uri, :remote_file_name => filename}

  if (custom_params = custom_endpoint_config_for(hostname))
    params.merge!(custom_params[:rake_options]) if custom_params[:rake_options]
  end

  @task        = "evm:db:#{action}:remote"
  @task_params = ["--", params]
end

#ask_file_locationObject



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

def ask_file_location
  @backup_type = ask_with_menu(*file_menu_args) do |menu|
    menu.choice(CANCEL) { |_| raise MiqSignalError }
  end
  if URI(backup_type).scheme
    ask_custom_file_options(backup_type)
  else
    # calling methods like ask_ftp_file_options and ask_s3_file_options
    send("ask_#{backup_type}_file_options")
  end
end

#ask_for_tables_to_exclude_in_dumpObject



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/manageiq/appliance_console/database_admin.rb', line 209

def ask_for_tables_to_exclude_in_dump
  if action == :dump && should_exclude_tables?
    say(<<-PROMPT.strip_heredoc)

      To exclude tables from the dump, enter them in a space separated
      list.  For example:

          > metrics_* vim_performance_states event_streams

    PROMPT
    table_excludes = ask_for_many("table",
                                  "tables to exclude",
                                  "metrics_* vim_performance_states event_streams",
                                  255,
                                  Float::INFINITY)

    @task_params.last[:"exclude-table-data"] = table_excludes
  end || true
end

#ask_ftp_file_optionsObject



135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/manageiq/appliance_console/database_admin.rb', line 135

def ask_ftp_file_options
  @filename    = just_ask(*filename_prompt_args) unless action == :restore
  @uri         = ask_for_uri(*remote_file_prompt_args_for("ftp"), :optional_path => true)
  user         = just_ask(USER_PROMPT)
  pass         = ask_for_password("password for #{user}")

  params = { :uri => uri }
  params[:uri_username]     = user     if user.present?
  params[:uri_password]     = pass     if pass.present?
  params[:remote_file_name] = filename if filename

  @task        = "evm:db:#{action}:remote"
  @task_params = ["--", params]
end

#ask_local_file_optionsObject



77
78
79
80
81
# File 'lib/manageiq/appliance_console/database_admin.rb', line 77

def ask_local_file_options
  @uri         = just_ask(*filename_prompt_args)
  @task        = "evm:db:#{action}:local"
  @task_params = ["--", {:local_file => uri}]
end

#ask_nfs_file_optionsObject



83
84
85
86
87
88
89
90
91
92
# File 'lib/manageiq/appliance_console/database_admin.rb', line 83

def ask_nfs_file_options
  @filename    = just_ask(*filename_prompt_args) unless action == :restore
  @uri         = ask_for_uri(*remote_file_prompt_args_for("nfs"))
  @task        = "evm:db:#{action}:remote"

  params = {:uri => uri}
  params[:remote_file_name] = filename if filename

  @task_params = ["--", params]
end

#ask_questionsObject



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/manageiq/appliance_console/database_admin.rb', line 44

def ask_questions
  setting_header
  if action == :restore && LinuxAdmin::Service.new("evmserverd").running?
    say("\nDatabase restore failed. Please execute the \“Stop EVM Server Processes\” command and try again.")
    press_any_key
    raise MiqSignalError
  end
  say(DB_DUMP_WARNING) if action == :dump
  ask_file_location
  ask_for_tables_to_exclude_in_dump
  ask_to_split_up_output
end

#ask_s3_file_optionsObject



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/manageiq/appliance_console/database_admin.rb', line 111

def ask_s3_file_options
  access_key_prompt = <<-PROMPT.strip_heredoc.chomp
    Access Key ID with access to this file.
    Example: 'amazon_aws_user'
  PROMPT

  @filename    = just_ask(*filename_prompt_args) unless action == :restore
  @uri         = ask_for_uri(*remote_file_prompt_args_for("s3"), :optional_path => true)
  region       = just_ask("Amazon Region for database file", "us-east-1")
  user         = just_ask(access_key_prompt)
  pass         = ask_for_password("Secret Access Key for #{user}")

  params = {
    :uri          => uri,
    :uri_username => user,
    :uri_password => pass,
    :aws_region   => region
  }
  params[:remote_file_name] = filename if filename

  @task        = "evm:db:#{action}:remote"
  @task_params = ["--", params]
end

#ask_smb_file_optionsObject



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/manageiq/appliance_console/database_admin.rb', line 94

def ask_smb_file_options
  @filename    = just_ask(*filename_prompt_args) unless action == :restore
  @uri         = ask_for_uri(*remote_file_prompt_args_for("smb"))
  user         = just_ask(USER_PROMPT)
  pass         = ask_for_password("password for #{user}")

  params = {
    :uri          => uri,
    :uri_username => user,
    :uri_password => pass
  }
  params[:remote_file_name] = filename if filename

  @task        = "evm:db:#{action}:remote"
  @task_params = ["--", params]
end

#ask_swift_file_optionsObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/manageiq/appliance_console/database_admin.rb', line 165

def ask_swift_file_options
  require 'uri'
  swift_user_prompt = <<-PROMPT.strip_heredoc.chomp
    User Name with access to this file.
    Example: 'openstack_user'
  PROMPT

  @filename  = just_ask(*filename_prompt_args) { |q| q.readline = false } unless action == :restore
  @uri       = URI(ask_for_uri(*remote_file_prompt_args_for("swift")) { |q| q.readline = false })
  @task      = "evm:db:#{action}:remote"
  user       = just_ask(swift_user_prompt) { |q| q.readline = false }
  pass       = ask_for_password("password for #{user}") { |q| q.readline = false }
  @uri.query = swift_query_elements.join('&').presence

  params = {
    :uri          => @uri.to_s,
    :uri_username => user,
    :uri_password => pass
  }
  params[:remote_file_name] = filename if filename
  @task        = "evm:db:#{action}:remote"
  @task_params = ["--", params]
end

#ask_to_delete_backup_after_restoreObject



202
203
204
205
206
207
# File 'lib/manageiq/appliance_console/database_admin.rb', line 202

def ask_to_delete_backup_after_restore
  if action == :restore && local_backup?
    say("The local database restore file is located at: '#{uri}'.\n")
    @delete_agree = agree("Should this file be deleted after completing the restore? (Y/N): ")
  end
end

#ask_to_split_up_outputObject



229
230
231
232
233
# File 'lib/manageiq/appliance_console/database_admin.rb', line 229

def ask_to_split_up_output
  if action == :dump && should_split_output?
    @task_params.last[:byte_count] = ask_for_string("byte size to split by", "500M")
  end || true
end

#confirm_and_executeObject



235
236
237
238
239
240
241
# File 'lib/manageiq/appliance_console/database_admin.rb', line 235

def confirm_and_execute
  if allowed_to_execute?
    processing_message
    run_rake
  end
  press_any_key
end

#file_menu_argsObject



271
272
273
274
275
276
277
278
# File 'lib/manageiq/appliance_console/database_admin.rb', line 271

def file_menu_args
  [
    action == :restore ? "Restore Database File Source" : "#{action.capitalize} Output File Destination",
    file_options,
    "local",
    nil
  ]
end

#file_optionsObject



250
251
252
253
254
255
256
257
258
259
260
# File 'lib/manageiq/appliance_console/database_admin.rb', line 250

def file_options
  @file_options ||= I18n.t("database_admin.menu_order").each_with_object({}) do |file_option, h|
    # special anonymous ftp sites are defined by uri
    uri = URI(file_option)
    if uri.scheme
      h["#{uri.scheme} to #{uri.host}"] = file_option unless skip_file_location?(uri.host)
    else
      h[I18n.t("database_admin.#{file_option}")] = file_option
    end
  end
end

#local_backup?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/manageiq/appliance_console/database_admin.rb', line 36

def local_backup?
  backup_type == "local".freeze
end

#object_store_backup?Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/manageiq/appliance_console/database_admin.rb', line 40

def object_store_backup?
  backup_type == "s3".freeze || backup_type == "swift".freeze
end

#security_protocol_menu_argsObject



280
281
282
283
284
285
286
287
# File 'lib/manageiq/appliance_console/database_admin.rb', line 280

def security_protocol_menu_args
  [
    "OpenStack Security Protocol",
    [["SSL without validation".freeze, "ssl".freeze], ["SSL".freeze, "ssl-with-validation".freeze], ["Non-SSL".freeze, "non-ssl".freeze], ["None".freeze, nil]].freeze,
    ["Non-SSL".freeze, "non-ssl".freeze],
    nil
  ]
end

#setting_headerObject



289
290
291
# File 'lib/manageiq/appliance_console/database_admin.rb', line 289

def setting_header
  say("#{I18n.t("advanced_settings.db#{action}")}\n\n")
end

#swift_query_elementsObject



189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/manageiq/appliance_console/database_admin.rb', line 189

def swift_query_elements
  region            = just_ask("OpenStack Swift Region") { |q| q.readline = false }
  @uri.port         = just_ask("OpenStack Swift Port", "5000") { |q| q.readline = false }
  security_protocol = ask_with_menu(*security_protocol_menu_args)
  api_version       = ask_with_menu(*api_version_menu_args) { |q| q.readline = false }
  domain_ident      = just_ask("OpenStack V3 Domain Identifier") { |q| q.readline = false } if api_version == "v3"
  query_elements    = []
  query_elements    << "region=#{region}"                       if region.present?
  query_elements    << "api_version=#{api_version}"             if api_version.present?
  query_elements    << "domain_id=#{domain_ident}"              if domain_ident.present?
  query_elements    << "security_protocol=#{security_protocol}" if security_protocol.present?
end