vagrant-hostsupdater 0.0.11 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/Gemfile +7 -48
- data/LICENSE.txt +1 -1
- data/README.md +183 -17
- data/lib/vagrant-hostsupdater/Action/RemoveHosts.rb +7 -5
- data/lib/vagrant-hostsupdater/Action/UpdateHosts.rb +2 -2
- data/lib/vagrant-hostsupdater/HostsUpdater.rb +169 -34
- data/lib/vagrant-hostsupdater/plugin.rb +6 -0
- data/lib/vagrant-hostsupdater/version.rb +1 -1
- data/vagrant-hostsupdater.gemspec +9 -9
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c931c60a9148df5bd393def93d08d89be804047f19249ccf253c4760d789f346
|
4
|
+
data.tar.gz: 89c817fbfa2232694ac757058fbeed8fc519765f07078372828ffc2a66b70167
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68b582634e6a0c4fe5a10b5633a0e1bc18f7f2ce21cc78b2a0650d2413ca4c6e8ead758fc4e21455e1dba01284e3c213312bf3b2085a4559c8c06d506581a82e
|
7
|
+
data.tar.gz: 3376c1d9f2a7889aea6de4e8eda2c67661e4fe9995a5a0d6a3c4ecf15018142c20ff3f3540183997f3bdd644b2c788788bad5181c8f6719b2bb0d2cc893bb32c
|
data/Gemfile
CHANGED
@@ -1,50 +1,9 @@
|
|
1
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
s.version = 0.2
|
6
|
-
s.platform = Gem::Platform::RUBY
|
7
|
-
s.authors = "Falk Kühnel"
|
8
|
-
s.email = "fk@cogitatio.de"
|
9
|
-
s.homepage = "https://github.com/cogitatio/vagrant-hostsupdater"
|
10
|
-
s.summary = "Enables Vagrant to update hosts file on the host machine"
|
11
|
-
s.description = "Enables Vagrant to update hosts file on the host machine"
|
12
|
-
|
13
|
-
|
14
|
-
# s.add_development_dependency "rake"
|
15
|
-
|
16
|
-
# # The following block of code determines the files that should be included
|
17
|
-
# # in the gem. It does this by reading all the files in the directory where
|
18
|
-
# # this gemspec is, and parsing out the ignored files from the gitignore.
|
19
|
-
# # Note that the entire gitignore(5) syntax is not supported, specifically
|
20
|
-
# # the "!" syntax, but it should mostly work correctly.
|
21
|
-
# root_path = File.dirname(__FILE__)
|
22
|
-
# all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
|
23
|
-
# all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
|
24
|
-
# gitignore_path = File.join(root_path, ".gitignore")
|
25
|
-
# gitignore = File.readlines(gitignore_path)
|
26
|
-
# gitignore.map! { |line| line.chomp.strip }
|
27
|
-
# gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
|
28
|
-
|
29
|
-
# unignored_files = all_files.reject do |file|
|
30
|
-
# # Ignore any directories, the gemspec only cares about files
|
31
|
-
# next true if File.directory?(file)
|
32
|
-
|
33
|
-
# # Ignore any paths that match anything in the gitignore. We do
|
34
|
-
# # two tests here:
|
35
|
-
# #
|
36
|
-
# # - First, test to see if the entire path matches the gitignore.
|
37
|
-
# # - Second, match if the basename does, this makes it so that things
|
38
|
-
# # like '.DS_Store' will match sub-directories too (same behavior
|
39
|
-
# # as git).
|
40
|
-
# #
|
41
|
-
# gitignore.any? do |ignore|
|
42
|
-
# File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
|
43
|
-
# File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
|
44
|
-
# end
|
45
|
-
# end
|
46
|
-
|
47
|
-
# s.files = unignored_files
|
48
|
-
# s.executables = unignored_files.map { |f| f[/^bin\/(.*)/, 1] }.compact
|
49
|
-
# s.require_path = 'lib'
|
3
|
+
group :development do
|
4
|
+
gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.6.2'
|
50
5
|
end
|
6
|
+
|
7
|
+
group :plugins do
|
8
|
+
gemspec
|
9
|
+
end
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
# Vagrant::Hostsupdater
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/vagrant-hostsupdater.svg)](https://badge.fury.io/rb/vagrant-hostsupdater)
|
4
|
+
[![Gem](https://img.shields.io/gem/dt/vagrant-hostsupdater.svg)](https://rubygems.org/gems/vagrant-hostsupdater)
|
5
|
+
[![Gem](https://img.shields.io/gem/dtv/vagrant-hostsupdater.svg)](https://rubygems.org/gems/vagrant-hostsupdater)
|
6
|
+
|
7
|
+
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cogitatio/vagrant-hostsupdater?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
8
|
+
[![Twitter](https://img.shields.io/twitter/url/https/github.com/cogitatio/vagrant-hostsupdater.svg?style=social)](https://twitter.com/intent/tweet?text=Checkout%20this%20awesome%20Vagrant%20plugin!&url=https%3A%2F%2Fgithub.com%2Fcogiatio%2Fvagrant-hostsupdater&hashtags=hostsupdater,vagrant)
|
4
9
|
|
5
|
-
On **up**, **resume** and **reload** commands, it tries to add the information, if its not already existant in your hosts file. If it needs to be added, you will be asked for an administrator password, since it uses sudo to edit the file.
|
6
10
|
|
7
|
-
|
8
|
-
By setting the remove\_on\_suspend option, you can have them removed on **suspend**, too:
|
11
|
+
This plugin adds an entry to your /etc/hosts file on the host system.
|
9
12
|
|
10
|
-
|
13
|
+
On **up**, **resume** and **reload** commands, it tries to add the information, if it does not already exist in your hosts file. If it needs to be added, you will be asked for an administrator password, since it uses sudo to edit the file.
|
11
14
|
|
15
|
+
On **halt**, **destroy**, and **suspend**, those entries will be removed again.
|
16
|
+
By setting the `config.hostsupdater.remove_on_suspend = false`, **suspend** and **halt** will not remove them.
|
12
17
|
|
13
18
|
|
14
19
|
## Installation
|
@@ -19,17 +24,187 @@ Uninstall it with:
|
|
19
24
|
|
20
25
|
$ vagrant plugin uninstall vagrant-hostsupdater
|
21
26
|
|
27
|
+
Update the plugin with:
|
28
|
+
|
29
|
+
$ vagrant plugin update vagrant-hostsupdater
|
30
|
+
|
22
31
|
## Usage
|
23
32
|
|
24
|
-
|
33
|
+
You currently only need the `hostname` and a `:private_network` network with a fixed IP address.
|
25
34
|
|
26
35
|
config.vm.network :private_network, ip: "192.168.3.10"
|
27
36
|
config.vm.hostname = "www.testing.de"
|
28
37
|
config.hostsupdater.aliases = ["alias.testing.de", "alias2.somedomain.com"]
|
29
38
|
|
30
|
-
This
|
39
|
+
This IP address and the hostname will be used for the entry in the `/etc/hosts` file.
|
40
|
+
|
41
|
+
### Multiple private network adapters
|
42
|
+
|
43
|
+
If you have multiple network adapters i.e.:
|
44
|
+
|
45
|
+
config.vm.network :private_network, ip: "10.0.0.1"
|
46
|
+
config.vm.network :private_network, ip: "10.0.0.2"
|
47
|
+
|
48
|
+
you can specify which hostnames are bound to which IP by passing a hash mapping the IP of the network to an array of hostnames to create, e.g.:
|
49
|
+
|
50
|
+
config.hostsupdater.aliases = {
|
51
|
+
'10.0.0.1' => ['foo.com', 'bar.com'],
|
52
|
+
'10.0.0.2' => ['baz.com', 'bat.com']
|
53
|
+
}
|
54
|
+
|
55
|
+
This will produce `/etc/hosts` entries like so:
|
56
|
+
|
57
|
+
10.0.0.1 foo.com
|
58
|
+
10.0.0.1 bar.com
|
59
|
+
10.0.0.2 baz.com
|
60
|
+
10.0.0.2 bat.com
|
61
|
+
|
62
|
+
### Skipping hostupdater
|
63
|
+
|
64
|
+
To skip adding some entries to the /etc/hosts file add `hostsupdater: "skip"` option to network configuration:
|
65
|
+
|
66
|
+
config.vm.network "private_network", ip: "172.21.9.9", hostsupdater: "skip"
|
67
|
+
|
68
|
+
Example:
|
69
|
+
|
70
|
+
config.vm.network :private_network, ip: "192.168.50.4"
|
71
|
+
config.vm.network :private_network,
|
72
|
+
ip: "172.21.9.9",
|
73
|
+
netmask: "255.255.240.0",
|
74
|
+
hostsupdater: "skip"
|
75
|
+
|
76
|
+
### Keeping Host Entries After Suspend/Halt
|
77
|
+
|
78
|
+
To keep your /etc/hosts file unchanged simply add the line below to your `VagrantFile`:
|
79
|
+
|
80
|
+
config.hostsupdater.remove_on_suspend = false
|
81
|
+
|
82
|
+
This disables vagrant-hostsupdater from running on **suspend** and **halt**.
|
83
|
+
|
84
|
+
|
85
|
+
## Suppressing prompts for elevating privileges
|
86
|
+
|
87
|
+
These prompts exist to prevent anything that is being run by the user from inadvertently updating the hosts file.
|
88
|
+
If you understand the risks that go with supressing them, here's how to do it.
|
89
|
+
|
90
|
+
### Linux/OS X: Passwordless sudo
|
91
|
+
|
92
|
+
To allow vagrant to automatically update the hosts file without asking for a sudo password, add one of the following snippets to a new sudoers file include, i.e. `sudo visudo -f /etc/sudoers.d/vagrant_hostsupdater`.
|
93
|
+
|
94
|
+
For Ubuntu and most Linux environments:
|
95
|
+
|
96
|
+
# Allow passwordless startup of Vagrant with vagrant-hostsupdater.
|
97
|
+
Cmnd_Alias VAGRANT_HOSTS_ADD = /bin/sh -c echo "*" >> /etc/hosts
|
98
|
+
Cmnd_Alias VAGRANT_HOSTS_REMOVE = /bin/sed -i -e /*/ d /etc/hosts
|
99
|
+
%sudo ALL=(root) NOPASSWD: VAGRANT_HOSTS_ADD, VAGRANT_HOSTS_REMOVE
|
100
|
+
|
101
|
+
For MacOS:
|
102
|
+
|
103
|
+
# Allow passwordless startup of Vagrant with vagrant-hostsupdater.
|
104
|
+
Cmnd_Alias VAGRANT_HOSTS_ADD = /bin/sh -c echo "*" >> /etc/hosts
|
105
|
+
Cmnd_Alias VAGRANT_HOSTS_REMOVE = /usr/bin/sed -i -e /*/ d /etc/hosts
|
106
|
+
%admin ALL=(root) NOPASSWD: VAGRANT_HOSTS_ADD, VAGRANT_HOSTS_REMOVE
|
107
|
+
|
108
|
+
- If vagrant still asks for a password on commands that trigger the `VAGRANT_HOSTS_ADD` alias above (like **up**), you might need to wrap the echo statement in quotes, i.e. `Cmnd_Alias VAGRANT_HOSTS_ADD = /bin/sh -c 'echo "*" >> /etc/hosts'`. This seems to be a problem with older versions of Linux and MacOS.
|
109
|
+
- If vagrant still asks for a password on commands that trigger the `VAGRANT_HOSTS_REMOVE` alias above (like
|
110
|
+
**halt** or **suspend**), this might indicate that the location of **sed** in the `VAGRANT_HOSTS_REMOVE` alias is
|
111
|
+
pointing to the wrong location. The solution is to find the location of **sed** (ex. `which sed`) and
|
112
|
+
replace that location in the `VAGRANT_HOSTS_REMOVE` alias.
|
113
|
+
|
114
|
+
### Windows: UAC Prompt
|
31
115
|
|
32
|
-
|
116
|
+
You can use `cacls` or `icacls` to grant your user account permanent write permission to the system's hosts file.
|
117
|
+
You have to open an elevated command prompt; hold `❖ Win` and press `X`, then choose "Command Prompt (Admin)"
|
118
|
+
|
119
|
+
cacls %SYSTEMROOT%\system32\drivers\etc\hosts /E /G %USERNAME%:W
|
120
|
+
|
121
|
+
## Using AWS as a Provider
|
122
|
+
|
123
|
+
If you'd like AWS as a provider using [vagrant-aws](https://github.com/mitchellh/vagrant-aws) or other plugin,
|
124
|
+
this plugin will detect the instance public IP by the tag infomations.
|
125
|
+
For example, [vagrant-aws](https://github.com/mitchellh/vagrant-aws) configures a tag infomations like the following.
|
126
|
+
|
127
|
+
config.vm.provider :aws do |aws, override|
|
128
|
+
aws.tags = {
|
129
|
+
"Name" => "vagrant",
|
130
|
+
...
|
131
|
+
}
|
132
|
+
aws.elastic_ip = true
|
133
|
+
...
|
134
|
+
end
|
135
|
+
|
136
|
+
* [AWS CLI](https://aws.amazon.com/cli/) is required
|
137
|
+
* The tag informations be unique for the instance
|
138
|
+
* Enable Elastic IP for the instance
|
139
|
+
|
140
|
+
## Using Google as a provider
|
141
|
+
|
142
|
+
If you'd like a Google provider using [vagrant-google](https://github.com/mitchellh/vagrant-google), this plugin will detect the public IP from the name of the instance.
|
143
|
+
[vagrant-google](https://github.com/mitchellh/vagrant-google) provides a default name, but you can specify your own as follows:
|
144
|
+
|
145
|
+
config.vm.provider :google do |google, override|
|
146
|
+
google.name = "somename"
|
147
|
+
...
|
148
|
+
end
|
149
|
+
|
150
|
+
* [Google Cloud SDK](https://cloud.google.com/sdk/) is required.
|
151
|
+
|
152
|
+
## Installing development version
|
153
|
+
|
154
|
+
If you would like to install vagrant-hostsupdater on the development version perform the following:
|
155
|
+
|
156
|
+
```
|
157
|
+
git clone https://github.com/cogitatio/vagrant-hostsupdater
|
158
|
+
cd vagrant-hostsupdater
|
159
|
+
git checkout develop
|
160
|
+
gem build vagrant-hostsupdater.gemspec
|
161
|
+
vagrant plugin install vagrant-hostsupdater-*.gem
|
162
|
+
```
|
163
|
+
|
164
|
+
## Contributing
|
165
|
+
|
166
|
+
1. Fork it
|
167
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
168
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
169
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
170
|
+
5. Create new Pull Request on the `develop` branch
|
171
|
+
|
172
|
+
|
173
|
+
## Versions
|
174
|
+
|
175
|
+
### 1.1.1
|
176
|
+
* Bugfix: AWS Feature broke part of the code [#155](/../../issues/155)
|
177
|
+
|
178
|
+
### 1.1.0
|
179
|
+
* Feature: Added AWS support [#74](/../../pull/74)
|
180
|
+
* Feature: Added libvirt provider [#122](/../../pull/122)
|
181
|
+
* Feature: Add support for multiple private network adapters [#96](/../../pull/96)
|
182
|
+
* Feature: Add support for VMs without private/public networking [#23](/../../issues/23)
|
183
|
+
* Feature: Add Docker support [#149](/../../pull/149)
|
184
|
+
* Bugfix: Windows users get UAC prompt [#40](/../../issues/40)
|
185
|
+
* Bugfix: Documentation update and type fix
|
186
|
+
* Misc: Added a note about suppressing UAC prompts
|
187
|
+
|
188
|
+
### 1.0.2
|
189
|
+
* Feature: Added `remove_on_suspend` for `vagrant_halt` [#71](/../../issues/71)
|
190
|
+
* Feature: Skip entries if they already exist [#69](/../../issues/69)
|
191
|
+
* Bugfix: Fixing extra lines in /etc/hosts file [#87](/../../pull/87)
|
192
|
+
* Misc: Fix yellow text on UI [#39](/../../issues/39)
|
193
|
+
|
194
|
+
### 1.0.1
|
195
|
+
* Bugfix: Fixing `up` issue on initialize [#28](/../../issues/28)
|
196
|
+
|
197
|
+
### 1.0.0
|
198
|
+
* Stable release
|
199
|
+
* Feature: Added `skip` flag [#69](/../../issues/69)
|
200
|
+
* Feature: Hosts update on provision action [#65](/../../issues/65)
|
201
|
+
* Bugfix: `remove_on_suspend` should be true [#19](/../../issues/19)
|
202
|
+
* Bugfix: Line break not inserted before first host [#37](/../../issues/37)
|
203
|
+
* Bugfix: Old changes not removed in linux [#67](/../../issues/67)
|
204
|
+
* Bugfix: Writable issue on OSX [#47](/../../issues/47)
|
205
|
+
* Bugfix: Update hosts before provisioning [#31](/../../issues/31)
|
206
|
+
* Misc: Using Semantic Versioning for version number
|
207
|
+
* Misc: Added note regarding sudoers file
|
33
208
|
|
34
209
|
### 0.0.11
|
35
210
|
* bugfix: Fix additional new lines being added to hosts file (Thanks to vincentmac)
|
@@ -58,12 +233,3 @@ This ip and the hostname will be used for the entry in the /etc/hosts file.
|
|
58
233
|
|
59
234
|
### 0.0.3
|
60
235
|
* added aliases config option to define additional hostnames
|
61
|
-
|
62
|
-
|
63
|
-
## Contributing
|
64
|
-
|
65
|
-
1. Fork it
|
66
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
67
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
68
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
69
|
-
5. Create new Pull Request
|
@@ -13,11 +13,13 @@ module VagrantPlugins
|
|
13
13
|
def call(env)
|
14
14
|
machine_action = env[:machine_action]
|
15
15
|
if machine_action != :destroy || !@machine.id
|
16
|
-
if machine_action != :suspend || @machine.config.hostsupdater.remove_on_suspend
|
17
|
-
@
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
if machine_action != :suspend || false != @machine.config.hostsupdater.remove_on_suspend
|
17
|
+
if machine_action != :halt || false != @machine.config.hostsupdater.remove_on_suspend
|
18
|
+
@ui.info "[vagrant-hostsupdater] Removing hosts"
|
19
|
+
removeHostEntries
|
20
|
+
else
|
21
|
+
@ui.info "[vagrant-hostsupdater] Removing hosts on suspend disabled"
|
22
|
+
end
|
21
23
|
end
|
22
24
|
end
|
23
25
|
@app.call(env)
|
@@ -1,40 +1,97 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
module VagrantPlugins
|
2
4
|
module HostsUpdater
|
3
5
|
module HostsUpdater
|
4
|
-
|
6
|
+
if ENV['VAGRANT_HOSTSUPDATER_PATH']
|
7
|
+
@@hosts_path = ENV['VAGRANT_HOSTSUPDATER_PATH']
|
8
|
+
else
|
9
|
+
@@hosts_path = Vagrant::Util::Platform.windows? ? File.expand_path('system32/drivers/etc/hosts', ENV['windir']) : '/etc/hosts'
|
10
|
+
end
|
11
|
+
@isWindowsHost = Vagrant::Util::Platform.windows?
|
12
|
+
@@ssh_known_hosts_path = '~/.ssh/known_hosts'
|
5
13
|
|
6
14
|
def getIps
|
7
15
|
ips = []
|
8
|
-
|
9
|
-
|
10
|
-
ip
|
11
|
-
|
16
|
+
|
17
|
+
if ip = getAwsPublicIp
|
18
|
+
ips.push(ip)
|
19
|
+
elsif ip = getGooglePublicIp
|
20
|
+
ips.push(ip)
|
21
|
+
else
|
22
|
+
@machine.config.vm.networks.each do |network|
|
23
|
+
key, options = network[0], network[1]
|
24
|
+
ip = options[:ip] if (key == :private_network || key == :public_network) && options[:hostsupdater] != "skip"
|
25
|
+
ips.push(ip) if ip
|
26
|
+
if options[:hostsupdater] == 'skip'
|
27
|
+
@ui.info '[vagrant-hostsupdater] Skipping adding host entries (config.vm.network hostsupdater: "skip" is set)'
|
28
|
+
end
|
29
|
+
end
|
12
30
|
end
|
13
|
-
return ips
|
14
|
-
end
|
15
31
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
32
|
+
if @machine.provider_name == :lxc
|
33
|
+
ip = @machine.provider.capability(:public_address)
|
34
|
+
ips.push(ip)
|
35
|
+
elsif @machine.provider_name == :docker
|
36
|
+
ip = @machine.provider.capability(:public_address)
|
37
|
+
ips.push(ip)
|
38
|
+
elsif @machine.provider_name == :libvirt
|
39
|
+
ssh_info = @machine.ssh_info
|
40
|
+
if ssh_info
|
41
|
+
ips.push(ssh_info[:host])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
if not ips.any?
|
45
|
+
ips.push( '127.0.0.1' )
|
20
46
|
end
|
47
|
+
return ips.uniq
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get a hash of hostnames indexed by ip, e.g. { 'ip1': ['host1'], 'ip2': ['host2', 'host3'] }
|
51
|
+
def getHostnames(ips)
|
52
|
+
hostnames = Hash.new { |h, k| h[k] = [] }
|
53
|
+
|
54
|
+
case @machine.config.hostsupdater.aliases
|
55
|
+
when Array
|
56
|
+
# simple list of aliases to link to all ips
|
57
|
+
ips.each do |ip|
|
58
|
+
hostnames[ip] += @machine.config.hostsupdater.aliases
|
59
|
+
end
|
60
|
+
when Hash
|
61
|
+
# complex definition of aliases for various ips
|
62
|
+
@machine.config.hostsupdater.aliases.each do |ip, hosts|
|
63
|
+
hostnames[ip] += Array(hosts)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# handle default hostname(s) if not already specified in the aliases
|
68
|
+
Array(@machine.config.vm.hostname).each do |host|
|
69
|
+
if hostnames.none? { |k, v| v.include?(host) }
|
70
|
+
ips.each do |ip|
|
71
|
+
hostnames[ip].unshift host
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
21
76
|
return hostnames
|
22
77
|
end
|
23
78
|
|
24
|
-
def addHostEntries
|
79
|
+
def addHostEntries
|
25
80
|
ips = getIps
|
26
|
-
hostnames = getHostnames
|
81
|
+
hostnames = getHostnames(ips)
|
27
82
|
file = File.open(@@hosts_path, "rb")
|
28
83
|
hostsContents = file.read
|
29
84
|
uuid = @machine.id
|
30
85
|
name = @machine.name
|
31
86
|
entries = []
|
32
87
|
ips.each do |ip|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
if
|
37
|
-
@ui.info "
|
88
|
+
hostnames[ip].each do |hostname|
|
89
|
+
entryPattern = hostEntryPattern(ip, hostname)
|
90
|
+
|
91
|
+
if hostsContents.match(/#{entryPattern}/)
|
92
|
+
@ui.info "[vagrant-hostsupdater] found entry for: #{ip} #{hostname}"
|
93
|
+
else
|
94
|
+
hostEntry = createHostEntry(ip, hostname, name, uuid)
|
38
95
|
entries.push(hostEntry)
|
39
96
|
end
|
40
97
|
end
|
@@ -48,7 +105,7 @@ module VagrantPlugins
|
|
48
105
|
|
49
106
|
def removeHostEntries
|
50
107
|
if !@machine.id and !@machine.config.hostsupdater.id
|
51
|
-
@ui.
|
108
|
+
@ui.info "[vagrant-hostsupdater] No machine id, nothing removed from #@@hosts_path"
|
52
109
|
return
|
53
110
|
end
|
54
111
|
file = File.open(@@hosts_path, "rb")
|
@@ -56,7 +113,8 @@ module VagrantPlugins
|
|
56
113
|
uuid = @machine.id || @machine.config.hostsupdater.id
|
57
114
|
hashedId = Digest::MD5.hexdigest(uuid)
|
58
115
|
if hostsContents.match(/#{hashedId}/)
|
59
|
-
|
116
|
+
removeFromHosts
|
117
|
+
removeFromSshKnownHosts
|
60
118
|
end
|
61
119
|
end
|
62
120
|
|
@@ -64,21 +122,41 @@ module VagrantPlugins
|
|
64
122
|
%Q(#{ip} #{hostnames.join(' ')} #{signature(name, uuid)})
|
65
123
|
end
|
66
124
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
125
|
+
def createHostEntry(ip, hostname, name, uuid = self.uuid)
|
126
|
+
%Q(#{ip} #{hostname} #{signature(name, uuid.to_s)})
|
127
|
+
end
|
128
|
+
|
129
|
+
# Create a regular expression that will match *any* entry describing the
|
130
|
+
# given IP/hostname pair. This is intentionally generic in order to
|
131
|
+
# recognize entries created by the end user.
|
132
|
+
def hostEntryPattern(ip, hostname)
|
133
|
+
Regexp.new('^\s*' + ip + '\s+' + hostname + '\s*(#.*)?$')
|
73
134
|
end
|
74
135
|
|
75
136
|
def addToHosts(entries)
|
76
137
|
return if entries.length == 0
|
77
138
|
content = entries.join("\n").strip
|
78
|
-
|
79
|
-
|
139
|
+
|
140
|
+
@ui.info "[vagrant-hostsupdater] Writing the following entries to (#@@hosts_path)"
|
141
|
+
@ui.info "[vagrant-hostsupdater] " + entries.join("\n[vagrant-hostsupdater] ")
|
142
|
+
if !File.writable_real?(@@hosts_path)
|
143
|
+
@ui.info "[vagrant-hostsupdater] This operation requires administrative access. You may " +
|
144
|
+
"skip it by manually adding equivalent entries to the hosts file."
|
145
|
+
if !sudo(%Q(sh -c 'echo "#{content}" >> #@@hosts_path'))
|
146
|
+
@ui.error "[vagrant-hostsupdater] Failed to add hosts, could not use sudo"
|
147
|
+
adviseOnSudo
|
148
|
+
end
|
149
|
+
elsif Vagrant::Util::Platform.windows?
|
150
|
+
require 'tmpdir'
|
151
|
+
uuid = @machine.id || @machine.config.hostsupdater.id
|
152
|
+
tmpPath = File.join(Dir.tmpdir, 'hosts-' + uuid + '.cmd')
|
153
|
+
File.open(tmpPath, "w") do |tmpFile|
|
154
|
+
entries.each { |line| tmpFile.puts(">>\"#{@@hosts_path}\" echo #{line}") }
|
155
|
+
end
|
156
|
+
sudo(tmpPath)
|
157
|
+
File.delete(tmpPath)
|
80
158
|
else
|
81
|
-
content = "\n" + content
|
159
|
+
content = "\n" + content + "\n"
|
82
160
|
hostsFile = File.open(@@hosts_path, "a")
|
83
161
|
hostsFile.write(content)
|
84
162
|
hostsFile.close()
|
@@ -88,20 +166,37 @@ module VagrantPlugins
|
|
88
166
|
def removeFromHosts(options = {})
|
89
167
|
uuid = @machine.id || @machine.config.hostsupdater.id
|
90
168
|
hashedId = Digest::MD5.hexdigest(uuid)
|
91
|
-
if !File.
|
92
|
-
sudo(%Q(sed -i -e '/#{hashedId}/ d' #@@hosts_path))
|
169
|
+
if !File.writable_real?(@@hosts_path) || Vagrant::Util::Platform.windows?
|
170
|
+
if !sudo(%Q(sed -i -e '/#{hashedId}/ d' #@@hosts_path))
|
171
|
+
@ui.error "[vagrant-hostsupdater] Failed to remove hosts, could not use sudo"
|
172
|
+
adviseOnSudo
|
173
|
+
end
|
93
174
|
else
|
94
175
|
hosts = ""
|
95
176
|
File.open(@@hosts_path).each do |line|
|
96
177
|
hosts << line unless line.include?(hashedId)
|
97
178
|
end
|
179
|
+
hosts.strip!
|
98
180
|
hostsFile = File.open(@@hosts_path, "w")
|
99
181
|
hostsFile.write(hosts)
|
100
182
|
hostsFile.close()
|
101
183
|
end
|
102
184
|
end
|
103
185
|
|
104
|
-
|
186
|
+
def removeFromSshKnownHosts
|
187
|
+
if !@isWindowsHost
|
188
|
+
ips = getIps
|
189
|
+
hostnames = getHostnames(ips)
|
190
|
+
ips.each do |ip|
|
191
|
+
hostnames[ip].each do |hostname|
|
192
|
+
command = %Q(sed -i -e '/#{hostname}/ d' #@@ssh_known_hosts_path)
|
193
|
+
if system(command)
|
194
|
+
@ui.info "[vagrant-hostsupdater] Removed host: #{hostname} from ssh_known_hosts file: #@@ssh_known_hosts_path"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
105
200
|
|
106
201
|
def signature(name, uuid = self.uuid)
|
107
202
|
hashedId = Digest::MD5.hexdigest(uuid)
|
@@ -111,11 +206,51 @@ module VagrantPlugins
|
|
111
206
|
def sudo(command)
|
112
207
|
return if !command
|
113
208
|
if Vagrant::Util::Platform.windows?
|
114
|
-
|
209
|
+
require 'win32ole'
|
210
|
+
args = command.split(" ")
|
211
|
+
command = args.shift
|
212
|
+
sh = WIN32OLE.new('Shell.Application')
|
213
|
+
sh.ShellExecute(command, args.join(" "), '', 'runas', 0)
|
115
214
|
else
|
116
|
-
|
215
|
+
return system("sudo #{command}")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def adviseOnSudo
|
220
|
+
@ui.error "[vagrant-hostsupdater] Consider adding the following to your sudoers file:"
|
221
|
+
@ui.error "[vagrant-hostsupdater] https://github.com/cogitatio/vagrant-hostsupdater#suppressing-prompts-for-elevating-privileges"
|
222
|
+
end
|
223
|
+
|
224
|
+
def getAwsPublicIp
|
225
|
+
return nil if ! Vagrant.has_plugin?("vagrant-aws")
|
226
|
+
aws_conf = @machine.config.vm.get_provider_config(:aws)
|
227
|
+
return nil if ! aws_conf.is_a?(VagrantPlugins::AWS::Config)
|
228
|
+
filters = ( aws_conf.tags || [] ).map {|k,v| sprintf('"Name=tag:%s,Values=%s"', k, v) }.join(' ')
|
229
|
+
return nil if filters == ''
|
230
|
+
cmd = 'aws ec2 describe-instances --filter '+filters
|
231
|
+
stdout, stderr, stat = Open3.capture3(cmd)
|
232
|
+
@ui.error sprintf("Failed to execute '%s' : %s", cmd, stderr) if stderr != ''
|
233
|
+
return nil if stat.exitstatus != 0
|
234
|
+
begin
|
235
|
+
return JSON.parse(stdout)["Reservations"].first()["Instances"].first()["PublicIpAddress"]
|
236
|
+
rescue => e
|
237
|
+
@ui.error sprintf("Failed to get IP from the result of '%s' : %s", cmd, e.message)
|
238
|
+
return nil
|
117
239
|
end
|
118
240
|
end
|
241
|
+
|
242
|
+
def getGooglePublicIp
|
243
|
+
return nil if ! defined?(VagrantPlugins::Google)
|
244
|
+
google_conf = @machine.config.vm.get_provider_config(:google)
|
245
|
+
return nil if ! google_conf.is_a?(VagrantPlugins::Google::Config)
|
246
|
+
cmd = 'gcloud compute instances list --filter="name=%s" --format="value(networkInterfaces[0].accessConfigs[0].natIP)"'
|
247
|
+
cmd = sprintf(cmd, google_conf.name)
|
248
|
+
stdout, stderr, stat = Open3.capture3(cmd)
|
249
|
+
@ui.error "Failed to execute '#{cmd}' : #{stderr}" if stderr != ''
|
250
|
+
ip = stdout.strip
|
251
|
+
return nil if stat.exitstatus != 0 || ip == nil || ip == ''
|
252
|
+
return ip
|
253
|
+
end
|
119
254
|
end
|
120
255
|
end
|
121
256
|
end
|
@@ -20,6 +20,10 @@ module VagrantPlugins
|
|
20
20
|
hook.append(Action::UpdateHosts)
|
21
21
|
end
|
22
22
|
|
23
|
+
action_hook(:hostsupdater, :machine_action_provision) do |hook|
|
24
|
+
hook.before(Vagrant::Action::Builtin::Provision, Action::UpdateHosts)
|
25
|
+
end
|
26
|
+
|
23
27
|
action_hook(:hostsupdater, :machine_action_halt) do |hook|
|
24
28
|
hook.append(Action::RemoveHosts)
|
25
29
|
end
|
@@ -37,10 +41,12 @@ module VagrantPlugins
|
|
37
41
|
end
|
38
42
|
|
39
43
|
action_hook(:hostsupdater, :machine_action_reload) do |hook|
|
44
|
+
hook.prepend(Action::RemoveHosts)
|
40
45
|
hook.append(Action::UpdateHosts)
|
41
46
|
end
|
42
47
|
|
43
48
|
action_hook(:hostsupdater, :machine_action_resume) do |hook|
|
49
|
+
hook.prepend(Action::RemoveHosts)
|
44
50
|
hook.append(Action::UpdateHosts)
|
45
51
|
end
|
46
52
|
|
@@ -4,20 +4,20 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'vagrant-hostsupdater/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'vagrant-hostsupdater'
|
8
8
|
spec.version = VagrantPlugins::HostsUpdater::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Falk Kühnel', 'Chris Smith']
|
10
|
+
spec.email = ['fk@cogitatio.de', 'chris@cgsmith.net']
|
11
11
|
spec.description = %q{Enables Vagrant to update hosts file on the host machine}
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
12
|
+
spec.summary = spec.description
|
13
|
+
spec.homepage = 'https://github.com/cogitatio/vagrant-hostsupdater'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
23
|
end
|
metadata
CHANGED
@@ -1,51 +1,53 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-hostsupdater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Falk Kühnel
|
8
|
+
- Chris Smith
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2020-11-24 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bundler
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- - ~>
|
18
|
+
- - "~>"
|
18
19
|
- !ruby/object:Gem::Version
|
19
20
|
version: '1.3'
|
20
21
|
type: :development
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
|
-
- - ~>
|
25
|
+
- - "~>"
|
25
26
|
- !ruby/object:Gem::Version
|
26
27
|
version: '1.3'
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
29
|
name: rake
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- -
|
32
|
+
- - ">="
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: '0'
|
34
35
|
type: :development
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
|
-
- -
|
39
|
+
- - ">="
|
39
40
|
- !ruby/object:Gem::Version
|
40
41
|
version: '0'
|
41
42
|
description: Enables Vagrant to update hosts file on the host machine
|
42
43
|
email:
|
43
44
|
- fk@cogitatio.de
|
45
|
+
- chris@cgsmith.net
|
44
46
|
executables: []
|
45
47
|
extensions: []
|
46
48
|
extra_rdoc_files: []
|
47
49
|
files:
|
48
|
-
- .gitignore
|
50
|
+
- ".gitignore"
|
49
51
|
- Gemfile
|
50
52
|
- LICENSE.txt
|
51
53
|
- README.md
|
@@ -70,17 +72,16 @@ require_paths:
|
|
70
72
|
- lib
|
71
73
|
required_ruby_version: !ruby/object:Gem::Requirement
|
72
74
|
requirements:
|
73
|
-
- -
|
75
|
+
- - ">="
|
74
76
|
- !ruby/object:Gem::Version
|
75
77
|
version: '0'
|
76
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
79
|
requirements:
|
78
|
-
- -
|
80
|
+
- - ">="
|
79
81
|
- !ruby/object:Gem::Version
|
80
82
|
version: '0'
|
81
83
|
requirements: []
|
82
|
-
|
83
|
-
rubygems_version: 2.0.3
|
84
|
+
rubygems_version: 3.1.2
|
84
85
|
signing_key:
|
85
86
|
specification_version: 4
|
86
87
|
summary: Enables Vagrant to update hosts file on the host machine
|