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.
- 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
|