loadrunner 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ed96c8d23afef79bc83474cdeb980cdea9a27177
4
- data.tar.gz: 0bf010a529fad2cb7b1aa6b701be77e719e8c213
3
+ metadata.gz: 3b9fd36357c745fed71eae60ca9b40ee65a4efa9
4
+ data.tar.gz: 6bae665acbdf5c16086c7c31f041f6a5e855c78b
5
5
  SHA512:
6
- metadata.gz: 0c32f1097bcee3743adc63cb1148fecf533b4e78fdd24e1a2f1ead011f7e9301431f4894bb1fa30e3db081c3badb100c252a9389961fba5f09c17406ea3f4537
7
- data.tar.gz: 2c47338a7941d91f70b91b260fa0806f6cc97694f6520f9d1e02c68f71a9b27884befdd9c0ae9000bc3a1c18c4d30483d04c0a943c286340e68006adf8324357
6
+ metadata.gz: baeaa1f2dee184b212ed6e9c0fff2437b05d2d5ed9c553708e383b06dfec022415e01eb7d90aebc131ce8eab26da683e9d6c2446ca2ee1e4619a30525ec40343
7
+ data.tar.gz: e99dc43867d5b07839a0e9a94d3e1330e74b803c1ba9a5afaed3d7493b50d4636a3b927651308697662f9777a6ba8938508f10c05f1510005128587477cc0292
data/README.md CHANGED
@@ -28,9 +28,18 @@ $ gem install loadrunner
28
28
  Getting Started
29
29
  --------------------------------------------------
30
30
 
31
- Soon
31
+ # Create a sample hook handler
32
+ $ mkdir -p handlers/myrepo
33
+ $ echo "#\!/usr/bin/env bash" > handlers/myrepo/push
34
+ $ echo "echo hello > output.txt" >> handlers/myrepo/push
35
+
36
+ # Start the server
37
+ $ loadrunner server
38
+
39
+ # In another terminal, send a sample webhook event
40
+ $ loadrunner send localhost:3000 myrepo push master
41
+
42
+ # Verify the handler was executed
43
+ $ cat output.txt
32
44
 
33
- Usage
34
- --------------------------------------------------
35
45
 
36
- Soon
@@ -18,7 +18,8 @@ module LoadRunner
18
18
 
19
19
  def send_payload(event=:push, payload)
20
20
  @payload = payload.is_a?(String) ? payload : payload.to_json
21
- self.class.post "/payload", body: @payload, headers: headers(:push)
21
+ headers = headers event
22
+ self.class.post "/payload", body: @payload, headers: headers
22
23
  end
23
24
 
24
25
  private
@@ -32,7 +33,7 @@ module LoadRunner
32
33
 
33
34
  def signature
34
35
  return nil unless secret_token
35
- signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), secret_token, payload)
36
+ 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), secret_token, payload)
36
37
  end
37
38
 
38
39
  def build_payload(opts={})
@@ -55,14 +56,9 @@ module LoadRunner
55
56
  def repo_from_opts(opts)
56
57
  if opts[:repo] =~ /.+\/.+/
57
58
  _owner, name = opts[:repo].split '/'
58
- {
59
- name: name,
60
- full_name: opts[:repo]
61
- }
59
+ { name: name, full_name: opts[:repo] }
62
60
  else
63
- {
64
- name: opts[:repo]
65
- }
61
+ { name: opts[:repo] }
66
62
  end
67
63
  end
68
64
 
