require 'json' module WatchHelper WATCHER_FILENAME_PREFIX = 'watcher_'.freeze class Watcher attr_reader :name, :handler_script, :handler_template, :type, :consul_config_file, :template_variables, :service_name def initialize(name = nil, handler_script = nil, handler_template = nil, type = nil, consul_watch_config_directory = nil, template_variables = {}) @name = name @handler_script = handler_script @handler_template = handler_template @type = type @consul_config_file = "#{consul_watch_config_directory}/#{WATCHER_FILENAME_PREFIX}#{name}.json" @service_name = "service:#{name}" @template_variables = template_variables.merge({ "watcher_service_name" => @service_name }) end def consul_config { watches: [ { type: @type, service: @name, args: [handler_script] } ] }.to_json end end class WatcherConfig attr_reader :node, :enabled_watchers, :standard_watchers def initialize(node) @node = node # user configuration @enabled_watchers = @node['consul']['watchers'] @handler_directory = @node['consul']['script_directory'] @consul_config_directory = @node['consul']['config_dir'] # library standards @standard_watchers = [ Watcher.new(name = node['consul']['internal']['postgresql_service_name'], handler_script = "#{@handler_directory}/failover_postgresql_in_pgbouncer", handler_template = 'failover_pgbouncer.erb', type = 'service', consul_config = @consul_config_directory, template_variables = node['consul'].to_hash.merge({ 'database_name' => node['gitlab']['gitlab_rails']['db_database'] }) ) ] # Backward compatibility if someone had actually made a customer # watcher, even though it was never documented or supported @user_watcher_configs = @node['consul']['watcher_config'] || {} @user_watchers = [] @user_watcher_configs.each do |watcher, config| handler = config['handler'] @user_watchers.push(Watcher.new(name = watcher, handler_script = "#{@handler_directory}/#{handler}", handler_template = "#{handler}.erb", type = 'service', consul_config = @consul_config_directory, template_variables = node['consul'].to_hash ) ) end @all_watchers = @standard_watchers + @user_watchers end def watchers @all_watchers.select { |watcher| @enabled_watchers.include? watcher.name } end def excess_watcher_configs enabled_watcher_configs = watchers.map { |w| File.basename w.consul_config_file } Dir.glob("#{@consul_config_directory}/*") .reject { |f| !File.basename(f).start_with? WATCHER_FILENAME_PREFIX } .reject { |f| enabled_watcher_configs.include? f } end def excess_handler_scripts enabled_handlers = watchers.map { |w| File.basename w.handler_script } Dir.glob("#{@handler_directory}/*") .reject { |h| enabled_handlers.include? h } end end end