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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.config/cucumber.yml +7 -0
  3. data/.gitignore +6 -4
  4. data/.rubocop.yml +5 -0
  5. data/.rubocop_todo.yml +32 -259
  6. data/CHANGELOG.md +8 -1
  7. data/CONTRIBUTING.md +11 -10
  8. data/Gemfile +7 -4
  9. data/Gemfile.lock +178 -0
  10. data/README.md +148 -35
  11. data/Rakefile +18 -0
  12. data/doc/img/advanced-tcp-properties.png +0 -0
  13. data/doc/img/network-connections.png +0 -0
  14. data/features/dns_resolution.feature +26 -0
  15. data/features/step_definitions/dns.rb +19 -0
  16. data/features/support/env.rb +16 -0
  17. data/landrush.gemspec +1 -2
  18. data/lib/landrush.rb +0 -12
  19. data/lib/landrush/action/common.rb +5 -5
  20. data/lib/landrush/action/redirect_dns.rb +1 -1
  21. data/lib/landrush/action/setup.rb +9 -14
  22. data/lib/landrush/action/teardown.rb +5 -1
  23. data/lib/landrush/cap/debian/install_iptables.rb +2 -2
  24. data/lib/landrush/cap/linux/add_iptables_rule.rb +0 -1
  25. data/lib/landrush/cap/linux/redirect_dns.rb +0 -1
  26. data/lib/landrush/cap/redhat/install_iptables.rb +2 -2
  27. data/lib/landrush/command.rb +8 -10
  28. data/lib/landrush/config.rb +1 -1
  29. data/lib/landrush/dependent_vms.rb +2 -2
  30. data/lib/landrush/os.rb +19 -0
  31. data/lib/landrush/plugin.rb +4 -4
  32. data/lib/landrush/resolver_config.rb +1 -5
  33. data/lib/landrush/server.rb +187 -25
  34. data/lib/landrush/store.rb +12 -4
  35. data/lib/landrush/version.rb +1 -1
  36. data/test/landrush/action/setup_test.rb +14 -9
  37. data/test/landrush/action/teardown_test.rb +8 -9
  38. data/test/landrush/cap/linux/configured_dns_servers_test.rb +2 -2
  39. data/test/landrush/cap/linux/read_host_visible_ip_address_test.rb +5 -7
  40. data/test/landrush/cap/linux/redirect_dns_test.rb +1 -1
  41. data/test/landrush/resolver_config_test.rb +0 -2
  42. data/test/landrush/server_test.rb +18 -12
  43. data/test/landrush/store_test.rb +7 -6
  44. data/test/support/clear_dependent_vms.rb +4 -2
  45. data/test/support/create_fake_working_dir.rb +19 -0
  46. data/test/support/delete_fake_working_dir.rb +12 -0
  47. data/test/support/fake_resolver_config.rb +8 -3
  48. data/test/support/test_server_daemon.rb +20 -15
  49. data/test/test_helper.rb +31 -22
  50. metadata +26 -28
  51. data/lib/ext/rexec.rb +0 -10
  52. data/test/support/fake_working_dir.rb +0 -16
@@ -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(Landrush.working_dir.join('hosts.json'))
7
+ @hosts ||= new(Server.working_dir.join('hosts.json'))
5
8
  end
6
9
 
7
10
  def self.config
8
- @config ||= new(Landrush.working_dir.join('config.json'))
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.has_key? key
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 = (IPAddr.new(search).reverse) if (IPAddr.new(search) rescue nil)
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 ||
@@ -1,3 +1,3 @@
1
1
  module Landrush
2
- VERSION = "0.19.0"
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -5,12 +5,17 @@ require 'landrush/action/setup'
5
5
  module Landrush
6
6
  module Action
7
7
  describe Setup do
8
- before { ResolverConfig.sudo = '' }
9
- after { ResolverConfig.sudo = 'sudo' }
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 = lambda { |e| e[:called] = true }
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 = Proc.new {}
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 = Proc.new {}
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 = Proc.new {}
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 = Proc.new {}
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 = Proc.new {}
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 = Proc.new {}
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 = lambda { |e| e[:called] = true }
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 = Proc.new {}
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 = Proc.new {}
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 = Proc.new {}
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 = Proc.new {}
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 = Proc.new {}
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 = Proc.new {}
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 = Proc.new {}
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 (:machine) { fake_machine }
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
- }.must_raise(IPAddr::InvalidAddressError)
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
- }.must_raise(RuntimeError, 'Cannot detect IP address, command `hostname -I` returned ``')
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
@@ -18,7 +18,7 @@ describe Landrush::Cap::Linux::RedirectDns do
18
18
  Landrush::Cap::Linux::RedirectDns.redirect_dns(
19
19
  machine,
20
20
  host: '2.3.4.5',
21
- port: '4321',
21
+ port: '4321'
22
22
  )
23
23
  end
24
24
  end
@@ -16,8 +16,6 @@ module Landrush
16
16
  port #{Server.port}
17
17
  EOF
18
18
  end
19
-
20
-
21
19
  end
22
20
  end
23
21
  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
- output = `dig -p #{Server.port} @127.0.0.1 #{host}`
7
- answer_line = output.split("\n").grep(/^#{Regexp.escape(host)}/).first
8
- answer_line.split.last
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 query_ptr(host)
12
- output = `dig ptr -p #{Server.port} @127.0.0.1 #{host}`
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
- # Which is not airplane hacking friendly. >:p
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
- query(fake_host).must_equal fake_ip
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
- query(fake_cname).must_equal fake_host+'.'
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
@@ -2,13 +2,14 @@ require 'test_helper'
2
2
 
3
3
  module Landrush
4
4
  describe Store do
5
- before {
6
- @store = Store.new(Tempfile.new(%w[landrush_test_store .json]))
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
- @store.backing_file.unlink
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
@@ -5,6 +5,8 @@ module ClearDependentVms
5
5
  end
6
6
  end
7
7
 
8
- class MiniTest::Spec
9
- include ClearDependentVms
8
+ module MiniTest
9
+ class Spec
10
+ include ClearDependentVms
11
+ end
10
12
  end
@@ -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
@@ -0,0 +1,12 @@
1
+ module DeleteFakeWorkingDirHooks
2
+ def teardown
3
+ super
4
+ Landrush::Server.working_dir.rmtree if Landrush::Server.working_dir.directory?
5
+ end
6
+ end
7
+
8
+ module MiniTest
9
+ class Spec
10
+ include DeleteFakeWorkingDirHooks
11
+ end
12
+ end
@@ -1,7 +1,10 @@
1
+ require 'tmpdir'
2
+
1
3
  module FakeResolverConfigHooks
2
4
  def setup
3
5
  super
4
- @test_resolver_config_dir = Pathname('/tmp/landrush_fake_resolver')
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
- class MiniTest::Spec
19
- include FakeResolverConfigHooks
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 = 11153
2
+ Landrush::Server.port = 111_53
3
3
 
4
4
  module SilenceOutput
5
- def silence
6
- orig_out, orig_err = $stdout, $stderr
7
- $stdout, $stderr = StringIO.new, StringIO.new
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 start
16
- silence { super }
17
- end
18
-
19
- def stop
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
- class Landrush::Server
25
- extend SilenceOutput
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
- class MiniTest::Spec
39
- include TestServerHooks
41
+ module MiniTest
42
+ class Spec
43
+ include TestServerHooks
44
+ end
40
45
  end