@@ -1,62 +1,63 @@
1
- require 'singleton'
2
- require 'docopt'
3
-
4
- module LoadRunner
5
-
6
- # Handles the command line interface
7
- class CommandLine
8
- include Singleton
9
-
10
- attr_reader :args
11
-
12
- # Gets an array of arguments (e.g. ARGV), executes the command if valid
13
- # and shows usage patterns / help otherwise.
14
- def execute(argv=[])
15
- doc = File.read File.dirname(__FILE__) + '/docopt.txt'
16
- begin
17
- @args = Docopt::docopt(doc, argv: argv, version: VERSION)
18
- handle
19
- rescue Docopt::Exit => e
20
- puts e.message
21
- end
22
- end
23
-
24
- private
25
-
26
- # Called when the arguments match one of the usage patterns. Will
27
- # delegate action to other, more specialized methods.
28
- def handle
29
- return send if args['send']
30
- return server if args['server']
31
- end
32
-
33
- def send
34
- client = Client.new client_opts
35
- response = client.send args['EVENT'], payload_opts
36
- puts response
37
- end
38
-
39
- def server
40
- Server.prepare port: args['--port'], bind: args['--bind']
41
- Server.run!
42
- end
43
-
44
- def client_opts
45
- {
46
- base_url: args['URL'],
47
- secret_token: '123'
48
- }
49
- end
50
-
51
- def payload_opts
52
- result = { repo: args['REPO'] }
53
-
54
- ref = args['REF']
55
- ref = "refs/tags/#{$1}" if ref =~ /^tag:(.+)/
56
- ref = "refs/heads/#{$1}" if ref =~ /^branch:(.+)/
57
-
58
- result[:ref] = ref
59
- result
60
- end
61
- end
62
- end
1
+ require 'singleton'
2
+ require 'docopt'
3
+
4
+ module LoadRunner
5
+
6
+ # Handles the command line interface
7
+ class CommandLine
8
+ include Singleton
9
+
10
+ attr_reader :args
11
+
12
+ # Gets an array of arguments (e.g. ARGV), executes the command if valid
13
+ # and shows usage patterns / help otherwise.
14
+ def execute(argv=[])
15
+ doc = File.read File.dirname(__FILE__) + '/docopt.txt'
16
+ begin
17
+ @args = Docopt::docopt(doc, argv: argv, version: VERSION)
18
+ handle
19
+ rescue Docopt::Exit => e
20
+ puts e.message
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ # Called when the arguments match one of the usage patterns. Will
27
+ # delegate action to other, more specialized methods.
28
+ def handle
29
+ return send if args['send']
30
+ return server if args['server']
31
+ end
32
+
33
+ def send
34
+ client = Client.new client_opts
35
+ response = client.send args['EVENT'], payload_opts
36
+ puts response
37
+ end
38
+
39
+ def server
40
+ Server.prepare port: args['--port'], bind: args['--bind']
41
+ Server.run!
42
+ end
43
+
44
+ def client_opts
45
+ {
46
+ base_url: args['URL'],
47
+ secret_token: '123'
48
+ }
49
+ end
50
+
51
+ def payload_opts
52
+ result = { repo: args['REPO'] }
53
+
54
+ ref = args['REF']
55
+ ref = "refs/tags/#{$1}" if ref =~ /^tag=(.+)/
56
+ ref = "refs/heads/#{$1}" if ref =~ /^branch=(.+)/
57
+ ref = "refs/heads/#{ref}" if ref !~ /^refs/
58
+
59
+ result[:ref] = ref
60
+ result
61
+ end
62
+ end
63
+ end
@@ -1,55 +1,57 @@
1
- LoadRunner
2
-
3
- Usage:
4
- loadrunner server [--port N --bind IP]
5
- loadrunner send URL REPO EVENT REF
6
- loadrunner (-h|--help|--version)
7
-
8
- Commands:
9
- server
10
- Start the webhook server.
11
-
12
- send
13
- Send a simulated GitHub event to a webhook server.
14
-
15
- Parameters:
16
- URL
17
- The URL of the webhook server. This server should have a /payload
18
- endpoint that responds to POST requests.
19
-
20
- REPO
21
- The name of the repository. This can be either the short name
22
- (my_repo), or the full name (my_name/my_repo).
23
-
24
- EVENT
25
- Any GitHub event, for example: push or ping.
26
-
27
- REF
28
- A branch or tag specifier. This parameter supports three formats:
29
- * tag:tag_name
30
- * branch:branch_name
31
- * raw ref string (for example /refs/tags/tagname)
32
-
33
- Options:
34
- --port N
35
- Set the port of the webhook server.
36
-
37
- --bind IP
38
- Set the listening address of the webhook server.
39
-
40
-
41
- Environment Variables:
42
- GITHUB_SECRET_TOKEN=y0urAP1k3y
43
- Set Your GitHub secret token.
44
-
45
- Examples:
46
- # Simulate push events
47
- loadrunner send localhost:3000 my_repo push branch:master
48
- loadrunner send localhost:3000 my_repo push tag:staging
49
- loadrunner send localhost:3000 my_repo push refs/tags/staging
50
-
51
- # Start the server
52
- loadrunner server
53
- loadrunner server --bind 0.0.0.0 --port 3000
54
-
55
-
1
+ LoadRunner
2
+
3
+ Usage:
4
+ loadrunner server [--port N --bind IP]
5
+ loadrunner send URL REPO EVENT [REF]
6
+ loadrunner (-h|--help|--version)
7
+
8
+ Commands:
9
+ server
10
+ Start the webhook server.
11
+
12
+ send
13
+ Send a simulated GitHub event to a webhook server.
14
+
15
+ Parameters:
16
+ URL
17
+ The URL of the webhook server. This server should have a /payload
18
+ endpoint that responds to POST requests.
19
+
20
+ REPO
21
+ The name of the repository. This can be either the short name
22
+ (my_repo), or the full name (my_name/my_repo).
23
+
24
+ EVENT
25
+ Any GitHub event, for example: push or ping.
26
+
27
+ REF
28
+ A branch or tag specifier. This parameter supports four formats:
29
+ * branch_name
30
+ * tag=tag_name
31
+ * branch=branch_name
32
+ * raw ref string (for example refs/tags/tagname)
33
+
34
+ Options:
35
+ --port N
36
+ Set the port of the webhook server.
37
+
38
+ --bind IP
39
+ Set the listening address of the webhook server.
40
+
41
+
42
+ Environment Variables:
43
+ GITHUB_SECRET_TOKEN=y0urAP1k3y
44
+ Set Your GitHub secret token.
45
+
46
+ Examples:
47
+ # Simulate push events
48
+ loadrunner send localhost:3000 my_repo push master
49
+ loadrunner send localhost:3000 my_repo push branch=master
50
+ loadrunner send localhost:3000 my_repo push tag=staging
51
+ loadrunner send localhost:3000 my_repo push refs/tags/staging
52
+
53
+ # Start the server
54
+ loadrunner server
55
+ loadrunner server --bind 0.0.0.0 --port 3000
56
+
57
+
@@ -0,0 +1,66 @@
1
+ module LoadRunner
2
+
3
+ class Runner
4
+ attr_reader :opts
5
+ attr_accessor :response
6
+
7
+ def initialize(opts)
8
+ @opts = opts
9
+ end
10
+
11
+ def execute
12
+ set_environment_vars
13
+
14
+ @response = opts.dup
15
+ handlers = locate_handlers
16
+
17
+ if handlers.empty?
18
+ @response[:matching_handlers] = matching_handlers
19
+ @response[:error] = "Could not find any handler to process this webhook. Please implement one of the 'matching_handlers'."
20
+ return false
21
+ else
22
+ execute_all handlers
23
+ @response[:executed_handlers] = handlers
24
+ return true
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def locate_handlers
31
+ handlers = []
32
+
33
+ matching_handlers.each do |handler|
34
+ handlers << handler if File.exist? handler
35
+ end
36
+
37
+ handlers
38
+ end
39
+
40
+ def execute_all(handlers)
41
+ handlers.each do |handler|
42
+ run_bg handler
43
+ end
44
+ end
45
+
46
+ def run_bg(cmd)
47
+ job = fork { exec cmd }
48
+ Process.detach job
49
+ end
50
+
51
+ def set_environment_vars
52
+ opts.each { |key, value| ENV[key.to_s.upcase] = value }
53
+ end
54
+
55
+ def matching_handlers
56
+ base = "handlers/#{opts[:repo]}"
57
+ handlers = ["#{base}/#{opts[:event]}"]
58
+
59
+ handlers.tap do |h|
60
+ h << "#{base}/#{opts[:event]}@branch-#{opts[:branch]}" if opts[:branch]
61
+ h << "#{base}/#{opts[:event]}@tag-#{opts[:tag]}" if opts[:tag]
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -2,6 +2,8 @@ module LoadRunner
2
2
 
