manageiq-postgres_ha_admin 2.0.0 → 3.1.2

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
- SHA1:
3
- metadata.gz: 2ea7e89193add948ecd827491eae6c7e055c20a6
4
- data.tar.gz: d416a3b5fd696ca582e13e360b6ea00af762aa58
2
+ SHA256:
3
+ metadata.gz: 4bbec7e79b7ae7140dadbeb59bd561ef7469f8568a9c1d5b8a78d2464b50d57d
4
+ data.tar.gz: 4f04ad4bb6a91887e77e5b85247510294a18ef8083c1883d5be0ff7ae21898ca
5
5
  SHA512:
6
- metadata.gz: a76ffe81cb4c0f218a5374a333f2458da83c59ff14cbc285ba9787c58e4362568c7c0303d794f587098ae3aa4b6fe144fc44c6ef1270e990e1581e5c83521394
7
- data.tar.gz: 2aaeb1824891fad95440f473ccd864a048538ddcdf37832a9d3b8c492d29d81e1a1d353ee070aca4861136a5cea8a2152bd26bf90c94c989df29e2f1bd97e088
6
+ metadata.gz: b6767d711af5f8b2b219e9924c8293f89c29f4b03770151f100e6a390f92eafc9be1630c43aa7149414fdec3b5ef6c6d6c12983b6a7d78c5d774ce0a8b870db5
7
+ data.tar.gz: e6e63fa21d95062f54fcbb9dde5efa942ca46f0627a0d243076d4f2a7bd034029610ff722e1cf8bd04dae897ae314e2e04a0112d255392ffd3e9447f073e674a
@@ -34,6 +34,7 @@ engines:
34
34
  rubocop:
35
35
  enabled: true
36
36
  config: '.rubocop_cc.yml'
37
+ channel: 'rubocop-0-69'
37
38
  prepare:
38
39
  fetch:
39
40
  - url: "https://raw.githubusercontent.com/ManageIQ/guides/master/.rubocop_base.yml"
@@ -2,7 +2,6 @@ language: ruby
2
2
  rvm:
3
3
  - '2.3.1'
4
4
  - '2.4.2'
5
- sudo: false
6
5
  cache: bundler
7
6
  env:
8
7
  global:
@@ -10,5 +9,5 @@ env:
10
9
  - RUBY_GC_HEAP_INIT_SLOTS=600000
11
10
  - RUBY_GC_HEAP_GROWTH_FACTOR=1.25
12
11
  addons:
13
- postgresql: '9.5'
12
+ postgresql: '10'
14
13
  after_script: bundle exec codeclimate-test-reporter
