Class: ManageIQ::ApplianceConsole::DatabaseConfiguration

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

Defined Under Namespace

Classes: ModelWithNoBackingTable

Constant Summary collapse

DB_YML =
ManageIQ::ApplianceConsole::RAILS_ROOT.join("config/database.yml")
DB_YML_TMPL =
ManageIQ::ApplianceConsole::RAILS_ROOT.join("config/database.pg.yml")
CREATE_REGION_AGREE =
"WARNING: Creating a database region will destroy any existing data and cannot be undone.\n\nAre you sure you want to continue? (Y/N):".freeze
FAILED_WITH_ERROR_HYPHEN =
"failed with error -".freeze
REGION_RANGE =

PG 9.2 bigint max 9223372036854775807 / ArRegion::DEFAULT_RAILS_SEQUENCE_FACTOR = 9223372 www.postgresql.org/docs/9.2/static/datatype-numeric.html 9223372 won’t be a full region though, so we’re not including it. TODO: This information should be shared outside of appliance console code and MiqRegion.

0..9223371
DEFAULT_PORT =
5432

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

#error_and_logging_from_command_result_error, #error_and_logging_from_standard_error, #interactive, #interactive=, interactive?, #interactive?, #log_and_feedback, #log_and_feedback_exception, #log_and_feedback_info, #log_error, #log_prefix, #logger, #logger=, #say_error, #say_info

Methods included from ManageiqUserMixin

#manageiq_gid, #manageiq_uid

Constructor Details

#initialize(hash = {}) ⇒ DatabaseConfiguration

Returns a new instance of DatabaseConfiguration.



36
37
38
39
40
41
42
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 36

def initialize(hash = {})
  initialize_from_hash(hash)
  @adapter ||= "postgresql"
  # introduced by Logging
  self.interactive = true unless hash.key?(:interactive)
  self.run_as_evm_server = true unless hash.key?(:run_as_evm_server)
end

Instance Attribute Details

#adapterObject

Returns the value of attribute adapter.



15
16
17
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 15

def adapter
  @adapter
end

#databaseObject

Returns the value of attribute database.



15
16
17
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 15

def database
  @database
end

#hostObject

Returns the value of attribute host.



15
16
17
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 15

def host
  @host
end

#passwordObject

Returns the value of attribute password.



16
17
18
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 16

def password
  @password
end

#portObject

Returns the value of attribute port.



15
16
17
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 15

def port
  @port
end

#regionObject

Returns the value of attribute region.



15
16
17
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 15

def region
  @region
end

#run_as_evm_serverObject

Returns the value of attribute run_as_evm_server.



15
16
17
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 15

def run_as_evm_server
  @run_as_evm_server
end

#usernameObject

Returns the value of attribute username.



15
16
17
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 15

def username
  @username
end

Class Method Details

.currentObject



202
203
204
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 202

def self.current
  decrypt_password(load_current)
end

.database_hostObject



210
211
212
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 210

def self.database_host
  database_yml_configured? ? current[rails_env]['host'] || "localhost" : nil
end

.database_nameObject



214
215
216
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 214

def self.database_name
  database_yml_configured? ? current[rails_env]['database'] : nil
end

.database_yml_configured?Boolean

Returns:

  • (Boolean)


206
207
208
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 206

def self.database_yml_configured?
  File.exist?(DB_YML) && File.exist?(KEY_FILE)
end

.decrypt_password(settings) ⇒ Object



198
199
200
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 198

def self.decrypt_password(settings)
  encrypt_decrypt_password(settings) { |pass| ManageIQ::Password.try_decrypt(pass) }
end

.encrypt_password(settings) ⇒ Object



194
195
196
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 194

def self.encrypt_password(settings)
  encrypt_decrypt_password(settings) { |pass| ManageIQ::Password.try_encrypt(pass) }
end

.regionObject



218
219
220
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 218

def self.region
  database_yml_configured? ? ManageIQ::ApplianceConsole::Utilities.db_region : nil
end

Instance Method Details

#activateObject



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 67

def activate
  return false unless validated

  original = self.class.current
  success  = false

  begin
    save
    success = create_or_join_region
    validate_encryption_key!
  rescue
    success = false
  ensure
    save(original) unless success
  end
end

#ask_for_database_credentials(password_twice = true) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 119

