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 +4 -4
- data/README.md +13 -4
- data/lib/load_runner/client.rb +5 -9
- data/lib/load_runner/command_line.rb +63 -62
- data/lib/load_runner/docopt.txt +57 -55
- data/lib/load_runner/runner.rb +66 -0
- data/lib/load_runner/server.rb +11 -17
- data/lib/load_runner/server_base.rb +1 -1
- data/lib/load_runner/server_helper.rb +13 -0
- data/lib/load_runner/version.rb +1 -1
- data/lib/loadrunner.rb +5 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b9fd36357c745fed71eae60ca9b40ee65a4efa9
|
4
|
+
data.tar.gz: 6bae665acbdf5c16086c7c31f041f6a5e855c78b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
data/lib/load_runner/client.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
59
|
-
result
|
60
|
-
|
61
|
-
|
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
|
data/lib/load_runner/docopt.txt
CHANGED
@@ -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
|
29
|
-
*
|
30
|
-
*
|
31
|
-
*
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
loadrunner send localhost:3000 my_repo push
|
49
|
-
loadrunner send localhost:3000 my_repo push
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
data/lib/load_runner/server.rb
CHANGED
@@ -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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
22
|
-
|
23
|
-
end
|
21
|
+
runner = Runner.new opts
|
22
|
+
success = runner.execute
|
24
23
|
|
25
|
-
|
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
|
-
|
32
|
-
ENV['GITHUB_SECRET_TOKEN']
|
26
|
+
json runner.response
|
33
27
|
end
|
34
28
|
end
|
35
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
|
data/lib/load_runner/version.rb
CHANGED
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.
|
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
|