alkesh-ghost 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Bodaniel Jeanes
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,111 @@
1
+ Ghost
2
+ =====
3
+
4
+ A gem that allows you to create, list, and modify local hostnames
5
+ with ease in linux and OS (more to come)...
6
+
7
+ Requirements
8
+ ============
9
+
10
+ Unix-based OS (for now)
11
+
12
+ Intended Usage
13
+ ==============
14
+
15
+ This gem is designed primarily for web developers who need to add
16
+ and modify hostnames to their system for virtual hosts on their
17
+ local/remote web server. However, it could be of use to other people
18
+ who would otherwise modify their `/etc/hosts` file manually and
19
+ flush the cache.
20
+
21
+ Command
22
+ -------
23
+
24
+ $ ghost add mydevsite.local
25
+ [Adding] mydevsite.local -> 127.0.0.1
26
+
27
+ $ ghost add staging-server.local 67.207.136.164
28
+ [Adding] staging-server.local -> 67.207.136.164
29
+
30
+ $ ghost list
31
+ Listing 2 host(s):
32
+ mydevsite.local -> 127.0.0.1
33
+ staging-server.local -> 67.207.136.164
34
+
35
+ $ ghost delete mydevsite.local
36
+ [Deleting] mydevsite.local
37
+
38
+ $ ghost delete_matching test
39
+ [Deleting] test2.local
40
+ [Deleting] test.local
41
+
42
+ $ ghost list
43
+ Listing 1 host(s):
44
+ staging-server.local -> 67.207.136.164
45
+
46
+ $ ghost modify staging-server.local 64.233.167.99
47
+ [Modifying] staging-server.local -> 64.233.167.99
48
+
49
+ $ ghost list
50
+ Listing 1 host(s):
51
+ staging-server.local -> 64.233.167.99
52
+
53
+ $ ghost export > some_file
54
+
55
+ $ ghost empty
56
+ [Emptying] Done.
57
+
58
+ $ ghost list
59
+ Listing 0 host(s):
60
+
61
+ $ ghost import some_file
62
+ [Adding] staging-server.local -> 64.233.167.99
63
+
64
+ $ ghost list
65
+ Listing 1 host(s):
66
+ staging-server.local -> 64.233.167.99
67
+
68
+ Library
69
+ -------
70
+
71
+ There is also a library that can be used in Ruby scripts. The `ghost`
72
+ command is a wrapper for the library. View the source of `bin/ghost`
73
+ to see how to use the library.
74
+
75
+ Installation
76
+ ============
77
+
78
+ sudo gem install ghost
79
+
80
+ Contributors
81
+ ============
82
+
83
+ * [Bodaniel Jeanes](http://github.com/bjeanes)
84
+ * [Ben Hoskings](http://github.com/benhoskings)
85
+ * [Mitchell V Riley](http://github.com/mitchellvriley)
86
+ * [Courtois Simon](http://github.com/simonc)
87
+ * [Justin Mazzi](http://github.com/jmazzi)
88
+
89
+ Legal Stuff
90
+ ===========
91
+
92
+ Copyright (c) 2008-2010 Bodaniel Jeanes
93
+
94
+ Permission is hereby granted, free of charge, to any person obtaining
95
+ a copy of this software and associated documentation files (the
96
+ "Software"), to deal in the Software without restriction, including
97
+ without limitation the rights to use, copy, modify, merge, publish,
98
+ distribute, sublicense, and/or sell copies of the Software, and to
99
+ permit persons to whom the Software is furnished to do so, subject to
100
+ the following conditions:
101
+
102
+ The above copyright notice and this permission notice shall be
103
+ included in all copies or substantial portions of the Software.
104
+
105
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
106
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
107
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
108
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
109
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
110
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
111
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rubygems/specification'
4
+ require 'date'
5
+
6
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
7
+
8
+
9
+ #### MISC TASKS ####
10
+
11
+ desc "list tasks"
12
+ task :default do
13
+ puts `rake -T`.grep(/^[^(].*$/)
14
+ end
15
+
16
+ desc "Outstanding TODO's"
17
+ task :todo do
18
+ files = ["**/*.{rb,rake}" "bin/*", "README.mkdn"]
19
+
20
+ File.open('TODO','w') do |f|
21
+ FileList[*files].egrep(/TODO|FIXME/) do |file, line, text|
22
+ output = "#{file}:#{line} - #{text.chomp.gsub(/^\s+|\s+$/ , "")}"
23
+
24
+ puts output
25
+ f.puts output
26
+ end
27
+ end
28
+ end
data/TODO ADDED
File without changes
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Bodaniel Jeanes on 2008-8-19.
4
+ # Copyright (c) 2008. All rights reserved.
5
+
6
+ begin
7
+ require 'rubygems'
8
+ rescue LoadError
9
+ # no rubygems to load, so we fail silently
10
+ end
11
+ require 'ghost'
12
+
13
+ def help_text(exit_code = 0)
14
+ script_name = File.basename $0
15
+ puts """USAGE: #{script_name} add <hostname> [<ip=127.0.1.1>]
16
+ #{script_name} modify <hostname> <ip> OR <hostname> (will lookup ip)
17
+ #{script_name} delete <hostname>
18
+ #{script_name} delete_matching <pattern>
19
+ #{script_name} list
20
+ #{script_name} empty
21
+ #{script_name} export
22
+ #{script_name} import <file>
23
+ """
24
+ exit(exit_code)
25
+ end
26
+
27
+ if ARGV.size.zero? || ['-h', '--help', 'help'].include?(ARGV.first)
28
+ help_text
29
+ else
30
+ case ARGV[0]
31
+ when 'add'
32
+ if [2,3].include?(ARGV.size)
33
+ begin
34
+ ARGV.shift
35
+ host = Host.add(*ARGV)
36
+ puts " [Adding] #{host.name} -> #{host.ip}"
37
+ exit 0
38
+ rescue SocketError
39
+ $stderr.puts "Cannot find ip for host"
40
+ exit 3
41
+ rescue StandardError
42
+ $stderr.puts "Cannot overwrite an existing entry. Use the modify subcommand"
43
+ exit 3
44
+ end
45
+ else
46
+ $stderr.puts "The add subcommand requires at least a hostname.\n\n"
47
+ help_text 2
48
+ end
49
+ when 'modify'
50
+ if ARGV.size == 3
51
+ ARGV.shift
52
+ ARGV << true
53
+ host = Host.add(*ARGV)
54
+ puts " [Modifying] #{host.name} -> #{host.ip}"
55
+ exit 0
56
+ else
57
+ $stderr.puts "The modify subcommand requires a hostname and an IP.\n\n"
58
+ help_text 4
59
+ end
60
+ when 'delete', 'del', 'remove', 'rm'
61
+ if ARGV.size == 2
62
+ Host.delete(ARGV[1])
63
+ puts " [Deleting] #{ARGV[1]}"
64
+ exit 0
65
+ else
66
+ $stderr.puts "The delete subcommand requires a hostname.\n\n"
67
+ help_text 2
68
+ end
69
+ when 'delete_matching'
70
+ if ARGV.size == 2
71
+ matched = Host.delete_matching(ARGV[1])
72
+ if matched.empty?
73
+ puts " No matching entries found"
74
+ else
75
+ matched.each { |h| puts " [Deleting] #{h}" }
76
+ end
77
+ exit 0
78
+ else
79
+ $stderr.puts "The delete_matching subcommand requires a hostname pattern.\n\n"
80
+ help_text 2
81
+ end
82
+ when 'list'
83
+ hosts = Host.list
84
+ pad = hosts.max{|a,b| a.to_s.length <=> b.to_s.length }.to_s.length
85
+
86
+ puts "Listing #{hosts.size} host(s):"
87
+
88
+ hosts.each do |host|
89
+ puts "#{host.name.rjust(pad+2)} -> #{host.ip}"
90
+ end
91
+ exit 0
92
+ when 'empty'
93
+ print " [Emptying] "
94
+ Host.empty!
95
+ puts "Done."
96
+ exit 0
97
+ when 'export'
98
+ hosts = Host.list
99
+ hosts.each do |host|
100
+ puts "#{host.name} #{host.ip}"
101
+ end
102
+ exit 0
103
+ when 'import'
104
+ if ARGV.size == 2
105
+ begin
106
+ File.foreach(ARGV[1]) do |line|
107
+ host_infos = line.strip.split(' ', 2)
108
+ host = Host.add(*host_infos)
109
+ puts " [Adding] #{host.name} -> #{host.ip}"
110
+ end
111
+ exit 0
112
+ rescue
113
+ $stderr.puts "Cannot import. A problem occured while opening the import file."
114
+ exit 5
115
+ end
116
+ else
117
+ $stderr.puts "The import command requires an input file.\n\n"
118
+ help_text 6
119
+ end
120
+ else
121
+ $stderr.puts "Invalid option: #{ARGV[0]}"
122
+ help_text 1
123
+ end
124
+ end
@@ -0,0 +1,8 @@
1
+ $: << File.dirname(__FILE__)
2
+
3
+ case RUBY_PLATFORM
4
+ when /darwin/
5
+ require 'ghost/mac-host'
6
+ when /linux/
7
+ require 'ghost/linux-host'
8
+ end
@@ -0,0 +1,92 @@
1
+ require 'socket'
2
+
3
+ class Host
4
+ attr_reader :host, :ip
5
+
6
+ def initialize(host, ip)
7
+ @host = host
8
+ @ip = ip
9
+ end
10
+
11
+ def ==(other)
12
+ @host == other.host && @ip = other.ip
13
+ end
14
+
15
+ alias :to_s :host
16
+ alias :name :host
17
+ alias :hostname :host
18
+
19
+ @@hosts_file = '/etc/hosts'
20
+ @@permanent_hosts = [Host.new("localhost", "127.0.0.1"),
21
+ Host.new(`hostname`.chomp, "127.0.0.1")]
22
+ class << self
23
+ protected :new
24
+
25
+ def list
26
+ entries = []
27
+ File.open(@@hosts_file).each do |line|
28
+ next if line =~ /^#/
29
+ if line =~ /^(\d+\.\d+\.\d+\.\d+)\s+(.*)$/
30
+ ip = $1
31
+ hosts = $2.split(/\s+/)
32
+ hosts.each { |host| entries << Host.new(host, ip) }
33
+ end
34
+ end
35
+ entries.delete_if { |host| @@permanent_hosts.include? host }
36
+ entries
37
+ end
38
+
39
+ def add(host, ip = "127.0.0.1", force = false)
40
+ if find_by_host(host).nil? || force
41
+ delete(host)
42
+
43
+ unless ip[/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/]
44
+ ip = Socket.gethostbyname(ip)[3].bytes.to_a.join('.')
45
+ end
46
+
47
+ new_host = Host.new(host, ip)
48
+
49
+ hosts = list
50
+ hosts << new_host
51
+ write_out!(hosts)
52
+
53
+ new_host
54
+ else
55
+ raise "Can not overwrite existing record"
56
+ end
57
+ end
58
+
59
+ def find_by_host(hostname)
60
+ list.find{ |host| host.hostname == hostname }
61
+ end
62
+
63
+ def find_by_ip(ip)
64
+ list.find_all{ |host| host.ip == ip }
65
+ end
66
+
67
+ def empty!
68
+ write_out!([])
69
+ end
70
+
71
+ def delete(name)
72
+ hosts = list
73
+ hosts = hosts.delete_if { |host| host.name == name }
74
+ write_out!(hosts)
75
+ end
76
+
77
+ def delete_matching(pattern)
78
+ pattern = Regexp.escape(pattern)
79
+ hosts = list.select { |host| host.name.match(/#{pattern}/) }
80
+ hosts.each { |host| delete(host.name) }
81
+ hosts
82
+ end
83
+
84
+ protected
85
+
86
+ def write_out!(hosts)
87
+ hosts += @@permanent_hosts
88
+ output = hosts.inject("") {|s, h| s + "#{h.ip} #{h.hostname}\n" }
89
+ File.open(@@hosts_file, 'w') {|f| f.print output }
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,114 @@
1
+ require 'socket'
2
+
3
+ class Host
4
+ ListCmd = "dscl localhost -list /Local/Default/Hosts 2>&1"
5
+ ReadCmd = "dscl localhost -read /Local/Default/Hosts/%s 2>&1"
6
+ CreateCmd = "sudo dscl localhost -create /Local/Default/Hosts/%s IPAddress %s 2>&1"
7
+ DeleteCmd = "sudo dscl localhost -delete /Local/Default/Hosts/%s 2>&1"
8
+
9
+ class << self
10
+ protected :new
11
+
12
+ def list
13
+ list = `#{ListCmd}`
14
+ list = list.split("\n")
15
+ list.collect { |host| Host.new(host.chomp) }
16
+ end
17
+
18
+ def add(host, ip = "127.0.0.1", force = false)
19
+ if find_by_host(host).nil? || force
20
+ unless ip[/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/]
21
+ ip = Socket.gethostbyname(ip)[3].bytes.to_a.join('.')
22
+ end
23
+
24
+ `#{CreateCmd % [host, ip]}`
25
+ flush!
26
+ find_by_host(host)
27
+ else
28
+ raise "Can not overwrite existing record"
29
+ end
30
+ end
31
+
32
+ def find_by_host(host)
33
+ @hosts ||= {}
34
+ @hosts[host] ||= begin
35
+ output = `#{ReadCmd % host}`
36
+
37
+ if output =~ /eDSRecordNotFound/
38
+ nil
39
+ else
40
+ host = parse_host(output)
41
+ ip = parse_ip(output)
42
+
43
+ Host.new(host, ip)
44
+ end
45
+ end
46
+ end
47
+
48
+ def find_by_ip(ip)
49
+ nil
50
+ end
51
+
52
+ def empty!
53
+ list.each { |h| delete(h) }
54
+ nil
55
+ end
56
+
57
+ def delete(host)
58
+ `#{DeleteCmd % host.to_s}`
59
+ flush!
60
+ end
61
+
62
+ def delete_matching(pattern)
63
+ pattern = Regexp.escape(pattern)
64
+ hosts = list.select { |h| h.to_s.match(/#{pattern}/) }
65
+ hosts.each do |h|
66
+ delete(h)
67
+ end
68
+ flush! unless hosts.empty?
69
+ hosts
70
+ end
71
+
72
+ # Flushes the DNS Cache
73
+ def flush!
74
+ `dscacheutil -flushcache`
75
+ @hosts = {}
76
+ true
77
+ end
78
+
79
+ protected
80
+ def parse_host(output)
81
+ parse_value(output, 'RecordName')
82
+ end
83
+
84
+ def parse_ip(output)
85
+ parse_value(output, 'IPAddress')
86
+ end
87
+
88
+ def parse_value(output, key)
89
+ match = output.match(Regexp.new("^#{key}: (.*)$"))
90
+ match[1] unless match.nil?
91
+ end
92
+ end
93
+
94
+ def initialize(host, ip=nil)
95
+ @host = host
96
+ @ip = ip
97
+ end
98
+
99
+ def hostname
100
+ @host
101
+ end
102
+ alias :to_s :hostname
103
+ alias :host :hostname
104
+ alias :name :hostname
105
+
106
+ def ip
107
+ @ip ||= self.class.send(:parse_ip, dump)
108
+ end
109
+
110
+ private
111
+ def dump
112
+ @dump ||= `#{ReadCmd % hostname}`
113
+ end
114
+ end
@@ -0,0 +1,155 @@
1
+ require 'ghost/linux-host'
2
+
3
+ $hosts_file = File.expand_path(File.join(File.dirname(__FILE__), "etc_hosts"))
4
+
5
+ describe Host do
6
+ before(:all) do
7
+ class Host
8
+ @@hosts_file = $hosts_file
9
+ end
10
+ end
11
+ before { `touch #{$hosts_file.inspect}` }
12
+ after { `rm -f #{$hosts_file.inspect}` }
13
+
14
+ it "has an IP" do
15
+ hostname = 'ghost-test-hostname.local'
16
+
17
+ Host.add(hostname)
18
+ host = Host.list.first
19
+ host.ip.should eql('127.0.0.1')
20
+
21
+ Host.empty!
22
+
23
+ ip = '169.254.23.121'
24
+ host = Host.add(hostname, ip)
25
+ host.ip.should eql(ip)
26
+ end
27
+
28
+ it "has a hostname" do
29
+ hostname = 'ghost-test-hostname.local'
30
+
31
+ Host.add(hostname)
32
+ host = Host.list.first
33
+ host.hostname.should eql(hostname)
34
+
35
+ Host.empty!
36
+
37
+ ip = '169.254.23.121'
38
+ Host.add(hostname, ip)
39
+ host.hostname.should eql(hostname)
40
+ end
41
+
42
+ describe ".list" do
43
+ it "returns an array" do
44
+ Host.list.should be_instance_of(Array)
45
+ end
46
+
47
+ it "contains instances of Host" do
48
+ Host.add('ghost-test-hostname.local')
49
+ Host.list.first.should be_instance_of(Host)
50
+ end
51
+
52
+ it "gets all hosts on a single /etc/hosts line" do
53
+ example = "127.0.0.1\tproject_a.local\t\t\tproject_b.local project_c.local"
54
+ File.open($hosts_file, 'w') {|f| f << example}
55
+ hosts = Host.list
56
+ hosts.should have(3).items
57
+ hosts.map{|h|h.ip}.uniq.should == ['127.0.0.1']
58
+ hosts.map{|h|h.host}.sort.should == %w[project_a.local project_b.local project_c.local]
59
+ Host.add("project_d.local")
60
+ Host.list.should have(4).items
61
+ end
62
+ end
63
+
64
+ describe "#to_s" do
65
+ it "returns hostname" do
66
+ hostname = 'ghost-test-hostname.local'
67
+
68
+ Host.add(hostname)
69
+ host = Host.list.first
70
+ host.to_s.should eql(hostname)
71
+ end
72
+ end
73
+
74
+ describe "finder methods" do
75
+ before do
76
+ Host.add('abc.local')
77
+ Host.add('def.local')
78
+ Host.add('efg.local', '10.2.2.4')
79
+ end
80
+
81
+ it "returns valid Host when searching for host name" do
82
+ Host.find_by_host('abc.local').should be_instance_of(Host)
83
+ end
84
+ end
85
+
86
+ describe ".add" do
87
+ it "returns Host object when passed hostname" do
88
+ Host.add('ghost-test-hostname.local').should be_instance_of(Host)
89
+ end
90
+
91
+ it "returns Host object when passed hostname" do
92
+ Host.add('ghost-test-hostname.local', '10.0.0.2').should be_instance_of(Host)
93
+ end
94
+
95
+ it "raises error if hostname already exists and not add a duplicate" do
96
+ Host.empty!
97
+ Host.add('ghost-test-hostname.local')
98
+ lambda { Host.add('ghost-test-hostname.local') }.should raise_error
99
+ Host.list.should have(1).thing
100
+ end
101
+
102
+ it "overwrites existing hostname if forced" do
103
+ hostname = 'ghost-test-hostname.local'
104
+
105
+ Host.empty!
106
+ Host.add(hostname)
107
+
108
+ Host.list.first.hostname.should eql(hostname)
109
+ Host.list.first.ip.should eql('127.0.0.1')
110
+
111
+ Host.add(hostname, '10.0.0.1', true)
112
+ Host.list.first.hostname.should eql(hostname)
113
+ Host.list.first.ip.should eql('10.0.0.1')
114
+
115
+ Host.list.should have(1).thing
116
+ end
117
+
118
+ it "should add a hostname using second hostname's ip" do
119
+ hostname = 'ghost-test-hostname.local'
120
+ alias_hostname = 'ghost-test-alias-hostname.local'
121
+
122
+ Host.empty!
123
+
124
+ Host.add(hostname)
125
+ Host.add(alias_hostname, hostname)
126
+
127
+ Host.list.last.ip.should eql(Host.list.first.ip)
128
+ end
129
+
130
+ it "should raise SocketError if it can't find hostname's ip" do
131
+ Host.empty!
132
+ lambda { Host.add('ghost-test-alias-hostname.google', 'google') }.should raise_error(SocketError)
133
+ end
134
+ end
135
+
136
+ describe ".empty!" do
137
+ it "empties the hostnames" do
138
+ Host.add('ghost-test-hostname.local') # add a hostname to be sure
139
+ Host.empty!
140
+ Host.list.should have(0).things
141
+ end
142
+ end
143
+
144
+ describe ".delete_matching" do
145
+ it "deletes matching hostnames" do
146
+ keep = 'ghost-test-hostname-keep.local'
147
+ Host.add(keep)
148
+ Host.add('ghost-test-hostname-match1.local')
149
+ Host.add('ghost-test-hostname-match2.local')
150
+ Host.delete_matching('match')
151
+ Host.list.should have(1).thing
152
+ Host.list.first.hostname.should eql(keep)
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,151 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'ghost'
3
+
4
+ # Warning: these tests will delete all hostnames in the system. Please back them up first
5
+
6
+ Host.empty!
7
+
8
+ describe Host, ".list" do
9
+ after(:each) { Host.empty! }
10
+
11
+ it "should return an array" do
12
+ Host.list.should be_instance_of(Array)
13
+ end
14
+
15
+ it "should contain instances of Host" do
16
+ Host.add('ghost-test-hostname.local')
17
+ Host.list.first.should be_instance_of(Host)
18
+ end
19
+ end
20
+
21
+ describe Host do
22
+ after(:each) { Host.empty! }
23
+
24
+ it "should have an IP" do
25
+ hostname = 'ghost-test-hostname.local'
26
+
27
+ Host.add(hostname)
28
+ host = Host.list.first
29
+ host.ip.should eql('127.0.0.1')
30
+
31
+ Host.empty!
32
+
33
+ ip = '169.254.23.121'
34
+ host = Host.add(hostname, ip)
35
+ host.ip.should eql(ip)
36
+ end
37
+
38
+ it "should have a hostname" do
39
+ hostname = 'ghost-test-hostname.local'
40
+
41
+ Host.add(hostname)
42
+ host = Host.list.first
43
+ host.hostname.should eql(hostname)
44
+
45
+ Host.empty!
46
+
47
+ ip = '169.254.23.121'
48
+ Host.add(hostname, ip)
49
+ host.hostname.should eql(hostname)
50
+ end
51
+
52
+ it ".to_s should return hostname" do
53
+ hostname = 'ghost-test-hostname.local'
54
+
55
+ Host.add(hostname)
56
+ host = Host.list.first
57
+ host.to_s.should eql(hostname)
58
+ end
59
+ end
60
+
61
+ describe Host, "finder methods" do
62
+ after(:all) { Host.empty! }
63
+ before(:all) do
64
+ Host.add('abc.local')
65
+ Host.add('def.local')
66
+ Host.add('efg.local', '10.2.2.4')
67
+ end
68
+
69
+ it "should return valid Host when searching for host name" do
70
+ Host.find_by_host('abc.local').should be_instance_of(Host)
71
+ end
72
+
73
+ end
74
+
75
+ describe Host, ".add" do
76
+ after(:each) { Host.empty! }
77
+
78
+ it "should return Host object when passed hostname" do
79
+ Host.add('ghost-test-hostname.local').should be_instance_of(Host)
80
+ end
81
+
82
+ it "should return Host object when passed hostname" do
83
+ Host.add('ghost-test-hostname.local', '10.0.0.2').should be_instance_of(Host)
84
+ end
85
+
86
+ it "should raise error if hostname already exists and not add a duplicate" do
87
+ Host.empty!
88
+ Host.add('ghost-test-hostname.local')
89
+ lambda { Host.add('ghost-test-hostname.local') }.should raise_error
90
+ Host.list.should have(1).thing
91
+ end
92
+
93
+ it "should overwrite existing hostname if forced" do
94
+ hostname = 'ghost-test-hostname.local'
95
+
96
+ Host.empty!
97
+ Host.add(hostname)
98
+
99
+ Host.list.first.hostname.should eql(hostname)
100
+ Host.list.first.ip.should eql('127.0.0.1')
101
+
102
+ Host.add(hostname, '10.0.0.1', true)
103
+ Host.list.first.hostname.should eql(hostname)
104
+ Host.list.first.ip.should eql('10.0.0.1')
105
+
106
+ Host.list.should have(1).thing
107
+ end
108
+
109
+ it "should add a hostname using second hostname's ip" do
110
+ hostname = 'ghost-test-hostname.local'
111
+ alias_hostname = 'ghost-test-alias-hostname.local'
112
+
113
+ Host.empty!
114
+
115
+ Host.add(hostname)
116
+ Host.add(alias_hostname, hostname)
117
+
118
+ Host.list.last.ip.should eql(Host.list.first.ip)
119
+ end
120
+
121
+ it "should raise SocketError if it can't find hostname's ip" do
122
+ Host.empty!
123
+ lambda { Host.add('ghost-test-alias-hostname.google', 'google') }.should raise_error(SocketError)
124
+ end
125
+ end
126
+
127
+ describe Host, ".empty!" do
128
+ it "should empty the hostnames" do
129
+ Host.add('ghost-test-hostname.local') # add a hostname to be sure
130
+ Host.empty!
131
+ Host.list.should have(0).things
132
+ end
133
+ end
134
+
135
+ describe Host, ".delete_matching" do
136
+ it "should delete matching hostnames" do
137
+ keep = 'ghost-test-hostname-keep.local'
138
+ Host.add(keep)
139
+ Host.add('ghost-test-hostname-match1.local')
140
+ Host.add('ghost-test-hostname-match2.local')
141
+ Host.delete_matching('match')
142
+ Host.list.should have(1).thing
143
+ Host.list.first.hostname.should eql(keep)
144
+ end
145
+ end
146
+
147
+
148
+ describe Host, ".backup and", Host, ".restore" do
149
+ it "should return a yaml file of all hosts and IPs when backing up"
150
+ it "should empty the hosts and restore only the ones in given yaml"
151
+ end
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,4 @@
1
+ $TESTING=true
2
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+ require 'rubygems'
4
+ require 'spec'
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alkesh-ghost
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 8
9
+ version: 0.2.8
10
+ platform: ruby
11
+ authors:
12
+ - Bodaniel Jeanes
13
+ autorequire: ghost
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-21 00:00:00 +01:00
18
+ default_executable: ghost
19
+ dependencies: []
20
+
21
+ description: Allows you to create, list, and modify local hostnames
22
+ email: me@bjeanes.com
23
+ executables:
24
+ - ghost
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README
29
+ - LICENSE
30
+ - TODO
31
+ files:
32
+ - LICENSE
33
+ - README
34
+ - Rakefile
35
+ - TODO
36
+ - bin/ghost
37
+ - lib/ghost/linux-host.rb
38
+ - lib/ghost/mac-host.rb
39
+ - lib/ghost.rb
40
+ - spec/etc_hosts_spec.rb
41
+ - spec/ghost_spec.rb
42
+ - spec/spec.opts
43
+ - spec/spec_helper.rb
44
+ has_rdoc: true
45
+ homepage: http://github.com/bjeanes/ghost
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --line-numbers
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ requirements: []
68
+
69
+ rubyforge_project: ghost
70
+ rubygems_version: 1.3.6
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Allows you to create, list, and modify local hostnames
74
+ test_files: []
75
+