ssh-conf 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.
- checksums.yaml +15 -0
- data/bin/ssh-conf +49 -0
- data/lib/ssh-conf.rb +2 -0
- data/lib/ssh-conf/version.rb +5 -0
- data/lib/ssh_config.rb +181 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NjIyYjA5MGJlZjQzOGNkZGVjNGQ3ODk4MTRiMjBjNzMwZmQxODk5Ng==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OGQ3M2JhYmUzNmViMGUzNzdiNzQ3ODllNjM0ZjFkZWRmMjQzMTU3MA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZmYxM2QwZDJmNzU1MDc5N2VjYWJmNDIwZTEzOGY2MDkxYmM0OTFjZjA5MDYy
|
10
|
+
MmZkNDFlODY1Y2M5MDZhMzkxMGFjMDcwNTlhZjBkYTkxNDU0NWVkMjM0Mjdj
|
11
|
+
M2I3NmQ0MTQ0YjIzZTA5OTEyMmNiYmZmMjFkOTVhZmYyYTgzZDU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MjFmNTU2NDMzOTk0OWM3ZmQzODA0ZDEzZDgzMjg3MGNmYzQ3ODIxMmY4ZDEx
|
14
|
+
NGJkOThmYWE3MDg3NDMyZDg0NzQ1NDY4MWU3ZjZiM2RiODYzODM2Y2JhYjNl
|
15
|
+
ZGMwODA0OTQ1YzdiM2I3M2YxN2QxYWNjYzgxYWZhYTA0ODMxYjU=
|
data/bin/ssh-conf
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ssh-conf'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
|
8
|
+
optparse = OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: ssh-conf [options]"
|
10
|
+
|
11
|
+
opts.on("-a", "--all", "Search all default SSH conf files on system") do |v|
|
12
|
+
options[:all] = true
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on("-f", "--files FILES", "Comma separated list of files to process") do |f|
|
16
|
+
options[:files] = f
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on("-p", "--pretty", "Pretty output") do |v|
|
20
|
+
options[:pretty] = true
|
21
|
+
end
|
22
|
+
|
23
|
+
opts.on("-f", "--format format", [:text, :json], "Output format (text, json)") do |f|
|
24
|
+
options[:format] = f
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("-v", "--version", "Gem version") do |f|
|
28
|
+
puts "ssh-conf: #{Ssh::Config::VERSION}"
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
33
|
+
puts opts
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
optparse.parse!
|
40
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument, OptionParser::InvalidArgument
|
41
|
+
puts $!.to_s
|
42
|
+
puts optparse
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
sshconf = Ssh::Config.new(ARGV, options)
|
48
|
+
|
49
|
+
puts sshconf.output
|
data/lib/ssh-conf.rb
ADDED
data/lib/ssh_config.rb
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Ssh
|
4
|
+
class Config
|
5
|
+
def initialize(hosts, options = {})
|
6
|
+
@hosts = hosts
|
7
|
+
@options = options
|
8
|
+
@results = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def output
|
12
|
+
method = "text"
|
13
|
+
|
14
|
+
if @options[:format] == :json
|
15
|
+
method = "json"
|
16
|
+
end
|
17
|
+
|
18
|
+
if @options[:pretty]
|
19
|
+
method = "pretty_#{method}"
|
20
|
+
end
|
21
|
+
|
22
|
+
send("as_#{method}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def as_text
|
26
|
+
out = ''
|
27
|
+
|
28
|
+
results.each do |host, config|
|
29
|
+
out << "Host\t#{host}\n"
|
30
|
+
|
31
|
+
config.each do |key, value|
|
32
|
+
out << "#{key}\t#{value}\n"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
out
|
37
|
+
end
|
38
|
+
|
39
|
+
def as_pretty_text
|
40
|
+
longest = results.values.map(&:flatten).flatten
|
41
|
+
.max { |a, b| a.length <=> b.length }.length + 2
|
42
|
+
|
43
|
+
out = ''
|
44
|
+
results.each do |host, config|
|
45
|
+
out << sprintf("%-#{longest}s %s\n", 'Host', host)
|
46
|
+
|
47
|
+
config.each do |key, value|
|
48
|
+
out << sprintf("%-#{longest}s %s\n", key, value)
|
49
|
+
end
|
50
|
+
|
51
|
+
out << "\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
out
|
55
|
+
end
|
56
|
+
|
57
|
+
def as_json
|
58
|
+
JSON.dump(results)
|
59
|
+
end
|
60
|
+
|
61
|
+
def as_pretty_json
|
62
|
+
JSON.pretty_generate(results)
|
63
|
+
end
|
64
|
+
|
65
|
+
def results
|
66
|
+
if @results.empty?
|
67
|
+
@hosts.each do |host|
|
68
|
+
config = self.for(host)
|
69
|
+
config.each do |key, value|
|
70
|
+
case value
|
71
|
+
when Array
|
72
|
+
config[key] = value.join(',')
|
73
|
+
when String
|
74
|
+
else
|
75
|
+
config[key] = value.to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
@results[host] = config
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
@results
|
84
|
+
end
|
85
|
+
|
86
|
+
def for(host)
|
87
|
+
files.inject({}) { |settings, file|
|
88
|
+
load(file, host, settings)
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def load(path, host, settings={})
|
93
|
+
file = File.expand_path(path)
|
94
|
+
return settings unless File.readable?(file)
|
95
|
+
|
96
|
+
globals = {}
|
97
|
+
matched_host = nil
|
98
|
+
seen_host = false
|
99
|
+
IO.foreach(file) do |line|
|
100
|
+
next if line =~ /^\s*(?:#.*)?$/
|
101
|
+
|
102
|
+
if line =~ /^\s*(\S+)\s*=(.*)$/
|
103
|
+
key, value = $1, $2
|
104
|
+
else
|
105
|
+
key, value = line.strip.split(/\s+/, 2)
|
106
|
+
end
|
107
|
+
|
108
|
+
# silently ignore malformed entries
|
109
|
+
next if value.nil?
|
110
|
+
|
111
|
+
value = $1 if value =~ /^"(.*)"$/
|
112
|
+
|
113
|
+
value = case value.strip
|
114
|
+
when /^\d+$/ then value.to_i
|
115
|
+
when /^no$/i then false
|
116
|
+
when /^yes$/i then true
|
117
|
+
else value
|
118
|
+
end
|
119
|
+
|
120
|
+
if key == 'Host'
|
121
|
+
# Support "Host host1 host2 hostN".
|
122
|
+
# See http://github.com/net-ssh/net-ssh/issues#issue/6
|
123
|
+
negative_hosts, positive_hosts = value.to_s.split(/\s+/).partition { |h| h.start_with?('!') }
|
124
|
+
|
125
|
+
# Check for negative patterns first. If the host matches, that overrules any other positive match.
|
126
|
+
# The host substring code is used to strip out the starting "!" so the regexp will be correct.
|
127
|
+
negative_match = negative_hosts.select { |h| host =~ pattern2regex(h[1..-1]) }.first
|
128
|
+
|
129
|
+
if negative_match
|
130
|
+
matched_host = nil
|
131
|
+
else
|
132
|
+
matched_host = positive_hosts.select { |h| host =~ pattern2regex(h) }.first
|
133
|
+
end
|
134
|
+
|
135
|
+
seen_host = true
|
136
|
+
settings.delete(key)
|
137
|
+
elsif !seen_host
|
138
|
+
if key == 'IdentityFile'
|
139
|
+
(globals[key] ||= []) << value
|
140
|
+
else
|
141
|
+
globals[key] = value unless settings.key?(key)
|
142
|
+
end
|
143
|
+
elsif !matched_host.nil?
|
144
|
+
if key == 'IdentityFile'
|
145
|
+
(settings[key] ||= []) << value
|
146
|
+
else
|
147
|
+
settings[key] = value unless settings.key?(key)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
settings = globals.merge(settings) if globals
|
153
|
+
|
154
|
+
return settings
|
155
|
+
end
|
156
|
+
|
157
|
+
def files
|
158
|
+
if @options[:files]
|
159
|
+
@options[:files].split(',')
|
160
|
+
elsif @options[:all]
|
161
|
+
%w(~/.ssh/config /etc/ssh_config /etc/ssh/ssh_config)
|
162
|
+
else
|
163
|
+
%w( ~/.ssh/config )
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
# Converts an ssh_config pattern into a regex for matching against
|
170
|
+
# host names.
|
171
|
+
def pattern2regex(pattern)
|
172
|
+
pattern = "^" + pattern.to_s.gsub(/\./, "\\.").
|
173
|
+
gsub(/\?/, '.').
|
174
|
+
gsub(/([+\/])/, '\\\\\\0').
|
175
|
+
gsub(/\*/, '.*') + "$"
|
176
|
+
Regexp.new(pattern, true)
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ssh-conf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nenad Petronijevic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Displays ssh config for given hosts
|
28
|
+
email:
|
29
|
+
- set.krag@gmail.com
|
30
|
+
executables:
|
31
|
+
- ssh-conf
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- bin/ssh-conf
|
36
|
+
- lib/ssh-conf.rb
|
37
|
+
- lib/ssh-conf/version.rb
|
38
|
+
- lib/ssh_config.rb
|
39
|
+
homepage: https://github.com/arr-dev/ssh-conf
|
40
|
+
licenses:
|
41
|
+
- MIT
|
42
|
+
metadata: {}
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 2.4.5
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: Displays ssh config for given hosts, with different output options
|
63
|
+
test_files: []
|