landrush 0.19.0 → 1.0.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/.config/cucumber.yml +7 -0
- data/.gitignore +6 -4
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +32 -259
- data/CHANGELOG.md +8 -1
- data/CONTRIBUTING.md +11 -10
- data/Gemfile +7 -4
- data/Gemfile.lock +178 -0
- data/README.md +148 -35
- data/Rakefile +18 -0
- data/doc/img/advanced-tcp-properties.png +0 -0
- data/doc/img/network-connections.png +0 -0
- data/features/dns_resolution.feature +26 -0
- data/features/step_definitions/dns.rb +19 -0
- data/features/support/env.rb +16 -0
- data/landrush.gemspec +1 -2
- data/lib/landrush.rb +0 -12
- data/lib/landrush/action/common.rb +5 -5
- data/lib/landrush/action/redirect_dns.rb +1 -1
- data/lib/landrush/action/setup.rb +9 -14
- data/lib/landrush/action/teardown.rb +5 -1
- data/lib/landrush/cap/debian/install_iptables.rb +2 -2
- data/lib/landrush/cap/linux/add_iptables_rule.rb +0 -1
- data/lib/landrush/cap/linux/redirect_dns.rb +0 -1
- data/lib/landrush/cap/redhat/install_iptables.rb +2 -2
- data/lib/landrush/command.rb +8 -10
- data/lib/landrush/config.rb +1 -1
- data/lib/landrush/dependent_vms.rb +2 -2
- data/lib/landrush/os.rb +19 -0
- data/lib/landrush/plugin.rb +4 -4
- data/lib/landrush/resolver_config.rb +1 -5
- data/lib/landrush/server.rb +187 -25
- data/lib/landrush/store.rb +12 -4
- data/lib/landrush/version.rb +1 -1
- data/test/landrush/action/setup_test.rb +14 -9
- data/test/landrush/action/teardown_test.rb +8 -9
- data/test/landrush/cap/linux/configured_dns_servers_test.rb +2 -2
- data/test/landrush/cap/linux/read_host_visible_ip_address_test.rb +5 -7
- data/test/landrush/cap/linux/redirect_dns_test.rb +1 -1
- data/test/landrush/resolver_config_test.rb +0 -2
- data/test/landrush/server_test.rb +18 -12
- data/test/landrush/store_test.rb +7 -6
- data/test/support/clear_dependent_vms.rb +4 -2
- data/test/support/create_fake_working_dir.rb +19 -0
- data/test/support/delete_fake_working_dir.rb +12 -0
- data/test/support/fake_resolver_config.rb +8 -3
- data/test/support/test_server_daemon.rb +20 -15
- data/test/test_helper.rb +31 -22
- metadata +26 -28
- data/lib/ext/rexec.rb +0 -10
- data/test/support/fake_working_dir.rb +0 -16
data/lib/landrush/store.rb
CHANGED
@@ -1,11 +1,19 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'json'
|
3
|
+
|
1
4
|
module Landrush
|
2
5
|
class Store
|
3
6
|
def self.hosts
|
4
|
-
@hosts ||= new(
|
7
|
+
@hosts ||= new(Server.working_dir.join('hosts.json'))
|
5
8
|
end
|
6
9
|
|
7
10
|
def self.config
|
8
|
-
@config ||= new(
|
11
|
+
@config ||= new(Server.working_dir.join('config.json'))
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.reset
|
15
|
+
@config = nil
|
16
|
+
@hosts = nil
|
9
17
|
end
|
10
18
|
|
11
19
|
attr_accessor :backing_file
|
@@ -28,14 +36,14 @@ module Landrush
|
|
28
36
|
|
29
37
|
def has?(key, value = nil)
|
30
38
|
if value.nil?
|
31
|
-
current_config.
|
39
|
+
current_config.key? key
|
32
40
|
else
|
33
41
|
current_config[key] == value
|
34
42
|
end
|
35
43
|
end
|
36
44
|
|
37
45
|
def find(search)
|
38
|
-
search =
|
46
|
+
search = IPAddr.new(search).reverse if (IPAddr.new(search) rescue nil)
|
39
47
|
current_config.keys.detect do |key|
|
40
48
|
key.casecmp(search) == 0 ||
|
41
49
|
search =~ /#{key}$/i ||
|
data/lib/landrush/version.rb
CHANGED
@@ -5,12 +5,17 @@ require 'landrush/action/setup'
|
|
5
5
|
module Landrush
|
6
6
|
module Action
|
7
7
|
describe Setup do
|
8
|
-
before
|
9
|
-
|
8
|
+
before do
|
9
|
+
ResolverConfig.sudo = ''
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
ResolverConfig.sudo = 'sudo'
|
14
|
+
end
|
10
15
|
|
11
16
|
it "calls the next app in the chain" do
|
12
17
|
env = fake_environment
|
13
|
-
app =
|
18
|
+
app = -> (e) { e[:called] = true }
|
14
19
|
setup = Setup.new(app, nil)
|
15
20
|
|
16
21
|
setup.call(env)
|
@@ -19,7 +24,7 @@ module Landrush
|
|
19
24
|
end
|
20
25
|
|
21
26
|
it "records the booting host as a dependent VM" do
|
22
|
-
app =
|
27
|
+
app = proc {}
|
23
28
|
setup = Setup.new(app, nil)
|
24
29
|
env = fake_environment
|
25
30
|
|
@@ -29,7 +34,7 @@ module Landrush
|
|
29
34
|
end
|
30
35
|
|
31
36
|
it "starts the landrush server if it's not already started" do
|
32
|
-
app =
|
37
|
+
app = proc {}
|
33
38
|
setup = Setup.new(app, nil)
|
34
39
|
env = fake_environment
|
35
40
|
|
@@ -39,7 +44,7 @@ module Landrush
|
|
39
44
|
end
|
40
45
|
|
41
46
|
it "does not attempt to start the server if it's already up" do
|
42
|
-
app =
|
47
|
+
app = proc {}
|
43
48
|
setup = Setup.new(app, nil)
|
44
49
|
env = fake_environment
|
45
50
|
|
@@ -53,7 +58,7 @@ module Landrush
|
|
53
58
|
end
|
54
59
|
|
55
60
|
it "does nothing if it is not enabled via config" do
|
56
|
-
app =
|
61
|
+
app = proc {}
|
57
62
|
setup = Setup.new(app, nil)
|
58
63
|
env = fake_environment
|
59
64
|
|
@@ -65,7 +70,7 @@ module Landrush
|
|
65
70
|
|
66
71
|
describe 'after boot' do
|
67
72
|
it "stores the machine's hostname => ip address" do
|
68
|
-
app =
|
73
|
+
app = proc {}
|
69
74
|
setup = Setup.new(app, nil)
|
70
75
|
env = fake_environment
|
71
76
|
|
@@ -75,7 +80,7 @@ module Landrush
|
|
75
80
|
end
|
76
81
|
|
77
82
|
it "does nothing if it is not enabled via config" do
|
78
|
-
app =
|
83
|
+
app = proc {}
|
79
84
|
setup = Setup.new(app, nil)
|
80
85
|
env = fake_environment(enabled: false)
|
81
86
|
|
@@ -7,7 +7,7 @@ module Landrush
|
|
7
7
|
describe Teardown do
|
8
8
|
it "calls the next app in the chain" do
|
9
9
|
env = fake_environment
|
10
|
-
app =
|
10
|
+
app = -> (e) { e[:called] = true }
|
11
11
|
teardown = Teardown.new(app, nil)
|
12
12
|
|
13
13
|
teardown.call(env)
|
@@ -16,7 +16,7 @@ module Landrush
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "clears the machine's hostname => ip address" do
|
19
|
-
app =
|
19
|
+
app = proc {}
|
20
20
|
teardown = Teardown.new(app, nil)
|
21
21
|
env = fake_environment
|
22
22
|
|
@@ -27,7 +27,7 @@ module Landrush
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it "removes the machine as a dependent VM" do
|
30
|
-
app =
|
30
|
+
app = proc {}
|
31
31
|
teardown = Teardown.new(app, nil)
|
32
32
|
env = fake_environment
|
33
33
|
|
@@ -38,7 +38,7 @@ module Landrush
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it "stops the landrush server when there are no dependent machines left" do
|
41
|
-
app =
|
41
|
+
app = proc {}
|
42
42
|
teardown = Teardown.new(app, nil)
|
43
43
|
env = fake_environment
|
44
44
|
|
@@ -49,7 +49,7 @@ module Landrush
|
|
49
49
|
end
|
50
50
|
|
51
51
|
it "leaves the landrush server when other dependent vms exist" do
|
52
|
-
app =
|
52
|
+
app = proc {}
|
53
53
|
teardown = Teardown.new(app, nil)
|
54
54
|
env = fake_environment
|
55
55
|
DependentVMs.add('otherhost.vagrant.test')
|
@@ -61,7 +61,7 @@ module Landrush
|
|
61
61
|
end
|
62
62
|
|
63
63
|
it "leaves static entries when other dependent vms exist" do
|
64
|
-
app =
|
64
|
+
app = proc {}
|
65
65
|
teardown = Teardown.new(app, nil)
|
66
66
|
env = fake_environment
|
67
67
|
DependentVMs.add('otherhost.vagrant.test')
|
@@ -74,7 +74,7 @@ module Landrush
|
|
74
74
|
end
|
75
75
|
|
76
76
|
it "leaves the server alone if it's not running" do
|
77
|
-
app =
|
77
|
+
app = proc {}
|
78
78
|
teardown = Teardown.new(app, nil)
|
79
79
|
env = fake_environment
|
80
80
|
|
@@ -88,7 +88,7 @@ module Landrush
|
|
88
88
|
# disabled in the first place, but oh well
|
89
89
|
Store.hosts.set('somehost.vagrant.test', '1.2.3.4')
|
90
90
|
|
91
|
-
app =
|
91
|
+
app = proc {}
|
92
92
|
teardown = Teardown.new(app, nil)
|
93
93
|
|
94
94
|
env = fake_environment
|
@@ -101,4 +101,3 @@ module Landrush
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
104
|
-
|
@@ -19,14 +19,14 @@ describe Landrush::Cap::Linux::ConfiguredDnsServers do
|
|
19
19
|
it 'parses out multiple the resolv.conf dns servers' do
|
20
20
|
machine.communicate.stubs(:sudo).yields(:stdout, [
|
21
21
|
"nameserver 12.23.34.45",
|
22
|
-
"nameserver 45.34.23.12"
|
22
|
+
"nameserver 45.34.23.12"
|
23
23
|
].join("\n"))
|
24
24
|
|
25
25
|
dns_servers = Landrush::Cap::Linux::ConfiguredDnsServers.configured_dns_servers(machine)
|
26
26
|
|
27
27
|
dns_servers.must_equal([
|
28
28
|
"12.23.34.45",
|
29
|
-
"45.34.23.12"
|
29
|
+
"45.34.23.12"
|
30
30
|
])
|
31
31
|
end
|
32
32
|
end
|
@@ -3,10 +3,9 @@ require 'test_helper'
|
|
3
3
|
module Landrush
|
4
4
|
module Cap
|
5
5
|
module Linux
|
6
|
-
|
7
6
|
describe ReadHostVisibleIpAddress do
|
8
7
|
describe 'read_host_visible_ip_address' do
|
9
|
-
let
|
8
|
+
let(:machine) { fake_machine }
|
10
9
|
|
11
10
|
it 'should read the last address' do
|
12
11
|
machine.communicate.stub_command(Landrush::Cap::Linux::ReadHostVisibleIpAddress.command, "1.2.3.4 5.6.7.8\n")
|
@@ -20,20 +19,19 @@ module Landrush
|
|
20
19
|
|
21
20
|
it 'should fail on invalid address' do
|
22
21
|
machine.communicate.stub_command(Landrush::Cap::Linux::ReadHostVisibleIpAddress.command, "hello world\n")
|
23
|
-
lambda
|
22
|
+
lambda do
|
24
23
|
machine.guest.capability(:read_host_visible_ip_address)
|
25
|
-
|
24
|
+
end.must_raise(IPAddr::InvalidAddressError)
|
26
25
|
end
|
27
26
|
|
28
27
|
it 'should fail without address' do
|
29
28
|
machine.communicate.stub_command(Landrush::Cap::Linux::ReadHostVisibleIpAddress.command, "\n")
|
30
|
-
lambda
|
29
|
+
lambda do
|
31
30
|
machine.guest.capability(:read_host_visible_ip_address)
|
32
|
-
|
31
|
+
end.must_raise(RuntimeError, 'Cannot detect IP address, command `hostname -I` returned ``')
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
36
|
-
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
@@ -1,17 +1,16 @@
|
|
1
1
|
require 'test_helper'
|
2
|
+
require 'resolv'
|
2
3
|
|
3
4
|
module Landrush
|
4
5
|
describe Server do
|
5
6
|
def query(host)
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
Resolv::DNS.open(:nameserver_port => [["127.0.0.1", Server.port]]) do |r|
|
8
|
+
r.getaddress(host).to_s
|
9
|
+
end
|
9
10
|
end
|
10
11
|
|
11
|
-
def
|
12
|
-
|
13
|
-
answer_line = output.split("\n").grep(/^#{Regexp.escape(host)}/).first
|
14
|
-
answer_line.split.last
|
12
|
+
def wait_for_port
|
13
|
+
sleep 1 until (TCPSocket.open('127.0.0.1', Server.port) rescue nil)
|
15
14
|
end
|
16
15
|
|
17
16
|
describe 'start/stop' do
|
@@ -24,11 +23,15 @@ module Landrush
|
|
24
23
|
end
|
25
24
|
|
26
25
|
# FIXME: This test requires network access.
|
27
|
-
#
|
26
|
+
# Which is not airplane hacking friendly. >:p
|
28
27
|
it 'can be queried for upstream entries' do
|
29
|
-
skip("needs network, and I am on an airplane without wifi")
|
28
|
+
# skip("needs network, and I am on an airplane without wifi")
|
29
|
+
Store.config.set('upstream', [[:udp, '8.8.8.8', 53], [:tcp, '8.8.8.8', 53]])
|
30
|
+
|
30
31
|
Server.start
|
31
32
|
|
33
|
+
wait_for_port
|
34
|
+
|
32
35
|
query("phinze.com").must_match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)
|
33
36
|
end
|
34
37
|
|
@@ -40,9 +43,9 @@ module Landrush
|
|
40
43
|
|
41
44
|
Store.hosts.set(fake_host, fake_ip)
|
42
45
|
|
43
|
-
|
44
|
-
query_ptr(fake_host).must_equal fake_ip+'.'
|
46
|
+
wait_for_port
|
45
47
|
|
48
|
+
query(fake_host).must_equal fake_ip
|
46
49
|
end
|
47
50
|
|
48
51
|
it 'responds properly to configured cname entries' do
|
@@ -55,8 +58,9 @@ module Landrush
|
|
55
58
|
Store.hosts.set(fake_host, fake_ip)
|
56
59
|
Store.hosts.set(fake_cname, fake_host)
|
57
60
|
|
58
|
-
|
61
|
+
wait_for_port
|
59
62
|
|
63
|
+
query(fake_cname).must_equal fake_ip
|
60
64
|
end
|
61
65
|
|
62
66
|
it 'also resolves wildcard subdomains to a given machine' do
|
@@ -67,6 +71,8 @@ module Landrush
|
|
67
71
|
|
68
72
|
Store.hosts.set(fake_host, fake_ip)
|
69
73
|
|
74
|
+
wait_for_port
|
75
|
+
|
70
76
|
query("green.#{fake_host}").must_match(fake_ip)
|
71
77
|
query("blue.#{fake_host}").must_match(fake_ip)
|
72
78
|
end
|
data/test/landrush/store_test.rb
CHANGED
@@ -2,13 +2,14 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
module Landrush
|
4
4
|
describe Store do
|
5
|
-
before
|
6
|
-
@
|
7
|
-
|
5
|
+
before do
|
6
|
+
@temp_file = Tempfile.new(%w[landrush_test_store .json])
|
7
|
+
@store = Store.new(@temp_file)
|
8
|
+
end
|
8
9
|
|
9
|
-
after
|
10
|
-
@
|
11
|
-
|
10
|
+
after do
|
11
|
+
@temp_file.unlink
|
12
|
+
end
|
12
13
|
|
13
14
|
describe "set" do
|
14
15
|
it "sets the key to the value and makes it available for getting" do
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CreateFakeWorkingDirHooks
|
2
|
+
def setup
|
3
|
+
super
|
4
|
+
tempdir = Dir.mktmpdir('vagrant_landrush_test_working_dir-')
|
5
|
+
working_dir = File.join(tempdir, 'data', 'landrush')
|
6
|
+
FileUtils.mkpath working_dir
|
7
|
+
|
8
|
+
# Make sure that for all tests where we use Landrush::Server the working directory
|
9
|
+
# is set to a temp directory.
|
10
|
+
# this gets deleted in DeleteFakeWorkingDirHooks
|
11
|
+
Landrush::Server.working_dir = working_dir
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module MiniTest
|
16
|
+
class Spec
|
17
|
+
include CreateFakeWorkingDirHooks
|
18
|
+
end
|
19
|
+
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
1
3
|
module FakeResolverConfigHooks
|
2
4
|
def setup
|
3
5
|
super
|
4
|
-
|
6
|
+
tempdir = Dir.mktmpdir('vagrant_landrush_fake_resolver-')
|
7
|
+
@test_resolver_config_dir = Pathname(tempdir)
|
5
8
|
Landrush::ResolverConfig.config_dir = @test_resolver_config_dir
|
6
9
|
Landrush::ResolverConfig.sudo = ''
|
7
10
|
end
|
@@ -15,6 +18,8 @@ module FakeResolverConfigHooks
|
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
18
|
-
|
19
|
-
|
21
|
+
module MiniTest
|
22
|
+
class Spec
|
23
|
+
include FakeResolverConfigHooks
|
24
|
+
end
|
20
25
|
end
|
@@ -1,28 +1,30 @@
|
|
1
1
|
# Set test port so there's nothing colliding
|
2
|
-
Landrush::Server.port =
|
2
|
+
Landrush::Server.port = 111_53
|
3
3
|
|
4
4
|
module SilenceOutput
|
5
|
-
def silence
|
6
|
-
orig_out
|
7
|
-
|
8
|
-
|
5
|
+
def self.silence
|
6
|
+
orig_out = $stdout
|
7
|
+
orig_err = $stderr
|
8
|
+
$stdout = StringIO.new
|
9
|
+
$stderr = StringIO.new
|
9
10
|
yield
|
10
11
|
ensure
|
11
12
|
$stdout = orig_out
|
12
13
|
$stderr = orig_err
|
13
14
|
end
|
14
15
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
silence { super }
|
16
|
+
def self.included(base)
|
17
|
+
orig_stop_method = base.method(:stop)
|
18
|
+
base.define_singleton_method :stop do
|
19
|
+
SilenceOutput.silence {orig_stop_method.call}
|
20
|
+
end
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
module Landrush
|
25
|
+
class Server
|
26
|
+
include SilenceOutput
|
27
|
+
end
|
26
28
|
end
|
27
29
|
|
28
30
|
module TestServerHooks
|
@@ -32,9 +34,12 @@ module TestServerHooks
|
|
32
34
|
if Landrush::Server.running?
|
33
35
|
Landrush::Server.stop
|
34
36
|
end
|
37
|
+
Landrush::Store.reset
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
38
|
-
|
39
|
-
|
41
|
+
module MiniTest
|
42
|
+
class Spec
|
43
|
+
include TestServerHooks
|
44
|
+
end
|
40
45
|
end
|