@@ -3,7 +3,31 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
- ## [Unreleased]
6
+ ## [3.1.2] - 2020-12-21
7
+ - Allow for Rails 6.0 [#23](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/23)
8
+
9
+ ## [3.1.1] - 2019-12-12
10
+ - Remove the dependency on linux_admin [#19](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/19)
11
+
12
+ ## [3.1.0] - 2019-05-09
13
+
14
+ ### Added
15
+ - Add a logical replication config handler [#17](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/17)
16
+
17
+ ## [3.0.1] - 2019-03-19
18
+
19
+ ### Changed
20
+ - Remove references to MiqPassword [#15](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/15)
21
+
22
+ ## [3.0.0] - 2018-09-05
23
+
24
+ ### Added
25
+ - Allow users of the gem to specify a logger object [#7](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/7)
26
+
27
+ ### Changed
28
+ - Make sources of database connection info pluggable [#8](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/8)
29
+ - Improve FailoverDatabases/ServerStore class [#9](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/9)
30
+ - Make failover monitor generic [#10](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/10)
7
31
 
8
32
  ## [2.0.0] - 2018-08-01
9
33
 
@@ -14,5 +38,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
14
38
  ### Changed
15
39
  - Make changes for upgrading repmgr to version 4 [#4](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/4)
16
40
 
17
- [Unreleased]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v2.0.0...master
41
+ [Unreleased]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.1.2...master
42
+ [3.1.2]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.1.1...v3.1.2
43
+ [3.1.1]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.1.0...v3.1.1
44
+ [3.1.0]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.0.1...v3.1.0
45
+ [3.0.1]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.0.0...v3.0.1
46
+ [3.0.0]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v2.0.0...v3.0.0
18
47
  [2.0.0]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v1.0.0...v2.0.0
@@ -0,0 +1 @@
1
+ * @carbonin
data/Gemfile CHANGED
@@ -1,7 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in manageiq-smartstate.gemspec
3
+ # Specify your gem's dependencies in manageiq-postgres_ha_admin.gemspec
4
4
  gemspec
5
-
6
- # For MiqPassword
7
- gem "manageiq-gems-pending", :git => "https://github.com/ManageIQ/manageiq-gems-pending", :branch => "master"
data/README.md CHANGED
@@ -4,7 +4,6 @@
4
4
  [![Build Status](https://travis-ci.org/ManageIQ/manageiq-postgres_ha_admin.svg)](https://travis-ci.org/ManageIQ/manageiq-postgres_ha_admin)
5
5
  [![Code Climate](https://codeclimate.com/github/ManageIQ/manageiq-postgres_ha_admin.svg)](https://codeclimate.com/github/ManageIQ/manageiq-postgres_ha_admin)
6
6
  [![Test Coverage](https://codeclimate.com/github/ManageIQ/manageiq-postgres_ha_admin/badges/coverage.svg)](https://codeclimate.com/github/ManageIQ/manageiq-postgres_ha_admin/coverage)
7
- [![Dependency Status](https://gemnasium.com/ManageIQ/manageiq-postgres_ha_admin.svg)](https://gemnasium.com/ManageIQ/manageiq-postgres_ha_admin)
8
7
  [![Security](https://hakiri.io/github/ManageIQ/manageiq-postgres_ha_admin/master.svg)](https://hakiri.io/github/ManageIQ/manageiq-postgres_ha_admin/master)
9
8
 
10
9
  [![Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ManageIQ/manageiq-postgres_ha_admin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -1,4 +1,24 @@
1
1
  require 'manageiq/postgres_ha_admin/version'
2
- require 'manageiq/postgres_ha_admin/database_yml'
3
- require 'manageiq/postgres_ha_admin/failover_databases'
2
+
3
+ require 'manageiq/postgres_ha_admin/logging'
4
+ require 'manageiq/postgres_ha_admin/null_logger'
5
+
6
+ require 'manageiq/postgres_ha_admin/server_store'
4
7
  require 'manageiq/postgres_ha_admin/failover_monitor'
8
+
9
+ require 'manageiq/postgres_ha_admin/config_handler'
10
+ require 'manageiq/postgres_ha_admin/config_handler/rails_config_handler'
11
+ require 'manageiq/postgres_ha_admin/config_handler/pglogical_config_handler'
12
+ require 'manageiq/postgres_ha_admin/config_handler/logical_replication_config_handler'
13
+
14
+ module ManageIQ
15
+ module PostgresHaAdmin
16
+ class << self
17
+ attr_writer :logger
18
+ end
19
+
20
+ def self.logger
21
+ @logger ||= NullLogger.new
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ module ManageIQ
2
+ module PostgresHaAdmin
3
+ class ConfigHandler
4
+ def name
5
+ "Config Handler"
6
+ end
7
+
8
+ def read
9
+ raise NotImplementedError
10
+ end
11
+
12
+ def write(_conninfo)
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def before_failover(&block)
17
+ raise ArgumentError, "A block is required to set the before failover callback" unless block_given?
18
+ @before_failover_cb = block
19
+ end
20
+
21
+ def after_failover(&block)
22
+ raise ArgumentError, "A block is required to set the after failover callback" unless block_given?
23
+ @after_failover_cb = block
24
+ end
25
+
26
+ def do_before_failover
27
+ @before_failover_cb&.call
28
+ end
29
+
30
+ def do_after_failover(new_primary_conn_info)
31
+ @after_failover_cb&.call(new_primary_conn_info)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,34 @@
1
+ require 'pg'
2
+ require 'pg/dsn_parser'
3
+
4
+ module ManageIQ
5
+ module PostgresHaAdmin
6
+ class LogicalReplicationConfigHandler < ConfigHandler
7
+ attr_reader :subscription, :conn_info
8
+
9
+ def initialize(options = {})
10
+ @subscription = options[:subscription]
11
+ @conn_info = options[:conn_info]
12
+ end
13
+
14
+ def name
15
+ "Logical Replication subscription #{subscription} Config Handler"
16
+ end
17
+
18
+ def read
19
+ conn = PG::Connection.open(@conn_info)
20
+ dsn = conn.exec_params(<<~SQL, [@subscription]).first["subconninfo"]
21
+ SELECT subconninfo
22
+ FROM pg_subscription
23
+ WHERE subname = $1
24
+ SQL
25
+ PG::DSNParser.new.parse(dsn)
26
+ end
27
+
28
+ def write(_params)
29
+ # Nothing to do here as the expectation is that the user will
30
+ # remove and re-add the subscription in the after failover callback
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ require 'pg'
2
+ require 'pg/dsn_parser'
3
+
4
+ module ManageIQ
5
+ module PostgresHaAdmin
6
+ class PglogicalConfigHandler < ConfigHandler
7
+ attr_reader :subscription, :conn_info
8
+
9
+ def initialize(options = {})
10
+ @subscription = options[:subscription]
11
+ @conn_info = options[:conn_info]
12
+ end
13
+
14
+ def name
15
+ "pglogical subscription #{subscription} Config Handler"
16
+ end
17
+
18
+ def read
19
+ conn = PG::Connection.open(@conn_info)
20
+ dsn = conn.exec_params(<<~SQL, [@subscription]).first["if_dsn"]
21
+ SELECT if_dsn
22
+ FROM pglogical.subscription s
23
+ JOIN pglogical.node_interface i
24
+ ON s.sub_origin_if = i.if_id
25
+ WHERE s.sub_name = $1
26
+ SQL
27
+ PG::DSNParser.new.parse(dsn)
28
+ end
29
+
30
+ def write(_params)
31
+ # Nothing to do here as the expectation is that the user will
32
+ # remove and re-add the subscription in the after failover callback
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,32 +1,36 @@
1
1
  require 'active_support/all'
2
- require 'util/miq-password'
2
+ require 'manageiq-password'
3
3
  require 'fileutils'
4
4
 
5
5
  module ManageIQ
6
6
  module PostgresHaAdmin
7
- class DatabaseYml
8
- attr_reader :db_yml_file, :environment
7
+ class RailsConfigHandler < ConfigHandler
8
+ attr_reader :environment, :file_path
9
9
 
10
- def initialize(db_yml_file, environment)
11
- @db_yml_file = db_yml_file
12
- @environment = environment
10
+ def initialize(options = {})
11
+ @file_path = options[:file_path]
12
+ @environment = options[:environment]
13
13
  end
14
14
 
15
- def pg_params_from_database_yml
16
- rails_params_to_pg(YAML.load_file(db_yml_file)[environment])
15
+ def name
16
+ "Rails #{environment} Config Handler"
17
17
  end
18
18
 
19
- def update_database_yml(params)
20
- db_yml = YAML.load_file(db_yml_file)
19
+ def read
20
+ rails_params_to_pg(YAML.load_file(file_path)[environment])
21
+ end
22
+
23
+ def write(params)
24
+ db_yml = YAML.load_file(file_path)
21
25
  db_yml[environment].merge!(pg_parameters_to_rails(params))
22
26
  remove_empty(db_yml[environment])
23
27
 
24
- new_name = "#{db_yml_file}_#{Time.current.strftime("%d-%B-%Y_%H.%M.%S")}"
25
- FileUtils.copy(db_yml_file, new_name)
28
+ new_name = "#{file_path}_#{Time.current.strftime("%d-%B-%Y_%H.%M.%S")}"
29
+ FileUtils.copy(file_path, new_name)
26
30
  begin
27
- File.write(db_yml_file, db_yml.to_yaml)
31
+ File.write(file_path, db_yml.to_yaml)
28
32
  rescue
29
- FileUtils.mv(new_name, db_yml_file)
33
+ FileUtils.mv(new_name, file_path)
30
34
  raise
31
35
  end
32
36
  new_name
@@ -40,7 +44,7 @@ module PostgresHaAdmin
40
44
  pg_params[:user] = params['username']
41
45
  pg_params[:port] = params['port']
42
46
  pg_params[:host] = params['host']
43
- pg_params[:password] = MiqPassword.try_decrypt(params['password'])
47
+ pg_params[:password] = ManageIQ::Password.try_decrypt(params['password'])
44
48
  remove_empty(pg_params)
45
49
  end
46
50
 
@@ -1,52 +1,49 @@
1
1
  require 'active_support/all'
2
2
  require 'pg'
3
- require 'linux_admin'
4
3
 
5
4
  module ManageIQ
6
5
  module PostgresHaAdmin
7
6
  class FailoverMonitor
8
- RAILS_ROOT = [
9
- Pathname.new("/var/www/miq/vmdb"),
10
- Pathname.new(File.expand_path(File.join(__dir__, "../..")))
11
- ].detect { |f| File.exist?(f) }
7
+ include Logging
8
+
12
9
  FAILOVER_ATTEMPTS = 10
13
10
  DB_CHECK_FREQUENCY = 300
14
11
  FAILOVER_CHECK_FREQUENCY = 60
15
- LOG_FILE = '/var/www/miq/vmdb/log/ha_admin.log'.freeze
16
12
  attr_accessor :failover_attempts, :db_check_frequency, :failover_check_frequency
13
+ attr_reader :config_handlers
17
14
 
18
- def initialize(db_yml_file: '/var/www/miq/vmdb/config/database.yml',
19
- failover_yml_file: '/var/www/miq/vmdb/config/failover_databases.yml',
20
- ha_admin_yml_file: '/var/www/miq/vmdb/config/ha_admin.yml',
21
- logger: nil,
22
- environment: 'production')
23
- if logger.respond_to?(:error, :info)
24
- @logger = logger
25
- else
26
- @logger = Logger.new(LOG_FILE)
27
- @logger.level = Logger::INFO
28
- end
29
- @database_yml = DatabaseYml.new(db_yml_file, environment)
30
- @failover_db = FailoverDatabases.new(failover_yml_file, @logger)
31
- initialize_settings(ha_admin_yml_file)
15
+ def initialize(config_path = "")
16
+ initialize_settings(config_path)
17
+ @config_handlers = []
32
18
  end
33
19
 
34
- def monitor
35
- connection = pg_connection(@database_yml.pg_params_from_database_yml)
36
- if connection
37
- @failover_db.update_failover_yml(connection)
38
- connection.finish
39
- return
40
- end
41
-
42
- @logger.error("Primary Database is not available. EVM server stop initiated. Starting to execute failover...")
43
- stop_evmserverd
20
+ def add_handler(handler)
21
+ @config_handlers << [handler, ServerStore.new]
22
+ end
44
23
 
45
- if execute_failover
46
- start_evmserverd
47
- raise_failover_event
48
- else
49
- @logger.error("Failover failed")
24
+ def monitor
25
+ config_handlers.each do |handler, server_store|
26
+ begin
27
+ connection = pg_connection(handler.read)
28
+ if connection
29
+ server_store.update_servers(connection)
30
+ connection.finish
31
+ next
32
+ end
33
+
34
+ logger.error("Primary Database is not available for #{handler.name}. Starting to execute failover...")
35
+ handler.do_before_failover
36
+
37
+ new_conn_info = execute_failover(handler, server_store)
38
+ if new_conn_info
39
+ handler.do_after_failover(new_conn_info)
40
+ else
41
+ logger.error("Failover failed")
42
+ end
43
+ rescue => e
44
+ logger.error("Received #{e.class} error while monitoring #{handler.name}: #{e.message}")
45
+ logger.error(e.backtrace)
46
+ end
50
47
  end
51
48
  end
52
49
 
@@ -55,59 +52,52 @@ module PostgresHaAdmin
55
52
  begin
56
53
  monitor
57
54
  rescue => err
58
- @logger.error("#{err.class}: #{err}")
59
- @logger.error(err.backtrace.join("\n"))
55
+ logger.error("#{err.class}: #{err}")
56
+ logger.error(err.backtrace.join("\n"))
60
57
  end
61
58
  sleep(db_check_frequency)
62
59
  end
63
60
  end
64
61
 
65
- def active_servers_conninfo
66
- servers = @failover_db.active_databases_conninfo_hash
67
- db_yml_params = @database_yml.pg_params_from_database_yml
68
- servers.map! { |info| db_yml_params.merge(info) }
69
- end
70
-
71
- def raise_failover_event
72
- require "awesome_spawn"
73
- AwesomeSpawn.run("rake evm:raise_server_event",
74
- :chdir => RAILS_ROOT,
75
- :params => ["--", {:event => "db_failover_executed"}])
62
+ def active_servers_conninfo(handler, server_store)
63
+ servers = server_store.connection_info_list
64
+ current_params = handler.read
65
+ servers.map! { |info| current_params.merge(info) }
76
66
  end
77
67
 
78
68
  private
79
69
 
80
70
  def initialize_settings(ha_admin_yml_file)
71
+ ha_admin_yml = {}
81
72
  begin
82
- ha_admin_yml = YAML.load_file(ha_admin_yml_file)
73
+ ha_admin_yml = YAML.load_file(ha_admin_yml_file) if File.exist?(ha_admin_yml_file)
83
74
  rescue SystemCallError, IOError => err
84
- ha_admin_yml = {}
85
- @logger.error("#{err.class}: #{err}")
86
- @logger.info("File not loaded: #{ha_admin_yml_file}. Default settings for failover will be used.")
75
+ logger.error("#{err.class}: #{err}")
76
+ logger.info("File not loaded: #{ha_admin_yml_file}. Default settings for failover will be used.")
87
77
  end
88
78
  @failover_attempts = ha_admin_yml['failover_attempts'] || FAILOVER_ATTEMPTS
89
79
  @db_check_frequency = ha_admin_yml['db_check_frequency'] || DB_CHECK_FREQUENCY
90
80
  @failover_check_frequency = ha_admin_yml['failover_check_frequency'] || FAILOVER_CHECK_FREQUENCY
91
- @logger.info("FAILOVER_ATTEMPTS=#{@failover_attempts} DB_CHECK_FREQUENCY=#{@db_check_frequency} FAILOVER_CHECK_FREQUENCY=#{@failover_check_frequency}")
81
+ logger.info("FAILOVER_ATTEMPTS=#{@failover_attempts} DB_CHECK_FREQUENCY=#{@db_check_frequency} FAILOVER_CHECK_FREQUENCY=#{@failover_check_frequency}")
92
82
  end
93
83
 
94
- def execute_failover
84
+ def execute_failover(handler, server_store)
95
85
  failover_attempts.times do
96
- with_each_standby_connection do |connection, params|
86
+ with_each_standby_connection(handler, server_store) do |connection, params|
97
87
  next if database_in_recovery?(connection)
98
- next unless @failover_db.host_is_repmgr_primary?(params[:host], connection)
99
- @logger.info("Failing over to server using conninfo: #{params.reject { |k, _v| k == :password }}")
100
- @failover_db.update_failover_yml(connection)
101
- @database_yml.update_database_yml(params)
102
- return true
88
+ next unless server_store.host_is_primary?(params[:host], connection)
89
+ logger.info("Failing over to server using conninfo: #{params.reject { |k, _v| k == :password }}")
90
+ server_store.update_servers(connection)
91
+ handler.write(params)
92
+ return params
103
93
  end
104
94
  sleep(failover_check_frequency)
105
95
  end
106
96
  false
107
97
  end
108
98
 
109
- def with_each_standby_connection
110
- active_servers_conninfo.each do |params|
99
+ def with_each_standby_connection(handler, server_store)
100
+ active_servers_conninfo(handler, server_store).each do |params|
111
101
  connection = pg_connection(params)
112
102
  next if connection.nil?
113
103
  begin
@@ -121,19 +111,10 @@ module PostgresHaAdmin
121
111
  def pg_connection(params)
122
112
  PG::Connection.open(params)
123
113
  rescue PG::Error => e
124
- @logger.error("Failed to establish PG connection: #{e.message}")
114
+ logger.error("Failed to establish PG connection: #{e.message}")
125
115
  nil
126
116
  end
127
117
 
128
- def start_evmserverd
129
- LinuxAdmin::Service.new("evmserverd").restart
130
- @logger.info("Starting EVM server from failover monitor")
131
- end
132
-
133
- def stop_evmserverd
134
- LinuxAdmin::Service.new("evmserverd").stop
135
- end
136
-
137
118
  # Checks if postgres database is in recovery mode
138
119
  #
139
120
  # @param pg_connection [PG::Connection] established pg connection
@@ -0,0 +1,9 @@
1
+ module ManageIQ
2
+ module PostgresHaAdmin
3
+ module Logging
4
+ def logger
5
+ ManageIQ::PostgresHaAdmin.logger
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ require 'logger'
2
+
3
+ module ManageIQ
4
+ module PostgresHaAdmin
5
+ class NullLogger < Logger
6
+ def initialize(*_args)
7
+ end
8
+
9
+ def add(*_args, &_block)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -4,38 +4,38 @@ require 'pg/dsn_parser'
4
4
 
5
5
  module ManageIQ
6
6
  module PostgresHaAdmin
7
- class FailoverDatabases
7
+ class ServerStore
8
+ include Logging
9
+
8
10
  TABLE_NAME = "repmgr.nodes".freeze
9
11
 
10
- attr_reader :yml_file
12
+ attr_reader :servers
11
13
 
12
- def initialize(yml_file, logger)
13
- @yml_file = yml_file
14
- @logger = logger
14
+ def initialize
15
+ @servers = []
15
16
  end
16
17
 
17
- def active_databases_conninfo_hash
18
+ def connection_info_list
18
19
  valid_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
19
- active_databases.map! do |db_info|
20
+ servers.map! do |db_info|
20
21
  db_info.keep_if { |k, _v| valid_keys.include?(k) }
21
22
  end
22
23
  end
23
24
 
24
- def active_databases
25
- all_databases.select { |record| record[:active] }
26
- end
27
-
28
- def update_failover_yml(connection)
29
- arr_yml = query_repmgr(connection)
30
- File.write(yml_file, arr_yml.to_yaml) unless arr_yml.empty?
25
+ def update_servers(connection)
26
+ new_servers = query_repmgr(connection)
27
+ if servers_changed?(new_servers)
28
+ logger.info("Updating servers cache to #{new_servers}")
29
+ @servers = new_servers
30
+ end
31
31
  rescue IOError => err
32
- @logger.error("#{err.class}: #{err}")
33
- @logger.error(err.backtrace.join("\n"))
32
+ logger.error("#{err.class}: #{err}")
33
+ logger.error(err.backtrace.join("\n"))
34
34
  end
35
35
 
36
- def host_is_repmgr_primary?(host, connection)
36
+ def host_is_primary?(host, connection)
37
37
  query_repmgr(connection).each do |record|
38
- if record[:host] == host && entry_is_active_master?(record)
38
+ if record[:host] == host && record[:type] == 'primary'
39
39
  return true
40
40
  end
41
41
  end
@@ -44,10 +44,14 @@ module PostgresHaAdmin
44
44
 
45
45
  private
46
46
 
47
+ def servers_changed?(new_servers)
48
+ ((servers - new_servers) + (new_servers - servers)).any?
49
+ end
50
+
47
51
  def query_repmgr(connection)
48
52
  return [] unless table_exists?(connection, TABLE_NAME)
49
53
  result = []
50
- db_result = connection.exec("SELECT type, conninfo, active FROM #{TABLE_NAME}")
54
+ db_result = connection.exec("SELECT type, conninfo, active FROM #{TABLE_NAME} WHERE active")
51
55
  db_result.map_types!(PG::BasicTypeMapForResults.new(connection)).each do |record|
52
56
  dsn = PG::DSNParser.parse(record.delete("conninfo"))
53
57
  result << record.symbolize_keys.merge(dsn)
@@ -55,20 +59,11 @@ module PostgresHaAdmin
55
59
  db_result.clear
56
60
  result
57
61
  rescue PG::Error => err
58
- @logger.error("#{err.class}: #{err}")
59
- @logger.error(err.backtrace.join("\n"))
62
+ logger.error("#{err.class}: #{err}")
63
+ logger.error(err.backtrace.join("\n"))
60
64
  result
61
65
  end
62
66
 
63
- def entry_is_active_master?(record)
64
- record[:type] == 'primary' && record[:active]
65
- end
66
-
67
- def all_databases
68
- return [] unless File.exist?(yml_file)
69
- YAML.load_file(yml_file)
70
- end
71
-
72
67
  def table_exists?(connection, table_name)
73
68
  result = connection.exec("SELECT to_regclass('#{table_name}')").first
74
69
  !result['to_regclass'].nil?
@@ -1,5 +1,5 @@
1
1
  module ManageIQ
2
2
  module PostgresHaAdmin
3
- VERSION = '2.0.0'.freeze
3
+ VERSION = '3.1.2'.freeze
4
4
  end
5
5
  end
@@ -20,10 +20,11 @@ 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 "awesome_spawn", "~> 1.4"
24
- spec.add_runtime_dependency "linux_admin", "~> 1.0"
23
+ spec.add_runtime_dependency "activesupport", ">=5.0", "< 6.1"
24
+ spec.add_runtime_dependency "awesome_spawn", "~> 1.4"
25
+ spec.add_runtime_dependency "manageiq-password", "~> 0.3"
25
26
  spec.add_runtime_dependency "pg"
26
- spec.add_runtime_dependency "pg-dsn_parser", "~> 0.1"
27
+ spec.add_runtime_dependency "pg-dsn_parser", "~> 0.1"
27
28
 
28
29
  spec.add_development_dependency "bundler"
29
30
  spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0"
metadata CHANGED
@@ -1,15 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manageiq-postgres_ha_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ManageIQ Developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-01 00:00:00.000000000 Z
11
+ date: 2020-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '6.1'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '5.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '6.1'
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: awesome_spawn
15
35
  requirement: !ruby/object:Gem::Requirement
@@ -25,19 +45,19 @@ dependencies:
25
45
  - !ruby/object:Gem::Version
26
46
  version: '1.4'
27
47
  - !ruby/object:Gem::Dependency
28
- name: linux_admin
48
+ name: manageiq-password
29
49
  requirement: !ruby/object:Gem::Requirement
30
50
  requirements:
31
51
  - - "~>"
32
52
  - !ruby/object:Gem::Version
33
- version: '1.0'
53
+ version: '0.3'
34
54
  type: :runtime
35
55
  prerelease: false
36
56
  version_requirements: !ruby/object:Gem::Requirement
37
57
  requirements:
38
58
  - - "~>"
39
59
  - !ruby/object:Gem::Version
40
- version: '1.0'
60
+ version: '0.3'
41
61
  - !ruby/object:Gem::Dependency
42
62
  name: pg
43
63
  requirement: !ruby/object:Gem::Requirement
@@ -152,8 +172,7 @@ dependencies:
152
172
  version: '0'
153
173
  description: ManageIQ Postgres H.A. Admin
154
174
  email:
155
- executables:
156
- - postgres_ha_admin
175
+ executables: []
157
176
  extensions: []
158
177
  extra_rdoc_files: []
159
178
  files:
@@ -166,15 +185,20 @@ files:
166
185
  - ".rubocop_local.yml"
167
186
  - ".travis.yml"
168
187
  - CHANGELOG.md
188
+ - CODEOWNERS
169
189
  - Gemfile
170
190
  - LICENSE.txt
171
191
  - README.md
172
192
  - Rakefile
173
- - bin/postgres_ha_admin
174
193
  - lib/manageiq-postgres_ha_admin.rb
175
- - lib/manageiq/postgres_ha_admin/database_yml.rb
176
- - lib/manageiq/postgres_ha_admin/failover_databases.rb
194
+ - lib/manageiq/postgres_ha_admin/config_handler.rb
195
+ - lib/manageiq/postgres_ha_admin/config_handler/logical_replication_config_handler.rb
196
+ - lib/manageiq/postgres_ha_admin/config_handler/pglogical_config_handler.rb
197
+ - lib/manageiq/postgres_ha_admin/config_handler/rails_config_handler.rb
177
198
  - lib/manageiq/postgres_ha_admin/failover_monitor.rb
199
+ - lib/manageiq/postgres_ha_admin/logging.rb
200
+ - lib/manageiq/postgres_ha_admin/null_logger.rb
201
+ - lib/manageiq/postgres_ha_admin/server_store.rb
178
202
  - lib/manageiq/postgres_ha_admin/version.rb
179
203
  - manageiq-postgres_ha_admin.gemspec
180
204
  homepage: https://github.com/ManageIQ/manageiq-postgres_ha_admin
@@ -196,8 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
220
  - !ruby/object:Gem::Version
197
221
  version: '0'
198
222
  requirements: []
199
- rubyforge_project:
200
- rubygems_version: 2.6.14
223
+ rubygems_version: 3.0.6
201
224
  signing_key:
202
225
  specification_version: 4
203
226
  summary: ManageIQ Postgres H.A. Admin
@@ -1,7 +0,0 @@
1
- #!/bin/env ruby
2
-
3
- require 'bundler/setup'
4
- require 'manageiq-postgres_ha_admin'
5
-
6
- monitor = ManageIQ::PostgresHaAdmin::FailoverMonitor.new
7
- monitor.monitor_loop