app_hosts 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ app_hosts-*.gem
3
+ config
4
+ config/**/*
5
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'http://rubygems.org'
2
+
3
+ group :development, :test do
4
+ gem 'rspec-rails', '>= 2.0.0.beta.22'
5
+ end
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.
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,2 @@
1
+ require "app_hosts/version"
2
+ require File.dirname(__FILE__) + '/app_hosts/host_manager.rb'
@@ -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,3 @@
1
+ module AppHosts
2
+ VERSION = "0.0.3"
3
+ 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
@@ -0,0 +1,7 @@
1
+ hosts_file_path: /path/to/hosts
2
+ host: www.example.com
3
+ addresses:
4
+ development: 127.0.0.1
5
+ staging: 127.0.0.2
6
+ beta: 127.0.0.3
7
+ production: 127.0.0.4
@@ -0,0 +1,5 @@
1
+ # first line comment
2
+
3
+ 127.0.0.1 www.example.com example.com
4
+ 127.0.0.2 hello-example.com
5
+ # last line comment
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