Skip to content

Instantly share code, notes, and snippets.

@peterkeen
Last active February 5, 2017 15:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peterkeen/f87ae8db4e7cf05d8e0fc69aa2f86748 to your computer and use it in GitHub Desktop.
Save peterkeen/f87ae8db4e7cf05d8e0fc69aa2f86748 to your computer and use it in GitHub Desktop.
require 'rubydns'
require 'httparty'
require 'lru_redux'
class ZeroTierAPI
include HTTParty
base_uri "https://my.zerotier.com/api"
headers 'Authorization' => "Bearer #{ENV['ZT_API_TOKEN']}"
def initialize
@cache = LruRedux::TTL::ThreadSafeCache.new(100, 300)
end
def members
@cache.getset('members') do
network_members = self.class.get("/network/#{ENV['ZT_NETWORK_ADDRESS']}/member").keys
network_members.map do |member|
self.class.get("/network/#{ENV['ZT_NETWORK_ADDRESS']}/member/#{member}")
end
end
end
def member(name)
members.detect { |m| m['nodeId'] == host || m['name'] == host }
end
end
INTERFACES = [
[:udp, "0.0.0.0", 5300],
[:tcp, "0.0.0.0", 5300]
]
ZT = ZeroTierAPI.new
RubyDNS::run_server(:listen => INTERFACES) do
match(/\w+\.#{ENV['ZT_NETWORK_NAME']/) do |transaction|
host, _ = transaction.name.split('.', 2)
member = ZT.member(host)
# inactive members sometimes have subnets as their ipAssignment
if member && member['config']['ipAssignments'].first !~ /\//
transaction.respond!(member['config']['ipAssignments'].first, ttl: 300)
else
transaction.fail!(:NXDomain)
end
end
otherwise do |transaction|
transaction.fail!(:NXDomain)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment