ssh-config 0.1.0
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/MIT-LICENSE +22 -0
- data/README.rdoc +66 -0
- data/bin/ssh-config +66 -0
- data/lib/config_file.rb +126 -0
- data/lib/config_section.rb +57 -0
- data/lib/ssh-config.rb +3 -0
- metadata +73 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2008-2009 David Brady github@shinybit.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
= ssh-config: A Tool for Managing ssh Config Files
|
2
|
+
|
3
|
+
== Overview
|
4
|
+
|
5
|
+
It's not THAT much trouble to update your .ssh/config file every time
|
6
|
+
a host changes, but when it starts happening often enough, even that
|
7
|
+
hassle starts to add up. This is a quick tool I wrote to help handle
|
8
|
+
them.
|
9
|
+
|
10
|
+
It takes great care to not trash your config file, so you can continue
|
11
|
+
to edit your config files by hand before and after running the tool.
|
12
|
+
|
13
|
+
ssh-config will make a backup of your ~/.ssh/config file as
|
14
|
+
~/.ssh/config~.
|
15
|
+
|
16
|
+
Probably the most useful command is "copy", which intelligently copies
|
17
|
+
an existing host section.
|
18
|
+
|
19
|
+
== Commands
|
20
|
+
|
21
|
+
=== set <host> <key> <value>
|
22
|
+
|
23
|
+
Adds or updates the value for a given host.
|
24
|
+
|
25
|
+
=== unset <host> <key>
|
26
|
+
|
27
|
+
Removes a key value for a given host. NOTE: If all values are removed
|
28
|
+
from a section, the section is NOT removed; use rm <host> for that.
|
29
|
+
|
30
|
+
=== rm <host>
|
31
|
+
|
32
|
+
Removes an entire host section.
|
33
|
+
|
34
|
+
=== copy <old_host> <new_host>
|
35
|
+
|
36
|
+
Copies the entire section named <old_host> to a new section called
|
37
|
+
<new_host>. If old_host has a Hostname section, ssh-config will try to
|
38
|
+
update it to reflect the new_host name. For example, if you had a
|
39
|
+
section like
|
40
|
+
|
41
|
+
Host rails01
|
42
|
+
Hostname rails01.example.com
|
43
|
+
|
44
|
+
And you did ssh-config copy rails01 rails02, the new section would
|
45
|
+
look like this:
|
46
|
+
|
47
|
+
Host rails02
|
48
|
+
Hostname rails02.example.com
|
49
|
+
|
50
|
+
=== dump
|
51
|
+
|
52
|
+
Dumps the entire file.
|
53
|
+
|
54
|
+
=== show <host>
|
55
|
+
|
56
|
+
Dumps one section. (Similar to ssh-what.)
|
57
|
+
|
58
|
+
=== search <pattern>
|
59
|
+
|
60
|
+
Shows all sections that have any line (key OR value) that matches
|
61
|
+
pattern. (Similar to ssh-what.)
|
62
|
+
|
63
|
+
=== list
|
64
|
+
|
65
|
+
Lists all section names (just the Host line)
|
66
|
+
|
data/bin/ssh-config
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'ftools'
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'ssh-config'))
|
4
|
+
|
5
|
+
# ssh-config - Manipulate config values in the .ssh/config file.
|
6
|
+
#
|
7
|
+
# ssh-config help
|
8
|
+
# ssh-config dump
|
9
|
+
# ssh-config list
|
10
|
+
# ssh-config show <host-nickname>
|
11
|
+
# ssh-config find <regex>
|
12
|
+
# ssh-config set <host-nickname> <setting> <value> [<setting> <value> [...]]
|
13
|
+
# Note: "<setting> -" deletes a setting
|
14
|
+
# ssh-config rm <host-nickname> # delete config settings for that host
|
15
|
+
# ssh-config copy <host-nickname> <new-host-nickname> # copy settings from one to the other.
|
16
|
+
|
17
|
+
config = ConfigFile.new
|
18
|
+
argv = ARGV
|
19
|
+
command = argv.shift
|
20
|
+
|
21
|
+
def usage
|
22
|
+
str =<<HELP
|
23
|
+
ssh-config - Configure your .ssh/config file
|
24
|
+
|
25
|
+
Usage:
|
26
|
+
ssh-config <command> <params>
|
27
|
+
|
28
|
+
Commands:
|
29
|
+
help - show this message
|
30
|
+
dump - parse and dump the config file
|
31
|
+
list - list configured hosts
|
32
|
+
show <host> - display the settings for host
|
33
|
+
find <pattern> - find all hosts with any detail matching pattern
|
34
|
+
set <host> <setting> <value> [<setting> <value> [...]] - set a value
|
35
|
+
NOTE: If host does not exist, it will be created
|
36
|
+
NOTE: If value is -, setting will be deleted, e.g. set User -
|
37
|
+
NOTE: If all values are deleted, section will NOT be removed, use rm instead
|
38
|
+
unset <host> <setting> - Remove a setting from a host section
|
39
|
+
rm <host> - Remove configuration for a host
|
40
|
+
copy <host> <newhost> - Duplicate the settings for a host
|
41
|
+
NOTE: If Hostname contains Host, new host will be automagically updated
|
42
|
+
HELP
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
case command
|
47
|
+
when 'help'
|
48
|
+
puts usage
|
49
|
+
when 'list'
|
50
|
+
puts config.list
|
51
|
+
when 'show'
|
52
|
+
puts config.show(argv.shift)
|
53
|
+
when 'search'
|
54
|
+
puts config.search(argv.shift)
|
55
|
+
when 'cp', 'copy'
|
56
|
+
config.copy! argv.shift, argv.shift
|
57
|
+
when 'unset'
|
58
|
+
config.unset!(argv.shift, *argv)
|
59
|
+
when 'set'
|
60
|
+
config.set!(*argv)
|
61
|
+
when 'rm', 'del', 'delete'
|
62
|
+
config.rm! argv.shift
|
63
|
+
when 'dump'
|
64
|
+
puts config.dump
|
65
|
+
end
|
66
|
+
|
data/lib/config_file.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
class ConfigFile
|
2
|
+
def initialize
|
3
|
+
@make_backups = true
|
4
|
+
@header_lines = []
|
5
|
+
@sections = []
|
6
|
+
@sections_by_name = {}
|
7
|
+
read_config
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_section(name)
|
11
|
+
section = ConfigSection.new(name)
|
12
|
+
@sections << section
|
13
|
+
@sections_by_name[name] = section
|
14
|
+
section
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_config
|
18
|
+
current_section = nil
|
19
|
+
IO.readlines(File.expand_path("~/.ssh/config")).each_with_index do |line, i|
|
20
|
+
line.rstrip!
|
21
|
+
if line =~ /\bHost\s+(.+)/
|
22
|
+
current_section = add_section($1)
|
23
|
+
else
|
24
|
+
if current_section
|
25
|
+
current_section.lines << line
|
26
|
+
else
|
27
|
+
@header_lines << line
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def show(host_nick)
|
34
|
+
@sections_by_name[host_nick]
|
35
|
+
end
|
36
|
+
|
37
|
+
def list()
|
38
|
+
to_text(@sections_by_name.keys.sort.map {|name| "Host #{name}"})
|
39
|
+
end
|
40
|
+
|
41
|
+
def search(text)
|
42
|
+
to_text(@sections.find_all {|section| section.matches?(text)}.sort_by {|section| section.name})
|
43
|
+
end
|
44
|
+
|
45
|
+
def set!(host_nick, *args)
|
46
|
+
backup if @make_backups
|
47
|
+
while args.length > 0
|
48
|
+
key, value = args.shift, args.shift
|
49
|
+
section = set(host_nick, key, value)
|
50
|
+
end
|
51
|
+
save
|
52
|
+
section
|
53
|
+
end
|
54
|
+
|
55
|
+
def set(host_nick, key, value)
|
56
|
+
section = @sections_by_name[host_nick] || add_section(host_nick)
|
57
|
+
section[key] = value
|
58
|
+
end
|
59
|
+
|
60
|
+
def unset!(host_nick, *keys)
|
61
|
+
backup if @make_backups
|
62
|
+
while keys.length > 0
|
63
|
+
section = unset(host_nick, keys.shift)
|
64
|
+
end
|
65
|
+
save
|
66
|
+
section
|
67
|
+
end
|
68
|
+
|
69
|
+
def unset(host_nick, key)
|
70
|
+
if section = @sections_by_name[host_nick]
|
71
|
+
section.unset(key)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def dump
|
76
|
+
to_text([@header_lines, @sections].flatten)
|
77
|
+
end
|
78
|
+
|
79
|
+
def rm!(host_nick)
|
80
|
+
backup if @make_backups
|
81
|
+
rm(host_nick)
|
82
|
+
save
|
83
|
+
end
|
84
|
+
|
85
|
+
def rm(host_nick)
|
86
|
+
if @sections_by_name.key?(host_nick)
|
87
|
+
@sections_by_name.delete host_nick
|
88
|
+
@sections.delete_at(@sections.index{|s| s.name == host_nick})
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def copy!(old_host_nick, new_host_nick)
|
93
|
+
backup if @make_backups
|
94
|
+
copy(old_host_nick, new_host_nick)
|
95
|
+
save
|
96
|
+
end
|
97
|
+
|
98
|
+
def copy(old_host_nick, new_host_nick)
|
99
|
+
if @sections_by_name.key?(old_host_nick)
|
100
|
+
old_section = @sections_by_name[old_host_nick]
|
101
|
+
new_section = @sections_by_name[new_host_nick] || add_section(new_host_nick)
|
102
|
+
new_section.lines = old_section.lines.dup
|
103
|
+
|
104
|
+
if old_section["Hostname"]
|
105
|
+
new_section["Hostname"] = old_section["Hostname"].gsub(old_host_nick, new_host_nick)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def save
|
111
|
+
File.open(File.expand_path("~/.ssh/config"), "w") do |file|
|
112
|
+
file.puts dump
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def backup
|
117
|
+
File.copy(File.expand_path("~/.ssh/config"), File.expand_path("~/.ssh/config~"))
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def to_text(ray)
|
123
|
+
ray.map {|s| s.to_s } * "\n"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class ConfigSection
|
2
|
+
attr_accessor :name, :lines, :settings
|
3
|
+
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
@settings = {}
|
7
|
+
@lines = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def [](setting)
|
11
|
+
unless @settings.key? setting
|
12
|
+
if line = lines[setting_index(setting)]
|
13
|
+
key,val = line.split(nil, 2)
|
14
|
+
@settings[key] = val
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@settings[setting]
|
18
|
+
end
|
19
|
+
|
20
|
+
def unset(setting)
|
21
|
+
if line_num = setting_index(setting)
|
22
|
+
@settings.delete setting
|
23
|
+
@lines.delete_at line_num
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
["Host #{name}", *lines] * "\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
def []=(setting, value)
|
32
|
+
if value != '-'
|
33
|
+
line_num = setting_index(setting) || lines.length
|
34
|
+
lines[line_num] = format_line(setting, value)
|
35
|
+
else
|
36
|
+
@settings.delete(setting)
|
37
|
+
@lines.delete_at(setting_index(setting))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def matches?(text)
|
42
|
+
r = Regexp.new text
|
43
|
+
name =~ r || lines.any? {|line| line =~ r}
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def format_line(setting, value)
|
49
|
+
" #{setting} #{value}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def setting_index(setting)
|
53
|
+
r = Regexp.new(setting)
|
54
|
+
lines.index {|line| line =~ r}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
data/lib/ssh-config.rb
ADDED
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ssh-config
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- David Brady
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-26 00:00:00 -06:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Ssh-Config, a tool that lets you quickly add, update, remove, and copy ssh config file entries.
|
22
|
+
email: github@shinybit.com
|
23
|
+
executables:
|
24
|
+
- ssh-config
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README.rdoc
|
29
|
+
- MIT-LICENSE
|
30
|
+
files:
|
31
|
+
- bin/ssh-config
|
32
|
+
- lib/config_file.rb
|
33
|
+
- lib/config_section.rb
|
34
|
+
- lib/ssh-config.rb
|
35
|
+
- README.rdoc
|
36
|
+
- MIT-LICENSE
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/dbrady/ssh-config/
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --line-numbers
|
44
|
+
- --inline-source
|
45
|
+
- --main
|
46
|
+
- README.rdoc
|
47
|
+
- --title
|
48
|
+
- Ssh-Config - A Tool for ssh config files
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
version: "0"
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.3.6
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: Ssh-Config - tool for managing your .ssh/config file
|
72
|
+
test_files: []
|
73
|
+
|