Class: LogStash::Inputs::GitHub

Inherits:
Base
  • Object
show all
Defined in:
lib/logstash/inputs/github.rb

Overview

Read events from github webhooks

Instance Method Summary collapse

Instance Method Details

#build_event_from_request(body, headers) ⇒ Object

def run



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/logstash/inputs/github.rb', line 54

def build_event_from_request(body, headers)
  begin
    data = JSON.parse(body)
    # The JSON specification defines single values as valid JSONs, it can be a string in double quotes,
    # a number, true or false or null. When the body is parsed, those values are transformed into its
    # corresponding types. When those types aren't a Hash (aka object),  it breaks the LogStash::Event
    # contract and crashes.
    if data.is_a?(::Hash)
      event = LogStash::Event.new(data)
    else
      event = LogStash::Event.new("message" => body, "tags" => "_invalidjsonobject")
    end
  rescue JSON::ParserError => e
    @logger.info("JSON parse failure. Falling back to plain-text", :error => e, :data => body)
    event = LogStash::Event.new("message" => body, "tags" => "_invalidjson")
  end
  event.set('headers', headers)
  return event
end

#registerObject



25
26
27
# File 'lib/logstash/inputs/github.rb', line 25

def register
  require "ftw"
end

#run(output_queue) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/logstash/inputs/github.rb', line 30

def run(output_queue)
  @server = FTW::WebServer.new(@ip, @port) do |request, response|
      body = request.read_body
      event = build_event_from_request(body, request.headers.to_hash)
      valid_event = verify_signature(event,body)
      if !valid_event && @drop_invalid
        @logger.info("Dropping invalid Github message")
      else
        decorate(event)
        output_queue << event
      end
      response.status = 200
      response.body = "Accepted!"
  end
  @server.run
rescue Exception => original_exception
  # If our server crashes, it may not have cleaned up after itself;
  # since `FTW::WebServer#stop` is idempotent, make one last attempt
  # before propagating the original exception.
  @server && @server.stop rescue logger.error("Error while stopping FTW::WebServer", exception: $!.message, backtrace: $!.backtrace)

  raise original_exception
end

#stopObject



89
90
91
# File 'lib/logstash/inputs/github.rb', line 89

def stop
  @server && @server.stop
end

#verify_signature(event, body) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/logstash/inputs/github.rb', line 74

def verify_signature(event,body)
  # skip validation if we have no secret token
  return true unless @secret_token

  sign_header = event.get("[headers][x-hub-signature]")
  if sign_header
    hash = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), @secret_token.value, body)
    event.set("hash", hash)
    return true if Rack::Utils.secure_compare(hash, sign_header)
  end

  event.tag("_Invalid_Github_Message")
  return false
end