stubby 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.
- data/LICENSE +21 -0
- data/README.md +172 -111
- data/lib/stubby/cli/application.rb +1 -50
- data/lib/stubby/extensions/default.rb +72 -0
- data/lib/stubby/extensions/dns.rb +47 -30
- data/lib/stubby/extensions/http.rb +63 -26
- data/lib/stubby/extensions/smtp.rb +47 -0
- data/lib/stubby/kernel.rb +36 -0
- data/lib/stubby/master.rb +83 -42
- data/lib/stubby/process.rb +22 -0
- data/lib/stubby/registry.rb +16 -115
- data/lib/stubby/stub.rb +18 -6
- data/lib/stubby.rb +7 -0
- metadata +38 -2
@@ -26,8 +26,10 @@ module Extensions
|
|
26
26
|
super(:server_settings => server_settings)
|
27
27
|
end
|
28
28
|
|
29
|
-
def adapter(
|
30
|
-
|
29
|
+
def adapter(*names, &block)
|
30
|
+
names.each do |name|
|
31
|
+
adapters[name] = block
|
32
|
+
end
|
31
33
|
end
|
32
34
|
|
33
35
|
def adapters
|
@@ -39,15 +41,7 @@ module Extensions
|
|
39
41
|
set :static, false
|
40
42
|
|
41
43
|
adapter "http-redirect" do
|
42
|
-
|
43
|
-
url.path = request.path if url.path.to_s.empty?
|
44
|
-
redirect to(url.to_s)
|
45
|
-
end
|
46
|
-
|
47
|
-
adapter "https-redirect" do
|
48
|
-
url.scheme = "https"
|
49
|
-
url.path = request.path if url.path.to_s.empty?
|
50
|
-
redirect to(url.to_s)
|
44
|
+
redirect to(instruction_params["to"])
|
51
45
|
end
|
52
46
|
|
53
47
|
adapter "file" do
|
@@ -73,37 +67,54 @@ module Extensions
|
|
73
67
|
not_found(paths.join(",\n"))
|
74
68
|
end
|
75
69
|
|
76
|
-
adapter "
|
70
|
+
adapter "http-proxy" do
|
71
|
+
url.scheme = "http"
|
72
|
+
|
77
73
|
if url.path.empty?
|
78
74
|
# Proxy all requests, preserve incoming path
|
79
75
|
out = url.dup
|
80
76
|
out.path = request.path
|
81
77
|
request = HTTPI::Request.new
|
82
78
|
request.url = out.to_s
|
79
|
+
else
|
80
|
+
# Proxy to the given path
|
81
|
+
request = HTTPI::Request.new
|
82
|
+
request.url = url.to_s
|
83
|
+
end
|
83
84
|
|
84
|
-
|
85
|
+
response = HTTPI.get(request)
|
86
|
+
response.headers.delete "transfer-encoding"
|
87
|
+
response.headers.delete "connection"
|
85
88
|
|
86
|
-
|
87
|
-
|
89
|
+
status(response.code)
|
90
|
+
headers(response.headers)
|
91
|
+
body(response.body)
|
88
92
|
|
89
|
-
|
90
|
-
|
91
|
-
|
93
|
+
end
|
94
|
+
|
95
|
+
adapter "https-proxy" do
|
96
|
+
url.scheme = "https"
|
92
97
|
|
98
|
+
if url.path.empty?
|
99
|
+
# Proxy all requests, preserve incoming path
|
100
|
+
out = url.dup
|
101
|
+
out.path = request.path
|
102
|
+
request = HTTPI::Request.new
|
103
|
+
request.url = out.to_s
|
93
104
|
else
|
94
105
|
# Proxy to the given path
|
95
106
|
request = HTTPI::Request.new
|
96
107
|
request.url = url.to_s
|
108
|
+
end
|
97
109
|
|
98
|
-
|
110
|
+
response = HTTPI.get(request)
|
111
|
+
response.headers.delete "transfer-encoding"
|
112
|
+
response.headers.delete "connection"
|
99
113
|
|
100
|
-
|
101
|
-
|
114
|
+
status(response.code)
|
115
|
+
headers(response.headers)
|
116
|
+
body(response.body)
|
102
117
|
|
103
|
-
status(response.code)
|
104
|
-
headers(response.headers)
|
105
|
-
body(response.body)
|
106
|
-
end
|
107
118
|
end
|
108
119
|
|
109
120
|
get(//) do
|
@@ -126,10 +137,14 @@ module Extensions
|
|
126
137
|
end
|
127
138
|
|
128
139
|
def instruction
|
129
|
-
MultiJson.load(HTTPI.post("http://#{STUBBY_MASTER}:9000/rules/search.json",
|
140
|
+
@instruction ||= MultiJson.load(HTTPI.post("http://#{STUBBY_MASTER}:9000/rules/search.json",
|
130
141
|
trigger: "#{request.scheme}://#{request.host}").body)
|
131
142
|
end
|
132
143
|
|
144
|
+
def instruction_params
|
145
|
+
Rack::Utils.parse_nested_query url.query
|
146
|
+
end
|
147
|
+
|
133
148
|
def url
|
134
149
|
@url ||= URI.parse(instruction)
|
135
150
|
end
|
@@ -181,6 +196,24 @@ module Extensions
|
|
181
196
|
HTTPApp.run!(session)
|
182
197
|
end
|
183
198
|
|
199
|
+
# http://blah.com => localhost:3000
|
200
|
+
# =>
|
201
|
+
# http://blah.com => http-proxy://localhost:3000
|
202
|
+
def expand_rule(trigger, instruction, proto='http')
|
203
|
+
u = URI.parse(instruction)
|
204
|
+
|
205
|
+
(if u.scheme.nil?
|
206
|
+
{ trigger => "http-proxy://#{instruction}" }
|
207
|
+
elsif u.scheme == "http"
|
208
|
+
u.scheme = "http-proxy"
|
209
|
+
{ trigger => u.to_s }
|
210
|
+
else
|
211
|
+
{ trigger => instruction }
|
212
|
+
end).merge({
|
213
|
+
"#{trigger.gsub(proto + "://", "dns://")}/a" => "dns-a://#{STUBBY_MASTER}"
|
214
|
+
})
|
215
|
+
end
|
216
|
+
|
184
217
|
def stop!
|
185
218
|
HTTPApp.quit!
|
186
219
|
end
|
@@ -197,6 +230,10 @@ module Extensions
|
|
197
230
|
def stop!
|
198
231
|
HTTPSApp.quit!
|
199
232
|
end
|
233
|
+
|
234
|
+
def expand_rule(trigger, instruction)
|
235
|
+
super(trigger, instruction, "https")
|
236
|
+
end
|
200
237
|
end
|
201
238
|
end
|
202
239
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'mail_catcher'
|
2
|
+
|
3
|
+
module Extensions
|
4
|
+
module SMTP
|
5
|
+
class Server
|
6
|
+
def run!(session, options)
|
7
|
+
@process = Process.fork {
|
8
|
+
$0 = "stubby: [extension worker sub] Extensions::SMTP::Server"
|
9
|
+
|
10
|
+
sleep 2
|
11
|
+
|
12
|
+
HTTPI.post("http://#{STUBBY_MASTER}:9000/stubs/transient/activate.json",
|
13
|
+
options: MultiJson.dump(smtp_stub), key: "_smtp")
|
14
|
+
|
15
|
+
MailCatcher.run! smtp_ip: STUBBY_MASTER,
|
16
|
+
smtp_port: 25,
|
17
|
+
http_ip: STUBBY_MASTER,
|
18
|
+
http_port: 9001,
|
19
|
+
daemon: false
|
20
|
+
}
|
21
|
+
|
22
|
+
trap("INT", important: true){
|
23
|
+
stop!
|
24
|
+
}
|
25
|
+
|
26
|
+
sleep
|
27
|
+
end
|
28
|
+
|
29
|
+
def smtp_stub
|
30
|
+
{
|
31
|
+
"dns://outbox.stubby.dev/a" => "dns-a://#{STUBBY_MASTER}",
|
32
|
+
"http://outbox.stubby.dev" => "http://#{STUBBY_MASTER}:9001"
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def expand_rule(trigger, instruction)
|
37
|
+
{
|
38
|
+
"#{trigger.gsub("smtp://", "dns://")}/mx" => "dns-mx://#{STUBBY_MASTER}/?priority=10"
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def stop!
|
43
|
+
Process.shutdown(@process)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
$tracked = {}
|
2
|
+
|
3
|
+
module Kernel
|
4
|
+
alias _trap trap
|
5
|
+
|
6
|
+
def trap(*args, &block)
|
7
|
+
#puts "kernel::trap: #{args.inspect}\n---------------\n #{caller.join("\n")}\n\n"
|
8
|
+
|
9
|
+
if args.last.is_a? Hash
|
10
|
+
options = args.pop
|
11
|
+
else
|
12
|
+
options = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
if options[:important]
|
16
|
+
track(args.first, _trap(*args, &block))
|
17
|
+
else
|
18
|
+
if tracked?(args.first)
|
19
|
+
puts "kernel::trap: #{args.inspect} ignoring"
|
20
|
+
else
|
21
|
+
_trap(*args, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def track(signal, child_pid)
|
28
|
+
(($tracked ||= {})[Process.pid] ||= {})[signal] = child_pid
|
29
|
+
end
|
30
|
+
|
31
|
+
def tracked?(signal)
|
32
|
+
!!($tracked[Process.pid][signal])
|
33
|
+
rescue
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
data/lib/stubby/master.rb
CHANGED
@@ -5,8 +5,9 @@ module Stubby
|
|
5
5
|
class << self
|
6
6
|
attr_accessor :enabled_stubs
|
7
7
|
attr_accessor :registry
|
8
|
+
attr_accessor :master
|
8
9
|
attr_accessor :environments, :environment
|
9
|
-
|
10
|
+
|
10
11
|
def enabled_stubs
|
11
12
|
@enabled_stubs ||= {}
|
12
13
|
end
|
@@ -19,6 +20,8 @@ module Stubby
|
|
19
20
|
@enabled_stubs = nil
|
20
21
|
@environment = nil
|
21
22
|
@registry = nil
|
23
|
+
|
24
|
+
yield if block_given?
|
22
25
|
end
|
23
26
|
|
24
27
|
def env_settings
|
@@ -26,26 +29,50 @@ module Stubby
|
|
26
29
|
end
|
27
30
|
|
28
31
|
def environment=(name)
|
29
|
-
reset
|
30
|
-
|
32
|
+
reset do
|
33
|
+
@environment = name
|
31
34
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
+
(env_settings["dependencies"] || []).each do |depname, mode|
|
36
|
+
activate(depname, mode)
|
37
|
+
end
|
35
38
|
|
36
|
-
|
39
|
+
env_settings.delete("dependencies")
|
40
|
+
activate_transient(env_settings)
|
41
|
+
end
|
42
|
+
end
|
37
43
|
|
38
|
-
|
44
|
+
def activate(source, mode)
|
45
|
+
registry_item = RegistryItem.new(source)
|
46
|
+
self.enabled_stubs[source] = registry_item.stub(mode)
|
39
47
|
end
|
40
48
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
self.enabled_stubs[name] = registry_item.stub(mode)
|
49
|
+
def activate_transient(options, key="_")
|
50
|
+
puts "Transient activation #{options.inspect}, #{key}"
|
51
|
+
self.enabled_stubs[key] = TransientStub.new(options)
|
45
52
|
end
|
46
53
|
|
47
|
-
def
|
48
|
-
|
54
|
+
def expand_rules(options)
|
55
|
+
options.inject({}) do |new_opts, (trigger, instruction)|
|
56
|
+
if instruction.is_a? Hash # dependency modes
|
57
|
+
new_opts[trigger] = instruction
|
58
|
+
else
|
59
|
+
instruction = instruction.gsub("@", STUBBY_MASTER)
|
60
|
+
|
61
|
+
protocol, url = trigger.split("://")
|
62
|
+
url, protocol = protocol, :default if url.nil?
|
63
|
+
|
64
|
+
extension = master.extensions[protocol.to_sym]
|
65
|
+
|
66
|
+
if extension
|
67
|
+
new_opts.delete(trigger)
|
68
|
+
new_opts.merge!(extension.expand_rule(trigger, instruction))
|
69
|
+
else
|
70
|
+
raise "No `#{extension}` extension found for trigger: #{trigger}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
new_opts
|
75
|
+
end
|
49
76
|
end
|
50
77
|
end
|
51
78
|
|
@@ -87,7 +114,7 @@ module Stubby
|
|
87
114
|
end
|
88
115
|
|
89
116
|
post "/stubs/transient/activate.json" do
|
90
|
-
Api.activate_transient(params[:options])
|
117
|
+
Api.activate_transient(MultiJson.load(params[:options]), params[:key])
|
91
118
|
json status: "ok"
|
92
119
|
end
|
93
120
|
|
@@ -107,14 +134,17 @@ module Stubby
|
|
107
134
|
attr_accessor :extensions, :config
|
108
135
|
|
109
136
|
def initialize(environments)
|
110
|
-
@extensions =
|
111
|
-
Extensions::
|
112
|
-
Extensions::
|
113
|
-
Extensions::HTTP::
|
114
|
-
|
137
|
+
@extensions = {
|
138
|
+
default: Extensions::Default.new,
|
139
|
+
dns: Extensions::DNS::Server.new,
|
140
|
+
http: Extensions::HTTP::Server.new,
|
141
|
+
https: Extensions::HTTP::SSLServer.new,
|
142
|
+
smtp: Extensions::SMTP::Server.new
|
143
|
+
}
|
115
144
|
|
116
145
|
@config = Api
|
117
146
|
@config.environments = environments
|
147
|
+
@config.master = self
|
118
148
|
end
|
119
149
|
|
120
150
|
def environment=(environment)
|
@@ -122,50 +152,61 @@ module Stubby
|
|
122
152
|
end
|
123
153
|
|
124
154
|
def run!(options={})
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
puts "wait for #{process}"
|
130
|
-
Process.waitpid(process)
|
131
|
-
end
|
132
|
-
ensure
|
133
|
-
unassume_network_interface
|
155
|
+
run_network do
|
156
|
+
run_master do
|
157
|
+
run_extensions
|
158
|
+
end
|
134
159
|
end
|
135
160
|
end
|
136
161
|
|
137
162
|
private
|
138
|
-
def
|
163
|
+
def run_network
|
164
|
+
assume_network_interface
|
165
|
+
yield
|
166
|
+
ensure
|
167
|
+
unassume_network_interface
|
168
|
+
end
|
169
|
+
|
170
|
+
def run_master
|
171
|
+
$0 = "stubby: master"
|
172
|
+
|
173
|
+
Api.run! do |server|
|
174
|
+
yield
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def run_extensions
|
179
|
+
running.each do |process|
|
180
|
+
Process.waitpid(process)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def stop!
|
139
185
|
puts "Shutting down..."
|
140
186
|
|
187
|
+
Api.stop!
|
188
|
+
|
141
189
|
running.each do |process|
|
142
|
-
Process.
|
190
|
+
Process.shutdown(process)
|
143
191
|
end
|
144
192
|
|
145
193
|
puts "Bye."
|
146
194
|
end
|
147
195
|
|
148
196
|
def running
|
149
|
-
@running ||=
|
150
|
-
end
|
151
|
-
|
152
|
-
def run_master_api
|
153
|
-
Process.fork {
|
154
|
-
$0 = "stubby: [config api]"
|
155
|
-
Api.run!
|
156
|
-
}
|
197
|
+
@running ||= run_extensions
|
157
198
|
end
|
158
199
|
|
159
200
|
def run_extensions
|
160
|
-
@running_extensions ||= @extensions.collect { |plugin|
|
201
|
+
@running_extensions ||= @extensions.collect { |name, plugin|
|
161
202
|
Process.fork {
|
162
203
|
$0 = "stubby: [extension worker] #{plugin.class.name}"
|
163
204
|
plugin.run!(self, {})
|
164
205
|
}
|
165
206
|
}
|
166
207
|
|
167
|
-
trap("INT") {
|
168
|
-
|
208
|
+
trap("INT", important: true) {
|
209
|
+
stop!
|
169
210
|
}
|
170
211
|
|
171
212
|
return @running_extensions
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
3
|
+
module Process extend self
|
4
|
+
def running?(pid)
|
5
|
+
!!(kill(0, pid))
|
6
|
+
rescue
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def shutdown(pid, timeout=10, sig1="TERM", sig2="KILL")
|
11
|
+
puts "Shutting down: #{pid}"
|
12
|
+
|
13
|
+
kill(sig1, pid)
|
14
|
+
|
15
|
+
Timeout::timeout(timeout) do
|
16
|
+
sleep 1 and puts "." while running?(pid)
|
17
|
+
end
|
18
|
+
rescue Timeout::Error
|
19
|
+
kill(sig2, pid)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/lib/stubby/registry.rb
CHANGED
@@ -3,46 +3,32 @@ require 'httpi'
|
|
3
3
|
|
4
4
|
module Stubby
|
5
5
|
class RegistryItem
|
6
|
-
attr_accessor :name, :
|
6
|
+
attr_accessor :name, :source
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@source = source
|
12
|
-
@location = "~/.stubby/#{name}"
|
8
|
+
def initialize(source)
|
9
|
+
@source = URI.parse(source)
|
10
|
+
@name = @source.path
|
13
11
|
end
|
14
12
|
|
15
|
-
def
|
16
|
-
|
13
|
+
def install
|
14
|
+
`mkdir -p #{path}`
|
15
|
+
`cd #{path} && git clone #{@source} .`
|
17
16
|
end
|
18
17
|
|
19
|
-
def
|
20
|
-
|
21
|
-
uninstall
|
22
|
-
`ln -s #{source} ~/.stubby/#{name}`
|
23
|
-
else
|
24
|
-
`mkdir -p ~/.stubby`
|
25
|
-
download source, "~/.stubby/#{name}.zip"
|
26
|
-
`curl #{source} > ~/.stubby/#{name}.zip`
|
27
|
-
`unzip -d ~/.stubby/ #{source}`
|
28
|
-
`rm ~/.stubby/#{name}.zip`
|
29
|
-
end
|
18
|
+
def path
|
19
|
+
"~/.stubby/#{@source.path}"
|
30
20
|
end
|
31
21
|
|
32
22
|
def uninstall
|
33
|
-
`rm -rf ~/.stubby/#{
|
23
|
+
`rm -rf ~/.stubby/#{@source.path}`
|
34
24
|
end
|
35
25
|
|
36
26
|
def installed?
|
37
|
-
File.exists?
|
38
|
-
end
|
39
|
-
|
40
|
-
def download(source, destination)
|
41
|
-
`curl #{source} #{destination}`
|
27
|
+
File.exists? path
|
42
28
|
end
|
43
29
|
|
44
30
|
def config
|
45
|
-
|
31
|
+
"~/.stubby/#{@source.path}/stubby.json"
|
46
32
|
end
|
47
33
|
|
48
34
|
def stub(target=nil)
|
@@ -52,97 +38,12 @@ module Stubby
|
|
52
38
|
end
|
53
39
|
|
54
40
|
class Registry
|
55
|
-
def
|
56
|
-
|
57
|
-
[name, versions.collect { |version, source|
|
58
|
-
RegistryItem.new name, version, source
|
59
|
-
}]
|
60
|
-
}]
|
61
|
-
end
|
62
|
-
|
63
|
-
def versions(name)
|
64
|
-
if index[name]
|
65
|
-
index[name].sort { |x, y|
|
66
|
-
Gem::Version.new(y.version) <=> Gem::Version.new(x.version)
|
67
|
-
}
|
68
|
-
else
|
69
|
-
[]
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def version(name, version)
|
74
|
-
version = version.gsub("v", "")
|
75
|
-
|
76
|
-
index[name].detect { |stub|
|
77
|
-
stub.version == version
|
78
|
-
}
|
79
|
-
end
|
80
|
-
|
81
|
-
def latest(name)
|
82
|
-
versions(name).first
|
83
|
-
end
|
84
|
-
|
85
|
-
def install(name, opts={})
|
86
|
-
source = opts[:source]
|
87
|
-
v = opts[:version]
|
88
|
-
|
89
|
-
if name =~ /https?:\/\//
|
90
|
-
source = name
|
91
|
-
name = File.basename(name).split(".").first
|
92
|
-
RegistryItem.new(name, "v1.0.0", source).install
|
93
|
-
else
|
94
|
-
stub = v.nil? ? latest(name) : version(name, v)
|
95
|
-
|
96
|
-
if stub
|
97
|
-
stub.install
|
98
|
-
elsif source
|
99
|
-
add_new_source(name, source, v)
|
100
|
-
else
|
101
|
-
puts "[ERROR] Cannot find #{name} at #{v}"
|
102
|
-
end
|
103
|
-
end
|
41
|
+
def install(source)
|
42
|
+
RegistryItem.new(source).install
|
104
43
|
end
|
105
44
|
|
106
|
-
def uninstall(
|
107
|
-
|
108
|
-
# version, but we have a convention of using a ~/.stubby/NAME
|
109
|
-
# location, so this shouldn't be a problem for the POC
|
110
|
-
if name =~ /https?:\/\//
|
111
|
-
name = File.basename(name).split(".").first
|
112
|
-
end
|
113
|
-
|
114
|
-
latest(name).uninstall
|
115
|
-
end
|
116
|
-
|
117
|
-
|
118
|
-
private
|
119
|
-
|
120
|
-
def remote_index
|
121
|
-
response = HTTPI.get("http://github.com/jkassemi/stubby/index.json")
|
122
|
-
MultiJson.load(response.body) if response.code == 200
|
123
|
-
end
|
124
|
-
|
125
|
-
def local_index
|
126
|
-
MultiJson.load(File.read(File.expand_path(File.join('~', '.stubby', "index.json"))))
|
127
|
-
rescue
|
128
|
-
{}
|
129
|
-
end
|
130
|
-
|
131
|
-
def write_local_index(&block)
|
132
|
-
File.open File.expand_path(File.join('~', '.stubby', "index.json")), "w", &block
|
133
|
-
end
|
134
|
-
|
135
|
-
def add_new_source(name, source, v=nil)
|
136
|
-
version = v.nil? ? 'v0.0.1' : v
|
137
|
-
|
138
|
-
item = RegistryItem.new name, version, source
|
139
|
-
item.install
|
140
|
-
|
141
|
-
current_index = local_index
|
142
|
-
|
143
|
-
write_local_index do |index|
|
144
|
-
index.puts MultiJson.dump(local_index.merge({item.name => {item.version => item.location}}))
|
145
|
-
end
|
45
|
+
def uninstall(source)
|
46
|
+
RegistryItem.new(source).uninstall
|
146
47
|
end
|
147
48
|
end
|
148
49
|
end
|
data/lib/stubby/stub.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'pry'
|
2
|
-
|
3
1
|
module Stubby
|
4
2
|
class Stub
|
5
3
|
attr_accessor :target, :path, :modes
|
@@ -12,8 +10,11 @@ module Stubby
|
|
12
10
|
|
13
11
|
def modes
|
14
12
|
@modes ||= MultiJson.load(File.read(path))
|
15
|
-
rescue
|
16
|
-
|
13
|
+
rescue => e
|
14
|
+
if File.exists?(path)
|
15
|
+
puts "[INFO] Problem parsing #{path}"
|
16
|
+
raise e
|
17
|
+
end
|
17
18
|
end
|
18
19
|
|
19
20
|
def path=(v)
|
@@ -25,8 +26,14 @@ module Stubby
|
|
25
26
|
@path = File.expand_path(v)
|
26
27
|
end
|
27
28
|
|
29
|
+
def target=(environment)
|
30
|
+
@environment = environment
|
31
|
+
@options = nil
|
32
|
+
options
|
33
|
+
end
|
34
|
+
|
28
35
|
def options
|
29
|
-
modes[
|
36
|
+
@options ||= expand(modes[@environment] || {})
|
30
37
|
end
|
31
38
|
|
32
39
|
def search(trigger)
|
@@ -38,11 +45,16 @@ module Stubby
|
|
38
45
|
|
39
46
|
return nil
|
40
47
|
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def expand(options)
|
51
|
+
Stubby::Api.expand_rules(options)
|
52
|
+
end
|
41
53
|
end
|
42
54
|
|
43
55
|
class TransientStub < Stub
|
44
56
|
def initialize(options)
|
45
|
-
@options = options
|
57
|
+
@options = expand(options)
|
46
58
|
end
|
47
59
|
|
48
60
|
def modes
|
data/lib/stubby.rb
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
STUBBY_MASTER="172.16.123.1"
|
2
2
|
|
3
|
+
require 'oj'
|
3
4
|
require 'multi_json'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'bundler/setup'
|
4
7
|
require 'stubby/extensions/dns/osx'
|
5
8
|
require 'stubby/extensions/dns'
|
6
9
|
require 'stubby/extensions/http'
|
10
|
+
require 'stubby/extensions/smtp'
|
7
11
|
require 'stubby/extensions/reload'
|
12
|
+
require 'stubby/extensions/default'
|
8
13
|
require 'stubby/registry'
|
9
14
|
require 'stubby/stub'
|
10
15
|
require 'stubby/master'
|
16
|
+
require 'stubby/process'
|
17
|
+
require 'stubby/kernel'
|