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.
@@ -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: []