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