lib/bender/main.rb in bender-bot-0.5.6 vs lib/bender/main.rb in bender-bot-0.6.0

- old
+ new

@@ -6,11 +6,10 @@ require 'queryparams' require_relative 'metadata' require_relative 'mjolnir' require_relative 'helpers' -require_relative 'web' require_relative 'bot' Thread.abort_on_exception = true @@ -29,156 +28,100 @@ puts "\n%s\n" % ART end - desc 'bot', 'Start Bender HipChat bot and Web server' - option :bind, \ + desc 'start', 'Start Bender HipChat bot and Web server' + option :config, \ type: :string, - aliases: %w[ -b ], - desc: 'Set Sinatra interface', - default: '0.0.0.0' - option :port, \ - type: :numeric, - aliases: %w[ -o ], - desc: 'Set Sinatra port', - default: 4567 - option :environment, \ - type: :string, - aliases: %w[ -e ], - desc: 'Set Sinatra environment', - default: 'development' - option :hipchat_token, \ - type: :string, - aliases: %w[ -t ], - desc: 'Set HipChat v1 API token', - required: true - option :hipchat_v2_token, \ - type: :string, aliases: %w[ -c ], - desc: 'Set HipChat v2 API token', + desc: 'Set path to config file', required: true - option :primary_room_id, \ - type: :string, - aliases: %w[ -i ], - desc: 'Set HipChat primary room ID', - required: true - option :jid, \ - type: :string, - aliases: %w[ -j ], - desc: 'Set HipChat JID', - required: true - option :password, \ - type: :string, - aliases: %w[ -p ], - desc: 'Set HipChat password', - required: true - option :nick, \ - type: :string, - aliases: %w[ -n ], - desc: 'Set HipChat nick name', - required: true - option :mention, \ - type: :string, - aliases: %w[ -m ], - desc: 'Set HipChat mention name', - required: true - option :rooms, \ - type: :string, - aliases: %w[ -r ], - desc: 'Set HipChat rooms (comma-separated)', - required: true - option :database, \ - type: :string, - aliases: %w[ -d ], - desc: 'Set path to application database', - required: true - option :jira_user, \ - type: :string, - aliases: %w[ -U ], - desc: 'Set JIRA username', - required: true - option :jira_pass, \ - type: :string, - aliases: %w[ -P ], - desc: 'Set JIRA password', - required: true - option :jira_site, \ - type: :string, - aliases: %w[ -S ], - desc: 'Set JIRA site', - required: true - option :jira_project, \ - type: :string, - aliases: %w[ -J ], - desc: 'Set JIRA project', - required: true - option :jira_group, \ - type: :string, - aliases: %w[ -G ], - desc: 'Set JIRA group for write mode', - required: true - option :jira_type, \ - type: :string, - aliases: %w[ -T ], - desc: 'Set JIRA issue type', - required: true - option :user_refresh, \ - type: :numeric, - aliases: %w[ -R ], - desc: 'Set JIRA user refresh rate', - default: 300 - option :issue_refresh, \ - type: :numeric, - aliases: %w[ -S ], - desc: 'Set JIRA issue refresh rate', - default: 5 - option :group_refresh, \ - type: :numeric, - aliases: %w[ -T ], - desc: 'Set JIRA group refresh rate', - default: 60 - option :order, \ - type: :boolean, - aliases: %w[ -O ], - desc: 'Reverse order of HipChat API loading (hack)', - default: false - option :room_base_name, \ - type: :string, - aliases: %w[ -N ], - desc: 'Base name for the primary room', - default: 'Production Indicent' include_common_options def start + raw_config = JSON.parse File.read(options.config), symbolize_names: true + @config = DEFAULT_CONFIG.merge! raw_config + + BenderBot.const_set :RESOLVED_TRANSITIONS, %w[ 51 ] + Bender.const_set :RESOLVED_TRANSITIONS, BenderBot::RESOLVED_TRANSITIONS + Helpers.const_set :RESOLVED_TRANSITIONS, BenderBot::RESOLVED_TRANSITIONS + + BenderBot.const_set :RESOLVED_STATE, /resolve/i + Bender.const_set :RESOLVED_STATE, BenderBot::RESOLVED_STATE + Helpers.const_set :RESOLVED_STATE, BenderBot::RESOLVED_STATE + + BenderBot.const_set :CLOSED_TRANSITIONS, %w[ 61 71 ] + Bender.const_set :CLOSED_TRANSITIONS, BenderBot::CLOSED_TRANSITIONS + Helpers.const_set :CLOSED_TRANSITIONS, BenderBot::CLOSED_TRANSITIONS + + BenderBot.const_set :CLOSED_STATE, /close/i + Bender.const_set :CLOSED_STATE, BenderBot::CLOSED_STATE + Helpers.const_set :CLOSED_STATE, BenderBot::CLOSED_STATE + + BenderBot.const_set :SEVERITIES, { + 1 => '10480', + 2 => '10481', + 3 => '10482', + 4 => '10483', + 5 => '10484' + } + Bender.const_set :SEVERITIES, BenderBot::SEVERITIES + Helpers.const_set :SEVERITIES, BenderBot::SEVERITIES + + BenderBot.const_set :SHOW_FIELDS, { + 'summary' => 'Summary', + 'description' => 'Description', + 'customfield_11250' => 'Severity', + 'customfield_11251' => 'Impact Started', + 'customfield_11252' => 'Impact Ended', + 'customfield_11253' => 'Reported By', + 'customfield_11254' => 'Services Affected', + 'customfield_11255' => 'Cause', + 'status' => 'Status', + 'created' => 'Created', + 'updated' => 'Updated' + } + Bender.const_set :SHOW_FIELDS, BenderBot::SHOW_FIELDS + Helpers.const_set :SHOW_FIELDS, BenderBot::SHOW_FIELDS + + BenderBot.const_set :SEVERITY_FIELD, SHOW_FIELDS.key('Severity') + Bender.const_set :SEVERITY_FIELD, BenderBot::SEVERITY_FIELD + Helpers.const_set :SEVERITY_FIELD, BenderBot::SEVERITY_FIELD + + BenderBot.set_commands + bot = start_bot ts = [] ts << periodically_refresh_group(bot) ts << periodically_refresh_users(bot) ts << periodically_refresh_incidents(bot) - # serve_web bot + ts.map(&:join) end private + def config ; @config end + def start_bot - Bot::Connection.configure do |config| - config.jid = options.jid - config.password = options.password - config.nick = options.mention - config.mention_name = options.nick - config.rooms = options.rooms.split(',') + Bot::Connection.configure do |conn| + conn.jid = config[:jid] + conn.password = config[:password] + conn.nick = config[:mention] + conn.mention_name = config[:nick] + conn.rooms = config[:rooms].is_a?(Array) ? \ + config[:rooms] : config[:rooms].split(',') - Bot::Storage::YamlStore.file = options.database - config.store = Bot::Storage::YamlStore + Bot::Storage::YamlStore.file = config[:database] + conn.store = Bot::Storage::YamlStore - config.logger = log + conn.logger = log end - Bot.run! options, log + Bot.run! config, log end def set_room_name_and_topic room_id, incidents, hipchat, bot room = hipchat[room_id] @@ -203,22 +146,22 @@ @room_name ||= bot.store['primary_room_name'] || new_room['name'] @room_topic ||= bot.store['primary_room_topic'] || new_room['topic'] @open = nil unless defined? @open - log.trace \ + log.debug \ primary_room_name: bot.store['primary_room_name'], primary_room_topic: bot.store['primary_room_topic'], new_room_name: new_room['name'], new_room_topic: new_room['topic'], room_name: @room_name, room_topic: @room_topic, open: @open if open_incidents.empty? if @open.nil? || @open > 0 - new_room['name'] = '[NONE] %s' % options.room_base_name + new_room['name'] = '[NONE] %s' % config[:room_base_name] new_room['topic'] = 'Good news everyone! No high-severity incidents at the moment' apply_room_name_and_topic new_room end @open = 0 @@ -228,11 +171,11 @@ @room_name = new_room['name'] @room_topic = new_room['topic'] end unless @open == open_incidents.size - new_room['name'] = '[IN PROGRESS] %s' % options.room_base_name + new_room['name'] = '[IN PROGRESS] %s' % config[:room_base_name] tha_news = open_incidents.size == 1 ? "There's a high-severity incident" : "There are #{open_incidents.size} high-severity incidents" new_room['topic'] = "Terrible news everyone! #{tha_news}" apply_room_name_and_topic new_room end @@ -245,14 +188,14 @@ def apply_room_name_and_topic room uri = URI room['links']['self'] - resp = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| + Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| req = Net::HTTP::Put.new uri req['Content-Type'] = 'application/json' - req['Authorization'] = 'Bearer %s' % options.hipchat_v2_token + req['Authorization'] = 'Bearer %s' % config[:hipchat_v2_token] req.body = { name: room['name'], topic: room['topic'], privacy: room['privacy'], is_archived: room['is_archived'], @@ -265,45 +208,45 @@ end def periodically_refresh_incidents bot Thread.new do - if options.order + if config[:order] hipchat_v1 = HipChat::Client.new \ - options.hipchat_token, api_version: 'v1' + config[:hipchat_token], api_version: 'v1' hipchat_v2 = HipChat::Client.new \ - options.hipchat_v2_token, api_version: 'v2' + config[:hipchat_v2_token], api_version: 'v2' else hipchat_v2 = HipChat::Client.new \ - options.hipchat_v2_token, api_version: 'v2' + config[:hipchat_v2_token], api_version: 'v2' hipchat_v1 = HipChat::Client.new \ - options.hipchat_token, api_version: 'v1' + config[:hipchat_token], api_version: 'v1' end - room_id = options.primary_room_id + room_id = config[:primary_room_id] loop do is = refresh_incidents bot set_room_name_and_topic room_id, is, hipchat_v2, bot - sleep options.issue_refresh + sleep config[:issue_refresh] end end end def periodically_refresh_users bot req_path = '/rest/api/2/user/assignable/search' req_params = QueryParams.encode \ - project: options.jira_project, + project: config[:jira_project], startAt: 0, maxResults: 1_000_000 - uri = URI(options.jira_site + req_path + '?' + req_params) + uri = URI(config[:jira_site] + req_path + '?' + req_params) http = Net::HTTP.new uri.hostname, uri.port req = Net::HTTP::Get.new uri - req.basic_auth options.jira_user, options.jira_pass + req.basic_auth config[:jira_user], config[:jira_pass] req['Content-Type'] = 'application/json' req['Accept'] = 'application/json' Thread.new do loop do @@ -327,27 +270,27 @@ } ; h end bot.store['users'] = users - sleep options.user_refresh + sleep config[:user_refresh] end end end def periodically_refresh_group bot req_path = '/rest/api/2/group' req_params = QueryParams.encode \ - groupname: options.jira_group, + groupname: config[:jira_group], expand: 'users' - uri = URI(options.jira_site + req_path + '?' + req_params) + uri = URI(config[:jira_site] + req_path + '?' + req_params) http = Net::HTTP.new uri.hostname, uri.port req = Net::HTTP::Get.new uri - req.basic_auth options.jira_user, options.jira_pass + req.basic_auth config[:jira_user], config[:jira_pass] req['Content-Type'] = 'application/json' req['Accept'] = 'application/json' Thread.new do loop do @@ -362,31 +305,12 @@ next end user_names = data['users']['items'].map { |u| u['displayName'] } bot.store['group'] = user_names - sleep options.group_refresh + sleep config[:group_refresh] end end end - - - def serve_web bot - Web.set :environment, options.environment - Web.set :port, options.port - Web.set :bind, options.bind - Web.set :store, options.database - - if log.level >= ::Logger::DEBUG - Web.set :raise_errors, true - Web.set :dump_errors, true - Web.set :show_exceptions, true - Web.set :logging, ::Logger::DEBUG - end - - Web.set :bot, bot - Web.run! - end - end end