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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +5 -14
- data/.travis.yml +1 -1
- data/README.md +29 -5
- data/lib/landrush.rb +0 -2
- data/lib/landrush/action/setup.rb +2 -12
- data/lib/landrush/cap/{all → guest/all}/read_host_visible_ip_address.rb +0 -0
- data/lib/landrush/cap/{debian → guest/debian}/install_iptables.rb +0 -0
- data/lib/landrush/cap/{debian → guest/debian}/iptables_installed.rb +0 -0
- data/lib/landrush/cap/{linux → guest/linux}/add_iptables_rule.rb +1 -1
- data/lib/landrush/cap/{linux → guest/linux}/configured_dns_servers.rb +0 -0
- data/lib/landrush/cap/{linux → guest/linux}/redirect_dns.rb +0 -0
- data/lib/landrush/cap/{redhat → guest/redhat}/install_iptables.rb +0 -0
- data/lib/landrush/cap/{redhat → guest/redhat}/iptables_installed.rb +0 -0
- data/lib/landrush/cap/host/darwin/configure_visibility_on_host.rb +62 -0
- data/lib/landrush/cap/host/debian/dnsmasq_installed.rb +11 -0
- data/lib/landrush/cap/host/debian/host.rb +11 -0
- data/lib/landrush/cap/host/debian/install_dnsmasq.rb +12 -0
- data/lib/landrush/cap/host/debian/restart_dnsmasq.rb +11 -0
- data/lib/landrush/cap/host/linux/configure_visibility_on_host.rb +18 -0
- data/lib/landrush/cap/host/linux/create_dnsmasq_config.rb +65 -0
- data/lib/landrush/cap/host/redhat/dnsmasq_installed.rb +11 -0
- data/lib/landrush/cap/host/redhat/install_dnsmasq.rb +14 -0
- data/lib/landrush/cap/host/redhat/restart_dnsmasq.rb +23 -0
- data/lib/landrush/cap/host/ubuntu/host.rb +12 -0
- data/lib/landrush/cap/host/windows/configure_visibility_on_host.rb +187 -0
- data/lib/landrush/config.rb +22 -15
- data/lib/landrush/plugin.rb +68 -8
- data/lib/landrush/version.rb +1 -1
- data/test/landrush/action/setup_test.rb +4 -34
- data/test/landrush/cap/{all → guest/all}/read_host_visible_ip_address_test.rb +1 -1
- data/test/landrush/cap/{linux → guest/linux}/configured_dns_servers_test.rb +1 -1
- data/test/landrush/cap/{linux → guest/linux}/redirect_dns_test.rb +2 -5
- data/test/landrush/cap/host/darwin/configure_visibility_on_host_test.rb +56 -0
- data/test/landrush/cap/host/linux/configure_visibility_on_host_test.rb +34 -0
- data/test/landrush/cap/host/windows/configure_visibility_on_host_test.rb +70 -0
- data/test/test_helper.rb +28 -17
- metadata +34 -26
- data/lib/landrush/resolver_config.rb +0 -68
- data/lib/landrush/win_network_config.rb +0 -185
- data/test/landrush/resolver_config_test.rb +0 -19
- data/test/landrush/win_network_config_test.rb +0 -70
- data/test/support/fake_resolver_config.rb +0 -25
- 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
|