# frozen_string_literal: true require "uri" module Backup module Notifier class HttpPost < Base ## # URI to post notification to. # # URI scheme may be `http` or `https`. # # If Basic Authentication is needed, supply the `user:password` in the # URI. e.g. 'https://user:pass@www.example.com/path' # # Port may also be supplied. # e.g. 'http://www.example.com:8080/path' attr_accessor :uri ## # Hash of additional HTTP headers to send. # # This notifier sets the following headers: # { 'User-Agent' => "Backup/#{ Backup::VERSION }", # 'Content-Type' => 'x-www-form-urlencoded' } # # 'Content-Type' may not be changed. # 'User-Agent' may be overridden or omitted by setting it to +nil+. # e.g. { 'Authorization' => 'my_auth_info', 'User-Agent' => nil } attr_accessor :headers ## # Hash of additional POST parameters to send. # # This notifier will set two parameters: # { 'status' => 'success|warning|failure', # 'message' => '[Backup::(Success|Warning|Failure)] label (trigger)' } # # 'status' may not be changed. # 'message' may be overridden or omitted by setting a +nil+ value. # e.g. { 'auth_token' => 'my_token', 'message' => nil } attr_accessor :params ## # Successful HTTP Status Code(s) that should be returned. # # This may be a single code or an Array of acceptable codes. # e.g. [200, 201, 204] # # If any other response code is returned, the request will be retried # using `max_retries` and `retry_waitsec`. # # Default: 200 attr_accessor :success_codes ## # Verify the server's certificate when using SSL. # # This will default to +true+ for most systems. It may be forced by # setting to +true+, or disabled by setting to +false+. attr_accessor :ssl_verify_peer ## # Path to a +cacert.pem+ file to use for +ssl_verify_peer+. # # This is provided (via Excon), but may be specified if needed. attr_accessor :ssl_ca_file def initialize(model, &block) super instance_eval(&block) if block_given? @headers ||= {} @params ||= {} @success_codes ||= 200 end private ## # Notify the user of the backup operation results. # # `status` indicates one of the following: # # `:success` # : The backup completed successfully. # : Notification will be sent if `on_success` is `true`. # # `:warning` # : The backup completed successfully, but warnings were logged. # : Notification will be sent if `on_warning` or `on_success` is `true`. # # `:failure` # : The backup operation failed. # : Notification will be sent if `on_warning` or `on_success` is `true`. # def notify!(status) msg = message.call(model, status: status_data_for(status)) opts = { headers: { "User-Agent" => "Backup/#{VERSION}" } .merge(headers).reject { |_, value| value.nil? } .merge("Content-Type" => "application/x-www-form-urlencoded"), body: URI.encode_www_form({ "message" => msg } .merge(params).reject { |_, value| value.nil? } .merge("status" => status.to_s)), expects: success_codes # raise error if unsuccessful } opts[:ssl_verify_peer] = ssl_verify_peer unless ssl_verify_peer.nil? opts[:ssl_ca_file] = ssl_ca_file if ssl_ca_file Excon.post(uri, opts) end end end end