ghost 0.2.8 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
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.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -15,7 +15,7 @@ Intended Usage
15
15
  This gem is designed primarily for web developers who need to add
16
16
  and modify hostnames to their system for virtual hosts on their
17
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
18
+ who would otherwise modify their `/etc/hosts` file manually and
19
19
  flush the cache.
20
20
 
21
21
  Command
@@ -68,28 +68,37 @@ Command
68
68
  Library
69
69
  -------
70
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`
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
73
  to see how to use the library.
74
74
 
75
75
  Installation
76
76
  ============
77
77
 
78
78
  sudo gem install ghost
79
-
79
+
80
80
  Contributors
81
81
  ============
82
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)
83
+ If this list is ever out of date, you can get full contributor list with `git log --format='%aN (%ae)' | sort -u`
84
+
85
+ * [Alkesh Vaghmaria](https://github.com/alkesh)
86
+ * [Andrei Serdeliuc](https://github.com/extraordinaire)
87
+ * [Ben Hoskings](https://github.com/benhoskings)
88
+ * [Bodaniel Jeanes](https://github.com/bjeanes)
89
+ * [Courtois Simon](https://github.com/simonc)
90
+ * [Felipe Coury](https://github.com/fcoury)
91
+ * [Justin Mazzi](https://github.com/jmazzi)
92
+ * [Lars Fronius](https://github.com/LarsFronius)
93
+ * [Lee Jensen](https://github.com/outerim)
94
+ * [Mitchell Riley](https://github.com/mitchellvriley)
95
+ * [Ryan Bigg](https://github.com/radar)
96
+ * [Sam Beam](https://github.com/sbeam)
88
97
 
89
98
  Legal Stuff
90
99
  ===========
91
100
 
92
- Copyright (c) 2008-2010 Bodaniel Jeanes
101
+ Copyright (c) 2008-2012 Bodaniel Jeanes
93
102
 
94
103
  Permission is hereby granted, free of charge, to any person obtaining
95
104
  a copy of this software and associated documentation files (the
@@ -108,4 +117,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
108
117
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
109
118
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
110
119
  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.
120
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -10,19 +10,19 @@ Dir['tasks/**/*.rake'].each { |rake| load rake }
10
10
 
11
11
  desc "list tasks"
12
12
  task :default do
13
- puts `rake -T`.grep(/^[^(].*$/)
13
+ puts `rake -T`
14
14
  end
15
15
 
16
- desc "Outstanding TODO's"
17
- task :todo do
16
+ desc "Outstanding TODO's"
17
+ task :todo do
18
18
  files = ["**/*.{rb,rake}" "bin/*", "README.mkdn"]
19
-
19
+
20
20
  File.open('TODO','w') do |f|
21
21
  FileList[*files].egrep(/TODO|FIXME/) do |file, line, text|
22
22
  output = "#{file}:#{line} - #{text.chomp.gsub(/^\s+|\s+$/ , "")}"
23
-
23
+
24
24
  puts output
25
25
  f.puts output
26
26
  end
27
27
  end
28
- end
28
+ end
data/bin/ghost CHANGED
@@ -3,12 +3,8 @@
3
3
  # Created by Bodaniel Jeanes on 2008-8-19.
4
4
  # Copyright (c) 2008. All rights reserved.
5
5
 
6
- begin
7
- require 'rubygems'
8
- rescue LoadError
9
- # no rubygems to load, so we fail silently
10
- end
11
- require 'ghost'
6
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/ghost')
7
+ require 'open-uri'
12
8
 
13
9
  def help_text(exit_code = 0)
14
10
  script_name = File.basename $0
@@ -16,7 +12,7 @@ def help_text(exit_code = 0)
16
12
  #{script_name} modify <hostname> <ip> OR <hostname> (will lookup ip)
17
13
  #{script_name} delete <hostname>
18
14
  #{script_name} delete_matching <pattern>
19
- #{script_name} list
15
+ #{script_name} list [<filter>]
20
16
  #{script_name} empty
21
17
  #{script_name} export
22
18
  #{script_name} import <file>
@@ -24,101 +20,114 @@ def help_text(exit_code = 0)
24
20
  exit(exit_code)
25
21
  end
26
22
 
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
23
+ begin
24
+ if ARGV.size.zero? || ['-h', '--help', 'help'].include?(ARGV.first)
25
+ help_text
26
+ else
27
+ case ARGV[0]
28
+ when 'add'
29
+ if [2,3].include?(ARGV.size)
30
+ begin
31
+ ARGV.shift
32
+ host = Ghost::Host.add(*ARGV)
33
+ puts " [Adding] #{host.name} -> #{host.ip}"
34
+ exit 0
35
+ rescue SocketError
36
+ $stderr.puts "Cannot find IP for host"
37
+ exit 3
38
+ rescue Ghost::RecordExists
39
+ $stderr.puts "Cannot overwrite an existing entry. Use the modify subcommand"
40
+ exit 3
41
+ end
42
+ else
43
+ $stderr.puts "The add subcommand requires at least a hostname.\n\n"
44
+ help_text 2
45
+ end
46
+ when 'modify'
47
+ if ARGV.size == 3
34
48
  ARGV.shift
35
- host = Host.add(*ARGV)
36
- puts " [Adding] #{host.name} -> #{host.ip}"
49
+ ARGV << true
50
+ host = Ghost::Host.add(*ARGV)
51
+ puts " [Modifying] #{host.name} -> #{host.ip}"
52
+ exit 0
53
+ else
54
+ $stderr.puts "The modify subcommand requires a hostname and an IP.\n\n"
55
+ help_text 4
56
+ end
57
+ when 'delete', 'del', 'remove', 'rm'
58
+ if ARGV.size == 2
59
+ Ghost::Host.delete(ARGV[1])
60
+ puts " [Deleting] #{ARGV[1]}"
37
61
  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
62
+ else
63
+ $stderr.puts "The delete subcommand requires a hostname.\n\n"
64
+ help_text 2
65
+ end
66
+ when 'delete_matching'
67
+ if ARGV.size == 2
68
+ matched = Ghost::Host.delete_matching(ARGV[1])
69
+ if matched.empty?
70
+ puts " No matching entries found"
71
+ else
72
+ matched.each { |h| puts " [Deleting] #{h}" }
73
+ end
74
+ exit 0
75
+ else
76
+ $stderr.puts "The delete_matching subcommand requires a hostname pattern.\n\n"
77
+ help_text 2
78
+ end
79
+ when 'list'
80
+ filter = %r|#{ARGV[1]}| if ARGV.size == 2
81
+
82
+ hosts = Ghost::Host.list
83
+
84
+ if filter
85
+ hosts.reject! { |host| host.name !~ filter && host.ip !~ filter }
86
+ end
87
+
88
+ pad = hosts.max{|a,b| a.to_s.length <=> b.to_s.length }.to_s.length
89
+
90
+ puts "Listing #{hosts.size} host(s):"
91
+
92
+ hosts.each do |host|
93
+ puts "#{host.name.rjust(pad+2)} -> #{host.ip}"
44
94
  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
95
  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]}"
96
+ when 'empty'
97
+ print " [Emptying] "
98
+ Ghost::Host.empty!
99
+ puts "Done."
64
100
  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}" }
101
+ when 'export'
102
+ hosts = Ghost::Host.list
103
+ hosts.each do |host|
104
+ puts "#{host.name} #{host.ip}"
76
105
  end
77
106
  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}"
107
+ when 'import'
108
+ if ARGV.size == 2
109
+ begin
110
+ import_file = open(ARGV[1])
111
+ import_file.each_line do |line|
112
+ host_infos = line.strip.split(' ', 2)
113
+ host = Ghost::Host.add(*host_infos)
114
+ puts " [Adding] #{host.name} -> #{host.ip}"
115
+ end
116
+ exit 0
117
+ rescue
118
+ $stderr.puts "Cannot import. A problem occured while opening the import file."
119
+ exit 5
110
120
  end
111
- exit 0
112
- rescue
113
- $stderr.puts "Cannot import. A problem occured while opening the import file."
114
- exit 5
121
+ else
122
+ $stderr.puts "The import command requires an input file.\n\n"
123
+ help_text 6
115
124
  end
116
125
  else
117
- $stderr.puts "The import command requires an input file.\n\n"
118
- help_text 6
126
+ $stderr.puts "Invalid option: #{ARGV[0]}"
127
+ help_text 1
119
128
  end
120
- else
121
- $stderr.puts "Invalid option: #{ARGV[0]}"
122
- help_text 1
123
129
  end
130
+ rescue Errno::EACCES
131
+ $stderr.puts "Please re-run as root or using sudo"
132
+ exit 3
124
133
  end
data/bin/ghost-ssh ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/ghost')
4
+
5
+ def help_text(exit_code = 0)
6
+ script_name = File.basename $0
7
+ puts """USAGE: #{script_name} add <host> <hostname> [--user=<user>] [--port=<port>]
8
+ #{script_name} modify <host> <hostname> [--user=<user>] [--port=<port>]
9
+ #{script_name} delete <host>
10
+ #{script_name} list
11
+ #{script_name} empty
12
+ #{script_name} export
13
+ #{script_name} import <file>
14
+ """
15
+ exit(exit_code)
16
+ end
17
+
18
+ def parse(argv)
19
+ argv.shift
20
+
21
+ new_config = {
22
+ :host => argv.shift,
23
+ :hostname => argv.shift
24
+ }
25
+
26
+ if argv.size > 0
27
+ argv.each do |arg|
28
+ if arg =~ /--([a-z]+)=(.*)/
29
+ new_config[$1.to_sym] = $2
30
+ end
31
+ end
32
+ end
33
+
34
+ new_config
35
+ end
36
+
37
+ if ARGV.size.zero? || ['-h', '--help', 'help'].include?(ARGV.first)
38
+ help_text
39
+ else
40
+ case ARGV[0]
41
+ when 'add'
42
+ if [3,4,5].include?(ARGV.size)
43
+ begin
44
+ new_config = parse(ARGV)
45
+
46
+ config = Ghost::SshConfig.add(new_config)
47
+ puts " [Adding] #{config.host} -> #{config.hostname}"
48
+ exit 0
49
+ rescue Ghost::SshConfigDuplicateError
50
+ $stderr.puts $!
51
+ exit 3
52
+ end
53
+ else
54
+ $stderr.puts "The add subcommand requires at least a host and a hostname.\n\n"
55
+ help_text 2
56
+ end
57
+ when 'modify'
58
+ if [3,4,5].include?(ARGV.size)
59
+ new_config = parse(ARGV)
60
+ new_config[:force] = true
61
+ config = Ghost::SshConfig.add(new_config)
62
+ puts " [Modifying] #{config.host} -> #{config.hostname}"
63
+ exit 0
64
+ else
65
+ $stderr.puts "The modify subcommand requires at least a host and a hostname.\n\n"
66
+ help_text 4
67
+ end
68
+ when 'delete', 'del', 'remove', 'rm'
69
+ if ARGV.size == 2
70
+ Ghost::SshConfig.delete(ARGV[1])
71
+ puts " [Deleting] #{ARGV[1]}"
72
+ exit 0
73
+ else
74
+ $stderr.puts "The delete subcommand requires a hostname.\n\n"
75
+ help_text 2
76
+ end
77
+
78
+ when 'list'
79
+ configs = Ghost::SshConfig.list
80
+ pad = configs.max{|a,b| a.to_s.length <=> b.to_s.length }.to_s.length
81
+
82
+ puts "Listing #{configs.size} configs(s):"
83
+
84
+ configs.each do |c|
85
+ user = c.user ? "#{c.user}@" : ""
86
+ puts "#{c.host.rjust(pad+2)} -> #{user}#{c.hostname}:#{c.port||22}"
87
+ end
88
+ exit 0
89
+ when 'empty'
90
+ print " [Emptying] "
91
+ Ghost::SshConfig.empty!
92
+ puts "Done."
93
+ exit 0
94
+ when 'export'
95
+ configs = Ghost::SshConfig.list
96
+ configs.each do |c|
97
+ puts "#{c.host},#{c.hostname},#{c.user},#{c.port}"
98
+ end
99
+ exit 0
100
+ when 'import'
101
+ if ARGV.size == 2
102
+ begin
103
+ File.foreach(ARGV[1]) do |line|
104
+ cfg_infos = line.strip.split(',')
105
+ hash = {
106
+ :host => cfg_infos[0],
107
+ :hostname => cfg_infos[1]
108
+ }
109
+
110
+ hash[:user] = cfg_infos[2] if cfg_infos.size > 2
111
+ hash[:port] = cfg_infos[3] if cfg_infos.size > 3
112
+ hash[:force] = true
113
+
114
+ config = Ghost::SshConfig.add(hash)
115
+
116
+ puts " [Adding] #{config.host} -> #{config.hostname}"
117
+ end
118
+ exit 0
119
+ rescue
120
+ $stderr.puts "Cannot import. A problem occured while opening the import file (#{$!.message})."
121
+ exit 5
122
+ end
123
+ else
124
+ $stderr.puts "The import command requires an input file.\n\n"
125
+ help_text 6
126
+ end
127
+ else
128
+ $stderr.puts "Invalid option: #{ARGV[0]}"
129
+ help_text 1
130
+ end
131
+ end
132
+