app_hosts 0.0.3
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.
- data/.gitignore +5 -0
- data/Gemfile +5 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +12 -0
- data/app_hosts.gemspec +17 -0
- data/lib/app_hosts.rb +2 -0
- data/lib/app_hosts/host_manager.rb +107 -0
- data/lib/app_hosts/version.rb +3 -0
- data/lib/tasks/hosts_manager.rake +17 -0
- data/spec/app_host_spec.rb +128 -0
- data/spec/fixtures/app_hosts.yml +7 -0
- data/spec/fixtures/hosts +5 -0
- metadata +64 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Andrea Franz
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# AppHosts
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'app_hosts'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install app_hosts
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
Dir[File.dirname(__FILE__) + '/lib/**/*.rake'].each{ |file| load file }
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
8
|
+
t.rspec_opts = %w[--color --format documentation]
|
9
|
+
t.pattern = 'spec/*_spec.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => :spec
|
data/app_hosts.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/app_hosts/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Andrea Franz"]
|
6
|
+
gem.email = ["andrea@gravityblast.com"]
|
7
|
+
gem.description = %q{Application based /etc/hosts manager}
|
8
|
+
gem.summary = %q{}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "app_hosts"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = AppHosts::VERSION
|
17
|
+
end
|
data/lib/app_hosts.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module AppHosts
|
4
|
+
class HostManager
|
5
|
+
|
6
|
+
attr_reader :hosts, :lines
|
7
|
+
|
8
|
+
def initialize config_file_path
|
9
|
+
@lines = []
|
10
|
+
@parsed = false
|
11
|
+
@config = YAML.load_file config_file_path
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse file_path=@config['hosts_file_path']
|
15
|
+
@file_path = file_path
|
16
|
+
parse_file file_path
|
17
|
+
@parsed = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_ip_by_name name
|
21
|
+
pair = @config['addresses'].find{|key, value| key == name}
|
22
|
+
pair ? pair.last : nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def switch_ip_to named_host, file_path=@file_path
|
26
|
+
new_ip = find_ip_by_name named_host
|
27
|
+
raise "Named host not found: #{named_host}" unless new_ip
|
28
|
+
replace_ip @config['host'], new_ip, file_path
|
29
|
+
end
|
30
|
+
|
31
|
+
def replace_ip host, new_ip, file_path=@file_path
|
32
|
+
raise "You should parse original file before replacing ip address." unless @parsed
|
33
|
+
|
34
|
+
buffer = ''
|
35
|
+
|
36
|
+
found = false
|
37
|
+
@lines.each do |line|
|
38
|
+
line = if line[:host] == host
|
39
|
+
found = true
|
40
|
+
build_line new_ip, line[:host], line[:aliases]
|
41
|
+
else
|
42
|
+
line[:text]
|
43
|
+
end
|
44
|
+
buffer << "#{line}\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
buffer << "#{build_line(new_ip, host)}\n" if !found
|
48
|
+
write_file buffer, file_path
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_line ip, host, aliases=[]
|
52
|
+
"#{ip} #{host} #{aliases.join(' ')}".strip
|
53
|
+
end
|
54
|
+
|
55
|
+
def replace_ip_to_line line, new_ip
|
56
|
+
new_line = ""
|
57
|
+
line_attributes = parse_line line.strip.chomp
|
58
|
+
if !line_attributes.nil?
|
59
|
+
ip, attributes = line_attributes
|
60
|
+
new_line << build_line(new_ip, attributes[:host], attributes[:aliases])
|
61
|
+
end
|
62
|
+
new_line
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def write_file buffer, file_path
|
68
|
+
buffer.gsub!(/"/, '\\"')
|
69
|
+
buffer.gsub!(/'/){ |match| %|"'"\\'"'"|}
|
70
|
+
cmd = "echo"
|
71
|
+
if @config['use_sudo']
|
72
|
+
system %|sudo sh -c '#{cmd} "#{buffer}\\c" > "#{file_path}"'|
|
73
|
+
else
|
74
|
+
system %|#{cmd} "#{buffer}\\c" > "#{file_path}"|
|
75
|
+
end
|
76
|
+
end
|
77
|
+
def parse_file file_path
|
78
|
+
each_file_line file_path do |line|
|
79
|
+
line_attributes = parse_line line
|
80
|
+
if !line_attributes.nil?
|
81
|
+
ip, attributes = line_attributes
|
82
|
+
@lines << { :ip => ip, :host => attributes[:host], :aliases => attributes[:aliases], :text => line }
|
83
|
+
else
|
84
|
+
@lines << { :text => line }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def each_file_line file_path
|
90
|
+
File.open file_path, 'r' do |file|
|
91
|
+
file.each do |line|
|
92
|
+
yield line.chomp.strip
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def parse_line line
|
98
|
+
return nil if line.size == 0 || line =~ /^\s*#/
|
99
|
+
attributes = line.split.collect &:strip
|
100
|
+
[
|
101
|
+
attributes.shift,
|
102
|
+
:host => attributes.shift,
|
103
|
+
:aliases => attributes
|
104
|
+
]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../app_hosts'
|
2
|
+
|
3
|
+
namespace :app_hosts do
|
4
|
+
desc 'Switch'
|
5
|
+
task :switch, :named_host do |task, args|
|
6
|
+
named_host = args[:named_host].to_s.strip
|
7
|
+
raise "You must specify the named host: rake app_hosts:switch[NAMED_HOST]" if named_host.size == 0
|
8
|
+
in_file = File.dirname(__FILE__) + '/../../spec/fixtures/hosts'
|
9
|
+
out_file = 'test.txt'
|
10
|
+
host = 'www.example.com'
|
11
|
+
ip = '2.2.2.2'
|
12
|
+
|
13
|
+
manager = AppHosts::HostManager.new 'config/app_hosts.yml'
|
14
|
+
manager.parse
|
15
|
+
manager.switch_ip_to named_host
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/app_hosts'
|
3
|
+
|
4
|
+
describe AppHosts do
|
5
|
+
before(:each) do
|
6
|
+
@manager = AppHosts::HostManager.new File.dirname(__FILE__) + '/fixtures/app_hosts.yml'
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should parse line' do
|
10
|
+
line = ' 127.0.0.1 example.com www.example.com beta.example.com '
|
11
|
+
@manager.send(:parse_line, line).should == ['127.0.0.1', {
|
12
|
+
:host => 'example.com',
|
13
|
+
:aliases => ['www.example.com', 'beta.example.com']
|
14
|
+
}]
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should not parse comments' do
|
18
|
+
line = ' # 127.0.0.1 example.com www.example.com beta.example.com '
|
19
|
+
@manager.send(:parse_line, line).should be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should save file lines' do
|
23
|
+
@manager.parse File.dirname(__FILE__) + '/fixtures/hosts'
|
24
|
+
lines = [
|
25
|
+
{:text => "# first line comment"},
|
26
|
+
{:text => ""},
|
27
|
+
{:text => "127.0.0.1 www.example.com example.com", :ip => '127.0.0.1', :host => 'www.example.com', :aliases => ['example.com']},
|
28
|
+
{:text => "127.0.0.2 hello-example.com", :ip => '127.0.0.2', :host => 'hello-example.com', :aliases => []},
|
29
|
+
{:text => "# last line comment"}
|
30
|
+
]
|
31
|
+
@manager.lines.should =~ lines
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should replace ip address to line' do
|
35
|
+
line = '127.0.0.1 example.com www.example.com beta.example.com'
|
36
|
+
new_ip = '127.0.0.2'
|
37
|
+
new_line = "#{new_ip} example.com www.example.com beta.example.com"
|
38
|
+
@manager.replace_ip_to_line(line, new_ip).should == new_line
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should parse config file' do
|
42
|
+
config = {
|
43
|
+
'hosts_file_path' => '/path/to/hosts',
|
44
|
+
'host' => 'www.example.com',
|
45
|
+
'addresses' => {
|
46
|
+
'development' => '127.0.0.1',
|
47
|
+
'staging' => '127.0.0.2',
|
48
|
+
'beta' => '127.0.0.3',
|
49
|
+
'production' => '127.0.0.4'
|
50
|
+
}
|
51
|
+
}
|
52
|
+
@manager.instance_variable_get('@config').should == config
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should find host ip by name' do
|
56
|
+
{
|
57
|
+
'development' => '127.0.0.1',
|
58
|
+
'staging' => '127.0.0.2',
|
59
|
+
'beta' => '127.0.0.3',
|
60
|
+
'production' => '127.0.0.4'
|
61
|
+
}.each do |name, ip|
|
62
|
+
@manager.find_ip_by_name(name).should == ip
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should not find undefined address' do
|
67
|
+
@manager.find_ip_by_name('undefined-name').should be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should replace ip for specified host' do
|
71
|
+
tmp_path = File.dirname(__FILE__) + '/../tmp'
|
72
|
+
host = "www.example.com"
|
73
|
+
new_ip = '1.1.1.1'
|
74
|
+
original_file_path = File.dirname(__FILE__) + '/fixtures/hosts'
|
75
|
+
output_file_path = '/tmp/new_hosts.txt'
|
76
|
+
new_content = <<-FILE
|
77
|
+
# first line comment
|
78
|
+
|
79
|
+
#{new_ip} www.example.com example.com
|
80
|
+
127.0.0.2 hello-example.com
|
81
|
+
# last line comment
|
82
|
+
FILE
|
83
|
+
@manager.should_receive(:write_file).with(new_content, output_file_path)
|
84
|
+
@manager.parse original_file_path
|
85
|
+
@manager.replace_ip host, new_ip, output_file_path
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should replace ip for specified named host' do
|
89
|
+
tmp_path = File.dirname(__FILE__) + '/../tmp'
|
90
|
+
original_file_path = File.dirname(__FILE__) + '/fixtures/hosts'
|
91
|
+
output_file_path = '/tmp/new_hosts.txt'
|
92
|
+
named_host = 'production'
|
93
|
+
new_ip = @manager.instance_variable_get('@config')['addresses']['production']
|
94
|
+
new_content = <<-FILE
|
95
|
+
# first line comment
|
96
|
+
|
97
|
+
#{new_ip} www.example.com example.com
|
98
|
+
127.0.0.2 hello-example.com
|
99
|
+
# last line comment
|
100
|
+
FILE
|
101
|
+
@manager.should_receive(:write_file).with(new_content, output_file_path)
|
102
|
+
@manager.parse original_file_path
|
103
|
+
@manager.switch_ip_to named_host, output_file_path
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should add ip and hosts if not already specified' do
|
107
|
+
original_file_path = File.dirname(__FILE__) + '/fixtures/hosts'
|
108
|
+
output_file_path = '/tmp/new_hosts.txt'
|
109
|
+
named_host = 'production'
|
110
|
+
|
111
|
+
config = @manager.instance_variable_get('@config')
|
112
|
+
config['host'] = 'new-example.com'
|
113
|
+
@manager.instance_variable_set('@config', config)
|
114
|
+
|
115
|
+
new_ip = @manager.instance_variable_get('@config')['addresses']['production']
|
116
|
+
new_content = <<-FILE
|
117
|
+
# first line comment
|
118
|
+
|
119
|
+
127.0.0.1 www.example.com example.com
|
120
|
+
127.0.0.2 hello-example.com
|
121
|
+
# last line comment
|
122
|
+
#{new_ip} new-example.com
|
123
|
+
FILE
|
124
|
+
@manager.should_receive(:write_file).with(new_content, output_file_path)
|
125
|
+
@manager.parse original_file_path
|
126
|
+
@manager.switch_ip_to named_host, output_file_path
|
127
|
+
end
|
128
|
+
end
|
data/spec/fixtures/hosts
ADDED
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: app_hosts
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Andrea Franz
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-13 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Application based /etc/hosts manager
|
15
|
+
email:
|
16
|
+
- andrea@gravityblast.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- LICENSE
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- app_hosts.gemspec
|
27
|
+
- lib/app_hosts.rb
|
28
|
+
- lib/app_hosts/host_manager.rb
|
29
|
+
- lib/app_hosts/version.rb
|
30
|
+
- lib/tasks/hosts_manager.rake
|
31
|
+
- spec/app_host_spec.rb
|
32
|
+
- spec/fixtures/app_hosts.yml
|
33
|
+
- spec/fixtures/hosts
|
34
|
+
homepage: ''
|
35
|
+
licenses: []
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
hash: -976389179289596147
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
requirements: []
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.8.24
|
58
|
+
signing_key:
|
59
|
+
specification_version: 3
|
60
|
+
summary: ''
|
61
|
+
test_files:
|
62
|
+
- spec/app_host_spec.rb
|
63
|
+
- spec/fixtures/app_hosts.yml
|
64
|
+
- spec/fixtures/hosts
|