ssh-conf 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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=
@@ -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
@@ -0,0 +1,2 @@
1
+ require "ssh-conf/version"
2
+ require "ssh_config"
@@ -0,0 +1,5 @@
1
+ module Ssh
2
+ class Config
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -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: []