landrush 1.1.0.beta.1 → 1.1.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
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