lib/sconb.rb in sconb-0.0.5 vs lib/sconb.rb in sconb-0.0.6
- old
+ new
@@ -1,9 +1,10 @@
require "sconb/version"
require "thor"
require "net/ssh"
require "json"
+require "pp"
module Sconb
class CLI < Thor
method_option :all, :type => :boolean, :aliases => '-a', :default => false, :banner => 'dump .ssh/config and private keys.'
@@ -12,51 +13,64 @@
def dump()
path = options[:config]
file = File.expand_path(path)
configs = {}
unless File.readable?(file)
- puts configs
+ puts configs
return
end
-
+
allconfig = config_load(path, '*')
- configs['*'] = allconfig unless allconfig.size == 1
+ configs['*'] = allconfig unless allconfig.size <= 1
IO.foreach(file) do |line|
next if line =~ /^\s*(?:#.*)?$/
if line =~ /^\s*(\S+)\s*=(.*)$/
key, value = $1, $2
else
key, value = line.strip.split(/\s+/, 2)
end
next if value.nil?
- next unless key.downcase == 'host'
- negative_hosts, positive_hosts = value.to_s.split(/\s+/).partition { |h| h.start_with?('!') }
- positive_hosts.each do | host |
- next if host == '*'
- config = config_load(path, host)
- allconfig.each do |key, value|
- next unless config.key? key
- config.delete key if config[key] == allconfig[key]
+ # Host
+ if key.downcase == 'host'
+ negative_hosts, positive_hosts = value.to_s.split(/\s+/).partition { |h| h.start_with?('!') }
+ positive_hosts.each do | host |
+ next if host == '*'
+ config = config_load(path, host)
+
+ allconfig.each do |key, value|
+ next unless config.key? key
+ config.delete key if config[key] == allconfig[key]
+ end
+
+ configs[host] = config
end
+ end
- configs[host] = config
+ # Match
+ if key.downcase == 'match'
+ configs[key + ' ' + value] = config_load(path, value)
end
+
end
puts JSON.pretty_generate configs
end
-
+
desc "restore < dump.json > .ssh/config", "Restore .ssh/config from JSON"
def restore()
ssh_configs = []
json = stdin_read
configs = JSON.parse(json)
configs.each do |host, config|
ssh_config = ''
- ssh_config << 'Host ' + host + "\n"
+ unless host.match(/^Match /)
+ ssh_config << 'Host ' + host + "\n"
+ else
+ ssh_config << host + "\n"
+ end
config.each do |key, value|
- next if key.downcase == 'host' || key.downcase == 'identityfilecontent'
+ next if key.downcase == 'host' || key.downcase == 'match' || key.downcase == 'identityfilecontent'
if key.downcase == 'identityfile'
value.each_with_index do |keyfile,i|
ssh_config << ' ' + key + ' ' + keyfile + "\n"
end
else
@@ -101,11 +115,11 @@
private
def config_load(path, host)
settings = {}
file = File.expand_path(path)
return settings unless File.readable?(file)
-
+
globals = {}
matched_host = nil
multi_host = []
seen_host = false
IO.foreach(file) do |line|
@@ -134,12 +148,19 @@
if negative_match
matched_host = nil
else
matched_host = positive_hosts.select { |h| host =~ pattern2regex(h) }.first
end
-
+ settings[key] = host unless matched_host.nil?
seen_host = true
- settings[key] = host
+ elsif key.downcase == 'match'
+ if host == value
+ matched_host = true
+ else
+ matched_host = nil
+ end
+ settings[key] = host unless matched_host.nil?
+ seen_host = true
elsif !seen_host
if key.downcase == 'identityfile'
(globals[key] ||= []) << value
# Read IdentityFile Content