3
3
  # The Sinatra server
4
4
  class Server < ServerBase
5
+ include ServerHelper
6
+
5
7
  post '/payload' do
6
8
  request.body.rewind
7
9
  payload_body = request.body.read
@@ -10,26 +12,18 @@ module LoadRunner
10
12
 
11
13
  push = ActiveSupport::HashWithIndifferentAccess.new JSON.parse payload_body
12
14
 
13
- branch = push[:ref] =~ /refs\/heads/ ? push[:ref].sub('refs/heads/', '') : nil
14
- tag = push[:ref] =~ /refs\/tags/ ? push[:ref].sub('refs/tags/', '') : nil
15
- repo = push[:repository][:name]
16
- event = request.env['HTTP_X_GITHUB_EVENT']
17
-
18
- result = { event: event, repo: repo, branch: branch, tag: tag }
19
- result.inspect
15
+ opts = {}
16
+ opts[:repo] = push[:repository][:name]
17
+ opts[:event] = request.env['HTTP_X_GITHUB_EVENT']
18
+ opts[:branch] = push[:ref].sub('refs/heads/', '') if push[:ref] =~ /refs\/heads/
19
+ opts[:tag] = push[:ref].sub('refs/tags/', '') if push[:ref] =~ /refs\/tags/
20
20
 
