Skip to content

Instantly share code, notes, and snippets.

@m87h
Last active August 29, 2015 14:12
Show Gist options
  • Save m87h/74ad47c472882168d17c to your computer and use it in GitHub Desktop.
Save m87h/74ad47c472882168d17c to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'erb'
Cluster = Struct.new(:name, :hosts)
class Host
attr_accessor :fqdn, :port, :user, :name, :proxy
def proxied?
!!@proxy
end
def ip?
!(IPAddr.new(@fqdn) rescue nil).nil?
end
end
class ERBContext
def initialize(hash)
hash.each_pair do |key, value|
instance_variable_set('@' + key.to_s, value)
end
end
def get_binding
binding
end
end
FQDN_RE = /(.+?)(?=\.)/
HOST_SPEC_RE = /(?:(?<proxy>[^\s]+)\s+->\s+)?(?:(?<user>[^@]+)@)?(?<fqdn>[^\s:]+)(?:\:(?<port>\d+))?(?:\s+\((?<name>[^\)]+)\))?/
CSSHRC = <<EOS
clusters = <%= @clusters.map(&:name).join(' ') %>
<% @clusters.each do |cluster| %>
<%= cluster.name %> = <%= cluster.hosts.map(&:name).join(' ') %>
<% end %>
EOS
def parse_host_spec(spec)
data = HOST_SPEC_RE.match(spec)
host = Host.new
host.fqdn = data['fqdn']
host.proxy = data['proxy']
host.port = data['port'] || 22
host.user = data['user']
host.name =
if data['name']
data['name']
else
FQDN_RE.match(data['fqdn'])[1]
end
host
end
def get_clusters
Dir.glob(File.expand_path('~/.ssh/hosts.d/*.hosts')).map do |hosts_file|
cluster = Cluster.new(File.basename(hosts_file, '.hosts'))
cluster.hosts = File.readlines(hosts_file).map(&:chomp).map { |spec| parse_host_spec(spec) }
cluster
end
end
File.open(File.expand_path('~/.csshrc'), File::CREAT|File::TRUNC|File::RDWR, 0644) do |io|
io.puts ERB.new(CSSHRC, nil, '%').result(ERBContext.new(clusters: get_clusters).get_binding)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment