#!/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) result = keys.reduce({}) do |memo, key| response = fetch "http://#{etcd_host}:#{etcd_port}/v2/keys#{key}" vars = (JSON.parse(response)['node']['nodes'] || []) .map { |var| [var['key'].split('/').last, var['value']] } .to_h memo.merge(vars) end 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 sep = ARGV.index '--' if sep keys = ARGV[0...sep] commands = ARGV[(sep + 1)..-1] else keys = ARGV.take(1) commands = ARGV.drop(1) end if commands.empty? usage exit 1 end exec env_vars(keys), *commands