landrush 1.1.0.beta.1 → 1.1.0.beta.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.rubocop_todo.yml +5 -14
  4. data/.travis.yml +1 -1
  5. data/README.md +29 -5
  6. data/lib/landrush.rb +0 -2
  7. data/lib/landrush/action/setup.rb +2 -12
  8. data/lib/landrush/cap/{all → guest/all}/read_host_visible_ip_address.rb +0 -0
  9. data/lib/landrush/cap/{debian → guest/debian}/install_iptables.rb +0 -0
  10. data/lib/landrush/cap/{debian → guest/debian}/iptables_installed.rb +0 -0
  11. data/lib/landrush/cap/{linux → guest/linux}/add_iptables_rule.rb +1 -1
  12. data/lib/landrush/cap/{linux → guest/linux}/configured_dns_servers.rb +0 -0
  13. data/lib/landrush/cap/{linux → guest/linux}/redirect_dns.rb +0 -0
  14. data/lib/landrush/cap/{redhat → guest/redhat}/install_iptables.rb +0 -0
  15. data/lib/landrush/cap/{redhat → guest/redhat}/iptables_installed.rb +0 -0
  16. data/lib/landrush/cap/host/darwin/configure_visibility_on_host.rb +62 -0
  17. data/lib/landrush/cap/host/debian/dnsmasq_installed.rb +11 -0
  18. data/lib/landrush/cap/host/debian/host.rb +11 -0
  19. data/lib/landrush/cap/host/debian/install_dnsmasq.rb +12 -0
  20. data/lib/landrush/cap/host/debian/restart_dnsmasq.rb +11 -0
  21. data/lib/landrush/cap/host/linux/configure_visibility_on_host.rb +18 -0
  22. data/lib/landrush/cap/host/linux/create_dnsmasq_config.rb +65 -0
  23. data/lib/landrush/cap/host/redhat/dnsmasq_installed.rb +11 -0
  24. data/lib/landrush/cap/host/redhat/install_dnsmasq.rb +14 -0
  25. data/lib/landrush/cap/host/redhat/restart_dnsmasq.rb +23 -0
  26. data/lib/landrush/cap/host/ubuntu/host.rb +12 -0
  27. data/lib/landrush/cap/host/windows/configure_visibility_on_host.rb +187 -0
  28. data/lib/landrush/config.rb +22 -15
  29. data/lib/landrush/plugin.rb +68 -8
  30. data/lib/landrush/version.rb +1 -1
  31. data/test/landrush/action/setup_test.rb +4 -34
  32. data/test/landrush/cap/{all → guest/all}/read_host_visible_ip_address_test.rb +1 -1
  33. data/test/landrush/cap/{linux → guest/linux}/configured_dns_servers_test.rb +1 -1
  34. data/test/landrush/cap/{linux → guest/linux}/redirect_dns_test.rb +2 -5
  35. data/test/landrush/cap/host/darwin/configure_visibility_on_host_test.rb +56 -0
  36. data/test/landrush/cap/host/linux/configure_visibility_on_host_test.rb +34 -0
  37. data/test/landrush/cap/host/windows/configure_visibility_on_host_test.rb +70 -0
  38. data/test/test_helper.rb +28 -17
  39. metadata +34 -26
  40. data/lib/landrush/resolver_config.rb +0 -68
  41. data/lib/landrush/win_network_config.rb +0 -185
  42. data/test/landrush/resolver_config_test.rb +0 -19
  43. data/test/landrush/win_network_config_test.rb +0 -70
  44. data/test/support/fake_resolver_config.rb +0 -25
  45. data/test/support/fake_ui.rb +0 -5
