#!/usr/bin/env ruby # Runs the wrapped command with envronment variables taken from etcd. require 'json' require 'net/http' def usage puts "Usage: #{$PROGRAM_NAME} [ ... ] -- " end def env_vars(keys) var = Array.new keys.each do |key| response = fetch "http://#{etcd_host}:#{etcd_port}/v2/keys#{key}" var << (JSON.parse(response)['node']['nodes'] || []) .map { |var| [var['key'].split('/').last, var['value']] } .to_h end var end def etcd_host host = (ENV['ETCD_HOST'] || `ip route | awk '/default/ { print $3 }'`).strip rescue '' raise 'etcd host not found' if host.empty? fetch "http://#{host}:#{etcd_port}/v2/keys/" host end def etcd_port ENV['ETCD_PORT'] || 4001 end def fetch(uri_str, limit = 10) raise 'Too many HTTP redirects' if limit == 0 response = Net::HTTP.get_response(URI(uri_str)) case response when Net::HTTPSuccess then response.body when Net::HTTPRedirection then fetch(response['location'], limit - 1) else response.value end end if __FILE__ == $PROGRAM_NAME key_str, *commands = ARGV.join(" ").split(" -- ") keys = key_str.split(" ") if commands.empty? usage exit 1 end exec env_vars(keys).reduce({}, :merge), *commands end