def ask_for_database_credentials(password_twice = true)
  self.host     = ask_for_ip_or_hostname("database hostname or IP address", host) if host.blank? || !local?
  self.port     = ask_for_integer("port number", nil, port) unless local?
  self.database = just_ask("name of the database on #{host}", database) unless local?
  self.username = just_ask("username", username) unless local?
  count = 0
  loop do
    password1 = ask_for_password("database password on #{host}", password)
    # if they took the default, just bail
    break if (password1 == password)

    if password1.strip.length == 0
      say("\nPassword can not be empty, please try again")
      next
    end
    if password_twice
      password2 = ask_for_password("database password again")
      if password1 == password2
        self.password = password1
        break
      elsif count > 0 # only reprompt password once
        raise "passwords did not match"
      else
        count += 1
        say("\nThe passwords did not match, please try again")
      end
    else
      self.password = password1
      break
    end
  end
end

#create_new_region_questions(warn = true) ⇒ Object

Raises:



111
112
113
114
115
116
117
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 111

def create_new_region_questions(warn = true)
  clear_screen
  say("\n\nNote: Creating a new database region requires an empty database.") if warn
  say("Each database region number must be unique.\n")
  self.region = ask_for_integer("database region number", REGION_RANGE)
  raise MiqSignalError if warn && !agree(CREATE_REGION_AGREE)
end

#create_or_join_regionObject



84
85
86
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 84

def create_or_join_region
  region ? create_region : join_region
end

#create_regionObject



88
89
90
91
92
93
94
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 88

def create_region
  hint = "Please stop the EVM server process on all appliances in the region"
  ManageIQ::ApplianceConsole::Utilities.bail_if_db_connections("preventing the setup of a database region.\n#{hint}")
  log_and_feedback(__method__) do
    ManageIQ::ApplianceConsole::Utilities.rake("evm:db:region", {}, {'REGION' => region.to_s, 'VERBOSE' => 'false'})
  end
end

#friendly_inspectObject



152
153
154
155
156
157
158
159
160
161
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 152

def friendly_inspect
  output = <<-FRIENDLY
Host:     #{host}
Username: #{username}
Database: #{database}
FRIENDLY
  output << "Port:     #{port}\n" if port
  output << "Region:   #{region}\n" if region
  output
end

#join_regionObject



96
97
98
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 96

def join_region
  ManageIQ::ApplianceConsole::Utilities.rake("evm:join_region", {})
end

#local?Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 59

def local?
  host.blank? || host.in?(%w(localhost 127.0.0.1))
end

#merged_settingsObject

merge all the non specified setings for all the basic attributes, overwrite from this object (including blank values)



176
177
178
179
180
181
182
183
184
185
186
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 176

def merged_settings
  merged = self.class.current
  settings_hash.each do |k, v|
    if v.present?
      merged['production'][k] = v
    else
      merged['production'].delete(k)
    end
  end
  merged
end

#reset_regionObject



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

def reset_region
  say("Warning: RESETTING A DATABASE WILL DESTROY ANY EXISTING DATA AND CANNOT BE UNDONE.\n\n")
  raise MiqSignalError unless are_you_sure?("reset the configured database")

  create_new_region_questions(false)
  ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"] = "1"
  create_region
ensure
  ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"] = nil
end

#run_interactiveObject



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

def run_interactive
  ask_questions

  clear_screen
  say "Activating the configuration using the following settings...\n#{friendly_inspect}\n"

  raise MiqSignalError unless activate

  say("\nConfiguration activated successfully.\n")
rescue RuntimeError => e
  puts "Configuration failed#{": " + e.message unless e.class == MiqSignalError}"
  press_any_key
  raise MiqSignalError
end

#save(settings = nil) ⇒ Object



188
189
190
191
192
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 188

def save(settings = nil)
  settings ||= merged_settings
  settings = self.class.encrypt_password(settings)
  do_save(settings)
end

#settings_hashObject



163
164
165
166
167
168
169
170
171
172
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 163

def settings_hash
  {
    'adapter'  => 'postgresql',
    'host'     => local? ? "localhost" : host,
    'port'     => port,
    'username' => username,
    'password' => password.presence,
    'database' => database
  }
end

#validate!Object



230
231
232
233
234
235
236
237
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 230

def validate!
  pool = ModelWithNoBackingTable.establish_connection(settings_hash.delete_if { |_n, v| v.blank? })
  begin
    pool.connection
  ensure
    ModelWithNoBackingTable.remove_connection
  end
end

#validatedObject



222
223
224
225
226
227
228
# File 'lib/manageiq/appliance_console/database_configuration.rb', line 222

def validated
  !!validate!
rescue => err
  log_error(__method__, err.message)
  say_error(__method__, err.message)
  false
end