@@ -1,185 +0,0 @@
1
- # This file needs to be able to execute out of the Vagrant context. Do not require any non core or non relative files
2
- require 'ipaddr'
3
- require_relative 'util/retry'
4
-
5
- # This class configures the network interface on Windows for use with the Landrush DNS server.
6
- # It makes use of the netsh executable which is assumed to be available on the Windows host.
7
- module Landrush
8
- class WinNetworkConfig
9
- include Landrush::Util::Retry
10
-
11
- # Windows registry path under which network interface configuration is stored
12
- INTERFACES = 'SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces'.freeze
13
-
14
- def initialize(env={})
15
- @env = env
16
- end
17
-
18
- # Checks that all required tools are on the PATH and that the Wired AutoConfig service is started
19
- def ensure_prerequisites
20
- return false unless command_found('netsh')
21
- return false unless command_found('net')
22
- return false unless command_found('reg')
23
-
24
- unless wired_autoconfig_service_running?
25
- info('starting \'Wired AutoConfig\' service')
26
- if self.class.admin_mode?
27
- `net start dot3svc`
28
- else
29
- require 'win32ole'
30
- shell = WIN32OLE.new('Shell.Application')
31
- shell.ShellExecute('net', 'start dot3svc', nil, 'runas', 1)
32
- end
33
- service_has_started = self.retry(tries: 5, sleep: 1) do
34
- wired_autoconfig_service_running?
35
- end
36
- unless service_has_started
37
- info('Unable to start \'Wired AutoConfig\' service. Unable to configure DNS on host. Try manual configuration.')
38
- return false
39
- end
40
- info('\'Wired AutoConfig\' service has started.')
41
- end
42
- true
43
- end
44
-
45
- # Does the actual update of the network configuration
46
- def update_network_adapter(ip, name_server, domain)
47
- # Need to defer loading to ensure cross OS compatibility
48
- require 'win32/registry'
49
- ensure_admin_privileges(__FILE__.to_s, ip, name_server, domain)
50
-
51
- network_name = get_network_name(ip)
52
- if network_name.nil?
53
- info("unable to determine network interface for #{ip}. DNS on host cannot be configured. Try manual configuration.")
54
- return
55
- else
56
- info("adding Landrush'es DNS server to network '#{network_name}' using DNS IP '#{ip}'' and search domain '#{domain}'")
57
- end
58
- network_guid = get_guid(network_name)
59
- if network_guid.nil?
60
- info("unable to determine network GUID for #{ip}. DNS on host cannot be configured. Try manual configuration.")
61
- return
62
- end
63
- interface_path = INTERFACES + "\\{#{network_guid}}"
64
- Win32::Registry::HKEY_LOCAL_MACHINE.open(interface_path, Win32::Registry::KEY_ALL_ACCESS) do |reg|
65
- reg['NameServer'] = name_server
66
- reg['Domain'] = domain
67
- end
68
- end
69
-
70
- # If this registry query succeeds we assume we have Admin rights
71
- # http://stackoverflow.com/questions/8268154/run-ruby-script-in-elevated-mode/27954953
72
- def self.admin_mode?
73
- (`reg query HKU\\S-1-5-19 2>&1` =~ /ERROR/).nil?
74
- end
75
-
76
- private
77
-
78
- # Given a network name (as displayed on 'Control Panel\Network and Internet\Network Connections'),
79
- # determines the GUID of this network interface using 'netsh'.
80
- #
81
- # To make this work the "Wired Autoconfig" service must be started (go figure).
82
- #
83
- # Output of netsh command which is being processed:
84
- #
85
- # There are 4 interfaces on the system:
86
- #
87
- # Name : Ethernet
88
- # Description : Intel(R) Ethernet Connection (3) I218-LM
89
- # GUID : fd9270f6-aff6-4f24-bc4a-1f90c032d5c3
90
- # Physical Address : 50-7B-9D-AB-25-1D
91
- # \n\n
92
- # ...
93
- def get_guid(network_name)
94
- cmd_out = `netsh lan show interfaces`
95
- interface_details = cmd_out.split(/\n\n/).select { |settings| settings.match(/#{Regexp.quote(network_name)}/m) }
96
- return nil if interface_details.empty?
97
- interface_details[0].split(/\n/)[2].match(/.*:(.*)/).captures[0].strip
98
- end
99
-
100
- # Given an IP determines the network name, if any. Uses netsh which generates output like this:
101
- #
102
- # ...
103
- # \n\n
104
- # Configuration for interface "Ethernet 2"
105
- # DHCP enabled: Yes
106
- # IP Address: 10.10.10.1
107
- # Subnet Prefix: 10.10.10.0/24 (mask 255.255.255.0)
108
- # InterfaceMetric: 10
109
- # DNS servers configured through DHCP: None
110
- # Register with which suffix: Primary only
111
- # WINS servers configured through DHCP: None
112
- # \n\n
113
- # ...
114
- def get_network_name(ip)
115
- cmd_out = `netsh interface ip show config`
116
- network_details = cmd_out.split(/\n\n/).select do |settings|
117
- begin
118
- lines = settings.split(/\n/).reject(&:empty?)
119
- subnet = lines[3]
120
- next false unless subnet =~ /Subnet Prefix/
121
-
122
- mask = IPAddr.new(subnet.match(%r{.* (\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}/\d{1,3}).*}).captures[0])
123
- address = IPAddr.new(ip)
124
-
125
- mask.include?(address)
126
- rescue
127
- false
128
- end
129
- end
130
- return nil if network_details[0].nil?
131
- network_details[0].split(/\n/)[0].match(/Configuration for interface "(.*)"/).captures[0].strip
132
- end
133
-
134
- # Makes sure that we have admin privileges and if nor starts a new shell with the required
135
- # privileges
136
- def ensure_admin_privileges(file, *args)
137
- unless self.class.admin_mode?
138
- require 'win32ole'
139
- shell = WIN32OLE.new('Shell.Application')
140
- shell.ShellExecute('ruby', "#{file} #{args.join(' ')}", nil, 'runas', 1)
141
- # need to exit current execution, changes will occur in new environment
142
- exit
143
- end
144
- end
145
-
146
- def info(msg)
147
- @env[:ui].info("[landrush] #{msg}") unless @env.nil?
148
- end
149
-
150
- def wired_autoconfig_service_running?
151
- cmd_out = `net start`
152
- cmd_out =~ /Wired AutoConfig/m
153
- end
154
-
155
- def command_found(cmd)
156
- if which(cmd).nil?
157
- info("Cannot find '#{cmd}' on the PATH. Unable to configure DNS. Try manual configuration.")
158
- false
159
- else
160
- true
161
- end
162
- end
163
-
164
- # Cross-platform way of finding an executable in the $PATH.
165
- #
166
- # which('ruby') #=> /usr/bin/ruby
167
- def which(cmd)
168
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
169
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
170
- exts.each do |ext|
171
- exe = File.join(path, "#{cmd}#{ext}")
172
- return exe if File.executable?(exe) && !File.directory?(exe)
173
- end
174
- end
175
- nil
176
- end
177
- end
178
- end
179
-
180
- # Only run the following code when this file is the main file being run
181
- # instead of having been required or loaded by another file
182
- if __FILE__ == $0
183
- config = Landrush::WinNetworkConfig.new nil
184
- config.update_network_adapter(ARGV[0], ARGV[1], ARGV[2])
185
- end
@@ -1,19 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- module Landrush
4
- describe ResolverConfig do
5
- describe 'ensure_config_exists' do
6
- it 'writes a resolver config on the host if one is not already there' do
7
- resolver_config = ResolverConfig.new(fake_environment)
8
- resolver_config.config_file.exist?.must_equal false
9
- resolver_config.ensure_config_exists!
10
- resolver_config.config_file.exist?.must_equal true
11
- resolver_config.config_file.read.must_equal <<-EOF.gsub(/^ +/, '')
12
- # Generated by landrush, a vagrant plugin
13
- nameserver 127.0.0.1
14
- port #{Server.port}
15
- EOF
16
- end
17
- end
18
- end
19
- end
@@ -1,70 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- module Landrush
4
- TEST_IP = '10.42.42.42'.freeze
5
-
6
- describe WinNetworkConfig do
7
- before do
8
- @vboxmanage_found = !Vagrant::Util::Which.which('VBoxManage').nil?
9
- @has_admin_privileges = Landrush::WinNetworkConfig.admin_mode?
10
- end
11
-
12
- describe 'modify DNS settings of network adapter' do
13
- it 'sets 127.0.0.1 as DNS server on the interface' do
14
- skip('Only supported on Windows') unless Vagrant::Util::Platform.windows? && @vboxmanage_found && @has_admin_privileges
15
-
16
- # VBoxManage uses the network description for its commands whereas netsh uses the name
17
- # We need to get both
18
- begin
19
- old_network_state = network_state
20
- network_description = create_test_interface
21
- new_network_state = network_state
22
- network_name = get_network_name(old_network_state, new_network_state)
23
-
24
- get_dns_for_name(network_name).must_be_nil
25
-
26
- config = Landrush::WinNetworkConfig.new(fake_environment)
27
- config.ensure_prerequisites.must_equal true
28
- config.update_network_adapter(TEST_IP, '127.0.0.1', 'landrush.test')
29
-
30
- get_dns_for_name(network_name).must_equal '127.0.0.1'
31
- rescue
32
- delete_test_interface network_description
33
- end
34
- end
35
- end
36
-
37
- def network_state
38
- `netsh interface ip show config`.split(/\n/).reject(&:empty?)
39
- end
40
-
41
- def get_network_name(old_network_state, new_network_state)
42
- new_network_state.reject! { |line| old_network_state.include? line }
43
- new_network_state[0].match(/.*\"(.*)\"$/).captures[0]
44
- end
45
-
46
- # Creates a test interface using VBoxMange and sets a known test IP
47
- def create_test_interface
48
- cmd_out = `VBoxManage hostonlyif create`
49
- network_description = cmd_out.match(/.*'(.*)'.*/).captures[0]
50
- `VBoxManage.exe hostonlyif ipconfig \"#{network_description}\" --ip #{TEST_IP}`
51
- sleep 3
52
- network_description
53
- end
54
-
55
- def delete_test_interface(name)
56
- `VBoxManage hostonlyif remove \"#{name}\"`
57
- end
58
-
59
- def get_dns_for_name(name)
60
- cmd_out = `netsh interface ip show config name=\"#{name}\"`
61
- dns = cmd_out.split(/\n/).select { |settings| settings.match(/Statically Configured DNS Servers/m) }
62
- # TODO: better error handling
63
- begin
64
- dns[0].match(/.* (\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}).*/).captures[0]
65
- rescue
66
- return nil
67
- end
68
- end
69
- end
70
- end
@@ -1,25 +0,0 @@
1
- require 'tmpdir'
2
-
3
- module FakeResolverConfigHooks
4
- def setup
5
- super
6
- tempdir = Dir.mktmpdir('vagrant_landrush_fake_resolver-')
7
- @test_resolver_config_dir = Pathname(tempdir)
8
- Landrush::ResolverConfig.config_dir = @test_resolver_config_dir
9
- Landrush::ResolverConfig.sudo = ''
10
- end
11
-
12
- def teardown
13
- super
14
- Landrush::ResolverConfig.sudo = 'sudo'
15
- if @test_resolver_config_dir.exist?
16
- @test_resolver_config_dir.rmtree
17
- end
18
- end
19
- end
20
-
21
- module MiniTest
22
- class Spec
23
- include FakeResolverConfigHooks
24
- end
25
- end
@@ -1,5 +0,0 @@
1
- class FakeUI
2
- def self.info(*args)
3
- # puts "#{args.join(' ')}"
4
- end
5
- end