21
- file = "handlers/#{repo}/#{event}"
22
- File.exist?(file) ? `#{file}` : result.inspect
23
- end
21
+ runner = Runner.new opts
22
+ success = runner.execute
24
23
 
25
- def verify_signature(payload_body)
26
- signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), secret_token, payload_body)
27
- signature_match = Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE'])
28
- return halt 401, "Bad Signature" unless signature_match
29
- end
24
+ status 404 unless success
30
25
 
31
- def secret_token
32
- ENV['GITHUB_SECRET_TOKEN']
26
+ json runner.response
33
27
  end
34
28
  end
35
29
  end
@@ -1,5 +1,6 @@
1
1
  require 'sinatra/base'
2
2
  require "sinatra/reloader"
3
+ require "sinatra/json"
3
4
  require 'active_support/core_ext/hash/indifferent_access'
4
5
 
5
6
  module LoadRunner
@@ -25,5 +26,4 @@ module LoadRunner
25
26
  set :port, opts[:port] || '3000'
26
27
  end
27
28
  end
28
-
29
29
  end
@@ -0,0 +1,13 @@
1
+ module LoadRunner
2
+ module ServerHelper
3
+ def verify_signature(payload_body)
4
+ signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), secret_token, payload_body)
5
+ signature_match = Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE'])
6
+ return halt 401, "Bad Signature" unless signature_match
7
+ end
8
+
9
+ def secret_token
10
+ ENV['GITHUB_SECRET_TOKEN']
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module LoadRunner
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/loadrunner.rb CHANGED
@@ -1,6 +1,11 @@
1
1
  require 'load_runner/version'
2
2
  require 'load_runner/exceptions'
3
+
4
+ require 'load_runner/runner'
5
+ require 'load_runner/server_helper'
3
6
  require 'load_runner/server_base'
4
7
  require 'load_runner/server'
8
+
5
9
  require 'load_runner/client'
10
+
6
11
  require 'load_runner/command_line'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loadrunner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
@@ -164,8 +164,10 @@ files:
164
164
  - lib/load_runner/command_line.rb
165
165
  - lib/load_runner/docopt.txt
166
166
  - lib/load_runner/exceptions.rb
167
+ - lib/load_runner/runner.rb
167
168
  - lib/load_runner/server.rb
168
169
  - lib/load_runner/server_base.rb
170
+ - lib/load_runner/server_helper.rb
169
171
  - lib/load_runner/version.rb
170
172
  - lib/loadrunner.rb
171
173
  homepage: https://github.com/DannyBen/loadrunner