loadrunner 0.0.4 → 0.1.0
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 +11 -2
- data/lib/load_runner/client.rb +9 -0
- data/lib/load_runner/command_line.rb +29 -4
- data/lib/load_runner/docopt.txt +22 -0
- data/lib/load_runner/git_hub_api.rb +48 -0
- data/lib/load_runner/runner.rb +8 -0
- data/lib/load_runner/server.rb +1 -0
- data/lib/load_runner/server_helper.rb +0 -18
- data/lib/load_runner/signature_helper.rb +21 -0
- data/lib/load_runner/version.rb +1 -1
- data/lib/loadrunner.rb +4 -2
- metadata +21 -7
- data/lib/load_runner/_server.rb +0 -44
- data/lib/load_runner/exceptions.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45e2aa0edf131bb75fdac7ac306131ba87791958
|
4
|
+
data.tar.gz: b6380a094f0d73e15e3922b3b2caea0e90db56b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8775a42b092fb08485fdf72525ed2dcaa48f59f908f593c4ba8859a22739abdb671b0d3edfc92f3cc086198d875cccc5bc8322190f2202998846182506667be
|
7
|
+
data.tar.gz: 3fe722e065dab62c742d337c006b2cd2ccea46920cd2a70692a645250d721d609b47574e5af23c1d0d50d040df22cb5afa64e3c760384eb04e397430a4ed65c5
|
data/README.md
CHANGED
@@ -8,13 +8,16 @@ LoadRunner - GitHub Webhook Server and Event Simulator
|
|
8
8
|
|
9
9
|
---
|
10
10
|
|
11
|
-
LoadRunner is a
|
11
|
+
LoadRunner is a multi-purpose utility for working with GitHub webhooks and
|
12
|
+
statuses.
|
12
13
|
|
13
14
|
It provides these features:
|
14
15
|
|
15
16
|
- A webserver that responds to GitHub webhook events and can run any
|
16
17
|
arbitrary script writtn in any language.
|
17
|
-
- A command line utility for testing your webhook server configuration
|
18
|
+
- A command line utility for testing your webhook server configuration by
|
19
|
+
sending simulated events.
|
20
|
+
- A command line utility for sending status updates to pull requests.
|
18
21
|
|
19
22
|
---
|
20
23
|
|
@@ -43,3 +46,9 @@ Getting Started
|
|
43
46
|
$ cat output.txt
|
44
47
|
|
45
48
|
|
49
|
+
For more options, see the [documentation][1] or run
|
50
|
+
|
51
|
+
$ loadrunner --help
|
52
|
+
|
53
|
+
|
54
|
+
[1]: http://www.rubydoc.info/gems/loadrunner
|
data/lib/load_runner/client.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'httparty'
|
2
2
|
|
3
3
|
module LoadRunner
|
4
|
+
|
5
|
+
# Send simulated GitHub events to any webhook server
|
4
6
|
class Client
|
5
7
|
include HTTParty
|
6
8
|
attr_accessor :secret_token, :base_url, :payload
|
@@ -11,11 +13,18 @@ module LoadRunner
|
|
11
13
|
self.class.base_uri base_url
|
12
14
|
end
|
13
15
|
|
16
|
+
# Send a simulated event using a shorthand syntax. opts can contain
|
17
|
+
# any of these:
|
18
|
+
# * +repo+: repository name
|
19
|
+
# * +ref+: ref ID (for example +ref/heads/branchname+)
|
20
|
+
# * +branch+: branch name
|
21
|
+
# * +tag+: tag name
|
14
22
|
def send(event=:push, opts={})
|
15
23
|
payload = build_payload opts
|
16
24
|
send_payload event, payload
|
17
25
|
end
|
18
26
|
|
27
|
+
# Send a simulated event. Payload can be a hash or a JSON string.
|
19
28
|
def send_payload(event, payload)
|
20
29
|
@payload = payload.is_a?(String) ? payload : payload.to_json
|
21
30
|
headers = headers event
|
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
require 'docopt'
|
3
|
-
require '
|
3
|
+
require 'colsole'
|
4
4
|
|
5
5
|
module LoadRunner
|
6
6
|
|
7
7
|
# Handles the command line interface
|
8
8
|
class CommandLine
|
9
9
|
include Singleton
|
10
|
+
include Colsole
|
10
11
|
|
11
12
|
attr_reader :args
|
12
13
|
|
@@ -28,15 +29,14 @@ module LoadRunner
|
|
28
29
|
# delegate action to other, more specialized methods.
|
29
30
|
def handle
|
30
31
|
return send if args['send']
|
32
|
+
return status if args['status']
|
31
33
|
return server if args['server']
|
32
34
|
end
|
33
35
|
|
34
36
|
def send
|
35
37
|
client = Client.new client_opts
|
36
38
|
response = client.send args['EVENT'], payload_opts
|
37
|
-
|
38
|
-
puts "Reesponse code: #{response.code}" if response.respond_to? :code
|
39
|
-
ap response
|
39
|
+
show response
|
40
40
|
end
|
41
41
|
|
42
42
|
def server
|
@@ -44,6 +44,20 @@ module LoadRunner
|
|
44
44
|
Server.run!
|
45
45
|
end
|
46
46
|
|
47
|
+
def status
|
48
|
+
api = GitHubAPI.new
|
49
|
+
opts = {
|
50
|
+
state: args['STATE'],
|
51
|
+
target_url: args['--url'],
|
52
|
+
context: args['--context'],
|
53
|
+
description: args['--desc']
|
54
|
+
}
|
55
|
+
|
56
|
+
response = api.status args['REPO'], args['SHA'], opts
|
57
|
+
|
58
|
+
show response
|
59
|
+
end
|
60
|
+
|
47
61
|
def client_opts
|
48
62
|
{
|
49
63
|
base_url: args['URL'],
|
@@ -65,5 +79,16 @@ module LoadRunner
|
|
65
79
|
result[:ref] = ref
|
66
80
|
result
|
67
81
|
end
|
82
|
+
|
83
|
+
# Print the response json to stdout, and the response code to stderr.
|
84
|
+
def show(response)
|
85
|
+
puts JSON.pretty_generate response
|
86
|
+
|
87
|
+
if response.respond_to? :code
|
88
|
+
code = response.code.to_s
|
89
|
+
color = code =~ /^2\d\d/ ? :txtgrn : :txtred
|
90
|
+
say! "!#{color}!Response Code: #{code}"
|
91
|
+
end
|
92
|
+
end
|
68
93
|
end
|
69
94
|
end
|
data/lib/load_runner/docopt.txt
CHANGED
@@ -3,6 +3,7 @@ LoadRunner
|
|
3
3
|
Usage:
|
4
4
|
loadrunner server [--port N --bind IP]
|
5
5
|
loadrunner send URL REPO EVENT [REF]
|
6
|
+
loadrunner status REPO SHA STATE [--context TEXT --desc TEXT --url URL]
|
6
7
|
loadrunner (-h|--help|--version)
|
7
8
|
|
8
9
|
Commands:
|
@@ -12,6 +13,9 @@ Commands:
|
|
12
13
|
send
|
13
14
|
Send a simulated GitHub event to a webhook server.
|
14
15
|
|
16
|
+
status
|
17
|
+
Send status update to a github pull request.
|
18
|
+
|
15
19
|
Parameters:
|
16
20
|
URL
|
17
21
|
The URL of the webhook server. This server should have a /payload
|
@@ -31,6 +35,12 @@ Parameters:
|
|
31
35
|
* branch=branch_name
|
32
36
|
* raw ref string (for example refs/tags/tagname)
|
33
37
|
|
38
|
+
SHA
|
39
|
+
Commit SHA string.
|
40
|
+
|
41
|
+
STATE
|
42
|
+
One of 'success', 'pending', 'error', 'failure'
|
43
|
+
|
34
44
|
Options:
|
35
45
|
--port N
|
36
46
|
Set the port of the webhook server.
|
@@ -38,6 +48,14 @@ Options:
|
|
38
48
|
--bind IP
|
39
49
|
Set the listening address of the webhook server.
|
40
50
|
|
51
|
+
--context TEXT
|
52
|
+
Indicate what service is sending this status.
|
53
|
+
|
54
|
+
--url URL
|
55
|
+
The target URL to associate with this status.
|
56
|
+
|
57
|
+
--desc TEXT
|
58
|
+
A short description of the status.
|
41
59
|
|
42
60
|
Environment Variables:
|
43
61
|
GITHUB_SECRET_TOKEN=y0urAP1k3y
|
@@ -54,4 +72,8 @@ Examples:
|
|
54
72
|
loadrunner server
|
55
73
|
loadrunner server --bind 0.0.0.0 --port 3000
|
56
74
|
|
75
|
+
# Send a status
|
76
|
+
loadrunner status me/myrepo 018b0ac... pending
|
77
|
+
loadrunner status me/myrepo 018b0ac... success --context "My CI"
|
78
|
+
|
57
79
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module LoadRunner
|
4
|
+
# Communicate with GitHub
|
5
|
+
class GitHubAPI
|
6
|
+
include HTTParty
|
7
|
+
|
8
|
+
base_uri 'https://api.github.com'
|
9
|
+
|
10
|
+
# Send status update to a pull request. Supported options:
|
11
|
+
# * +state+: :pending, :success, :failure or :error
|
12
|
+
# * +context+: any string
|
13
|
+
# * +description+: any string
|
14
|
+
# * +target_url+: any valid URL
|
15
|
+
def status(repo, sha, opts={})
|
16
|
+
# sha = '018b0ac55dbf0d8e1eef6df46e04dfef8bea9b96'
|
17
|
+
message = {
|
18
|
+
body: {
|
19
|
+
state: (opts[:state] ? opts[:state].to_s : 'pending'),
|
20
|
+
context: (opts[:context] || 'LoadRunner'),
|
21
|
+
description: opts[:description],
|
22
|
+
target_url: opts[:target_url]
|
23
|
+
}.to_json
|
24
|
+
}
|
25
|
+
self.class.post "/repos/#{repo}/statuses/#{sha}", message.merge(request_options)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def request_options
|
31
|
+
{
|
32
|
+
headers: headers
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def headers
|
37
|
+
{
|
38
|
+
"Authorization" => "token #{secret_token}",
|
39
|
+
"User-Agent" => "LoadRunner"
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def secret_token
|
44
|
+
ENV['GITHUB_ACCESS_TOKEN']
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
data/lib/load_runner/runner.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module LoadRunner
|
2
2
|
|
3
|
+
# Executes event handlers
|
3
4
|
class Runner
|
4
5
|
attr_reader :opts
|
5
6
|
attr_accessor :response
|
@@ -8,6 +9,8 @@ module LoadRunner
|
|
8
9
|
@opts = opts
|
9
10
|
end
|
10
11
|
|
12
|
+
# Execute all matching handlers based on the input payload. This method
|
13
|
+
# populates the `#response` object, and returns true on success.
|
11
14
|
def execute
|
12
15
|
set_environment_vars
|
13
16
|
|
@@ -35,6 +38,7 @@ module LoadRunner
|
|
35
38
|
|
36
39
|
private
|
37
40
|
|
41
|
+
# Find all handlers that fit the payload meta data.
|
38
42
|
def locate_handlers
|
39
43
|
handlers = []
|
40
44
|
|
@@ -45,17 +49,21 @@ module LoadRunner
|
|
45
49
|
handlers
|
46
50
|
end
|
47
51
|
|
52
|
+
# Execute all handlers.
|
48
53
|
def execute_all(handlers)
|
49
54
|
handlers.each do |handler|
|
50
55
|
run_bg handler
|
51
56
|
end
|
52
57
|
end
|
53
58
|
|
59
|
+
# Run a command in the background.
|
54
60
|
def run_bg(cmd)
|
55
61
|
job = fork { exec cmd }
|
56
62
|
Process.detach job
|
57
63
|
end
|
58
64
|
|
65
|
+
# Set all payload meta data as environment variables so that the
|
66
|
+
# handler can use them.
|
59
67
|
def set_environment_vars
|
60
68
|
opts.each { |key, value| ENV[key.to_s.upcase] = value }
|
61
69
|
end
|
data/lib/load_runner/server.rb
CHANGED
@@ -1,23 +1,5 @@
|
|
1
1
|
module LoadRunner
|
2
2
|
module ServerHelper
|
3
|
-
def verify_signature(payload_body, signature)
|
4
|
-
return :no_client if secret_token and !signature
|
5
|
-
return :no_server if !secret_token and signature
|
6
|
-
return :ok if !secret_token and !signature
|
7
|
-
|
8
|
-
expected_signature = generate_signature payload_body
|
9
|
-
signature_match = Rack::Utils.secure_compare(expected_signature, signature)
|
10
|
-
return signature_match ? :ok : :mismatch
|
11
|
-
end
|
12
|
-
|
13
|
-
def generate_signature(payload_body)
|
14
|
-
'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), secret_token, payload_body)
|
15
|
-
end
|
16
|
-
|
17
|
-
def secret_token
|
18
|
-
ENV['GITHUB_SECRET_TOKEN']
|
19
|
-
end
|
20
|
-
|
21
3
|
def halt_messages
|
22
4
|
{
|
23
5
|
no_client: "Client did not send a signature",
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module LoadRunner
|
2
|
+
module SignatureHelper
|
3
|
+
def verify_signature(payload_body, signature)
|
4
|
+
return :no_client if secret_token and !signature
|
5
|
+
return :no_server if !secret_token and signature
|
6
|
+
return :ok if !secret_token and !signature
|
7
|
+
|
8
|
+
expected_signature = generate_signature payload_body
|
9
|
+
signature_match = Rack::Utils.secure_compare(expected_signature, signature)
|
10
|
+
return signature_match ? :ok : :mismatch
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_signature(payload_body)
|
14
|
+
'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), secret_token, payload_body)
|
15
|
+
end
|
16
|
+
|
17
|
+
def secret_token
|
18
|
+
ENV['GITHUB_SECRET_TOKEN']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/load_runner/version.rb
CHANGED
data/lib/loadrunner.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'load_runner/version'
|
2
|
-
require 'load_runner/exceptions'
|
3
2
|
|
4
|
-
require 'load_runner/
|
3
|
+
require 'load_runner/signature_helper'
|
5
4
|
require 'load_runner/server_helper'
|
5
|
+
require 'load_runner/git_hub_api'
|
6
|
+
|
7
|
+
require 'load_runner/runner'
|
6
8
|
require 'load_runner/server_base'
|
7
9
|
require 'load_runner/server'
|
8
10
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loadrunner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Danny Ben Shitrit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -67,19 +67,19 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '5.1'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: colsole
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0.5'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '0.5'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: runfile
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -178,6 +178,20 @@ dependencies:
|
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0.7'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: yard
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0.9'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0.9'
|
181
195
|
description: Run your GitHub webhook server and Send simulated github events
|
182
196
|
email: db@dannyben.com
|
183
197
|
executables:
|
@@ -187,15 +201,15 @@ extra_rdoc_files: []
|
|
187
201
|
files:
|
188
202
|
- README.md
|
189
203
|
- bin/loadrunner
|
190
|
-
- lib/load_runner/_server.rb
|
191
204
|
- lib/load_runner/client.rb
|
192
205
|
- lib/load_runner/command_line.rb
|
193
206
|
- lib/load_runner/docopt.txt
|
194
|
-
- lib/load_runner/
|
207
|
+
- lib/load_runner/git_hub_api.rb
|
195
208
|
- lib/load_runner/runner.rb
|
196
209
|
- lib/load_runner/server.rb
|
197
210
|
- lib/load_runner/server_base.rb
|
198
211
|
- lib/load_runner/server_helper.rb
|
212
|
+
- lib/load_runner/signature_helper.rb
|
199
213
|
- lib/load_runner/version.rb
|
200
214
|
- lib/loadrunner.rb
|
201
215
|
homepage: https://github.com/DannyBen/loadrunner
|
data/lib/load_runner/_server.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'sinatra'
|
2
|
-
require "sinatra/reloader" if development?
|
3
|
-
require 'json'
|
4
|
-
require 'active_support/core_ext/hash/indifferent_access'
|
5
|
-
require 'byebug'
|
6
|
-
|
7
|
-
set port: 3000
|
8
|
-
set bind: '0.0.0.0'
|
9
|
-
|
10
|
-
ENV['SECRET_TOKEN'] = '123'
|
11
|
-
|
12
|
-
post '/payload' do
|
13
|
-
request.env['HTTP_X_HUB_SIGNATURE']
|
14
|
-
|
15
|
-
request.body.rewind
|
16
|
-
payload_body = request.body.read
|
17
|
-
|
18
|
-
verify_signature payload_body
|
19
|
-
|
20
|
-
push = ActiveSupport::HashWithIndifferentAccess.new JSON.parse payload_body
|
21
|
-
|
22
|
-
branch = push[:ref] =~ /refs\/head/ ? push[:ref].sub('refs/heads/', '') : nil;
|
23
|
-
tag = push[:ref] =~ /refs\/tags/ ? push[:ref].sub('refs/tags/', '') : nil;
|
24
|
-
|
25
|
-
result = {
|
26
|
-
event: request.env['HTTP_X_GITHUB_EVENT'],
|
27
|
-
repo: push[:repository][:name],
|
28
|
-
branch: branch,
|
29
|
-
tag: tag
|
30
|
-
# payload: push
|
31
|
-
}
|
32
|
-
|
33
|
-
result.inspect
|
34
|
-
end
|
35
|
-
|
36
|
-
post '/debug' do
|
37
|
-
request.env['HTTP_X_HUB_SIGNATURE']
|
38
|
-
end
|
39
|
-
|
40
|
-
def verify_signature(payload_body)
|
41
|
-
signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), ENV['SECRET_TOKEN'], payload_body)
|
42
|
-
signature_match = Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE'])
|
43
|
-
return halt 401, "Bad Signature" unless signature_match
|
44
|
-
end
|