HTTPAPI and slack handlers


#1

We have Ubuntu 16.04 / 18.04 with chef-client 14.1.12.
Handlers are added to client.d folder.

template "/etc/chef/client.d/httpapi_handler.rb" do
  source "httpapi_handler.rb.erb"
  mode '0644'
end

Handler itself. HTTPAPI part is based on https://github.com/b1-systems/chef-handler-httpapi
I tried to use http call for slack as well but it didn’t work so I added new class with curl

require 'rubygems'
require 'chef'
require 'chef/handler'

require "net/http"
require "uri"
require "json"

class Httpapi < Chef::Handler
    def initialize(api_url, api_user, api_pass)
        @api_url = api_url
        @api_user = api_user
        @api_pass = api_pass
    end

    def report
        uri = URI.parse(@api_url)
        http = Net::HTTP.new(uri.host, uri.port)

        request = Net::HTTP::Post.new(uri.request_uri)
        request.basic_auth(@api_user, @api_pass)

        if run_status.success?
            api_data = { :id => "#{node.name}/chef", :message => "Chef successfull on #{node.name}", :details => { :Tags => { :host => "#{node.name}" }, :Level => "OK" } }
        else
            api_data = { :id => "#{node.name}/chef", :message => "Chef failed on #{node.name}, exception: #{run_status.exception}", :details => { :Tags => { :host => "#{node.name}" }, :Level => "CRITICAL" } }
        end

        request.body = api_data.to_json
        response = http.request(request)
        puts response
    end
end

class Slack < Chef::Handler
    def initialize(webhook_url)
        @webhook_url = webhook_url
    end

    def report
        if run_status.failed?
            message = { :text => "Chef failed on #{node.name}\n#{run_status.exception}" }
            payload = message.to_json

            cmd = "curl -X POST --data-urlencode 'payload=#{payload}' #{@webhook_url}"
            system(cmd)
        end
    end
end

api_url = "<%= node['dashboard']['api_url'] %>"
api_user = "<%= node['dashboard']['admin'] %>"
api_pass = "<%= node['dashboard']['password'] %>"
webhook_url = "<%= node['slack']['webhook_url'] %>"

Httpapi_handler = Httpapi.new(api_url, api_user, api_pass)
Slack_handler = Slack.new(webhook_url)

report_handlers << Slack_handler
exception_handlers << Slack_handler
report_handlers << Httpapi_handler
exception_handlers << Httpapi_handler

Notifications to HTTPAPI and Slack works but sometimes 100 same massages can came from one host.
Like host can’t be resolved

STDERR: ssh: Could not resolve hostname example.com: Temporary failure in name resolution
fatal: Could not read from remote repository.

or service can’t start

STDERR: Job for openvpn.service failed because a configured resource limit was exceeded. See "systemctl status openvpn.service" and "journalctl -xe" for details.

Logs from chef-client run

2018-06-18 16:56:47 6 chef-client[980]: #<Net::HTTPOK:0x000000000594fc28>
2018-06-18 16:56:47 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Httpapi#033[0m
2018-06-18 16:56:47 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Slack#033[0m
2018-06-18 16:56:47 6 chef-client[980]: #<Net::HTTPOK:0x000000000594a1d8>
2018-06-18 16:56:47 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Httpapi#033[0m
2018-06-18 16:56:47 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Slack#033[0m
2018-06-18 16:56:47 6 chef-client[980]: #<Net::HTTPOK:0x00000000059447d8>
2018-06-18 16:56:47 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Httpapi#033[0m
2018-06-18 16:56:47 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Slack#033[0m
2018-06-18 16:56:47 6 chef-client[980]: #<Net::HTTPOK:0x000000000593f378>
2018-06-18 16:56:47 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Httpapi#033[0m
2018-06-18 16:56:47 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Slack#033[0m
2018-06-18 16:56:48 6 chef-client[980]: #<Net::HTTPOK:0x0000000005cbe0a8>
2018-06-18 16:56:48 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Httpapi#033[0m
2018-06-18 16:56:48 6 chef-client[980]:   - #<Class:0x00000000029fe050>::Slack#033[0m

Why Slack Class belongs to Net::HTTPOK?
What should I do to send only one message to Slack? Add “exit” to cmd command?
Thanks in advance.