Compare commits
No commits in common. "dev" and "master" have entirely different histories.
|
@ -10,4 +10,4 @@ DEPENDENCIES
|
||||||
xmpp4r
|
xmpp4r
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.1.4
|
1.17.2
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
{ pkgs, helpers, ... }:
|
|
||||||
|
|
||||||
with pkgs.lib;
|
|
||||||
let
|
|
||||||
gems = pkgs.bundlerEnv {
|
|
||||||
name = "gems-for-backplane-dns-client";
|
|
||||||
gemdir = ./.;
|
|
||||||
};
|
|
||||||
|
|
||||||
in helpers.lib.writeRubyApplication {
|
|
||||||
name = "backplane-dns-client";
|
|
||||||
inherit pkgs;
|
|
||||||
ruby = gems.wrappedRuby;
|
|
||||||
text = readFile ./dns-client.rb;
|
|
||||||
}
|
|
199
dns-client.rb
199
dns-client.rb
|
@ -1,70 +1,70 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'ipaddr'
|
require "ipaddr"
|
||||||
require 'socket'
|
require "socket"
|
||||||
require 'optparse'
|
require "optparse"
|
||||||
require 'json'
|
require "json"
|
||||||
require 'securerandom'
|
require "securerandom"
|
||||||
require 'xmpp4r'
|
|
||||||
|
|
||||||
options = {
|
require "xmpp4r"
|
||||||
sshfp: []
|
|
||||||
}
|
|
||||||
|
|
||||||
# rubocop:disable Metrics/BlockLength
|
puts ARGV
|
||||||
|
|
||||||
|
options = {}
|
||||||
OptionParser.new do |opts|
|
OptionParser.new do |opts|
|
||||||
opts.banner = 'usage: ${$0} [opts]'
|
opts.banner = "usage: ${$0} [opts]"
|
||||||
|
|
||||||
opts.on('-i', '--interface=INTERFACE',
|
opts.on("-i", "--interface=INTERFACE",
|
||||||
'Publicly-accessible interface') do |interface|
|
"Publicly-accessible interface") do |interface|
|
||||||
options[:interface] = interface
|
options[:interface] = interface
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.on('-d', '--domain=DOMAIN',
|
opts.on("-d", "--domain=DOMAIN",
|
||||||
'Domain on which we wish to set the new ip') do |domain|
|
"Domain on which we wish to set the new ip") do |domain|
|
||||||
options[:domain] = domain
|
options[:domain] = domain
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.on('-s', '--server=SERVER',
|
opts.on("-s", "--server=SERVER",
|
||||||
'Backplane DNS XMPP server') do |server|
|
"Backplane DNS XMPP server") do |server|
|
||||||
options[:server] = server
|
options[:server] = server
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.on('-p', '--password-file=/path/to/file',
|
opts.on("-p", "--password-file=/path/to/file",
|
||||||
'File containing password for XMPP server') do |pw_file|
|
"File containing password for XMPP server") do |pw_file|
|
||||||
options[:pw_file] = pw_file
|
options[:pw_file] = pw_file
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.on('-4', '--ipv4',
|
opts.on("-4", "--ipv4",
|
||||||
'Check for a public IPv4 and register with the backplane.') do
|
"Check for a public IPv4 and register with the backplane.") do
|
||||||
options[:ipv4] = true
|
options[:ipv4] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.on('-6', '--ipv6',
|
opts.on("-6", "--ipv6",
|
||||||
'Check for a public IPv6 and register with the backplane.') do
|
"Check for a public IPv6 and register with the backplane.") do
|
||||||
options[:ipv6] = true
|
options[:ipv6] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.on('-f', '--ssh-fp=SSHFP', 'SSH fingerprint to register with he backplane.') do |sshfp|
|
opts.on("-f", "--sshfp=FILE",
|
||||||
options[:sshfp] << sshfp
|
"Register host SSH key fingerprints with the backplane.") do |file|
|
||||||
|
options[:sshfp] = [] if not options[:sshfp]
|
||||||
|
options[:sshfp] = options[:sshfp] + [file]
|
||||||
end
|
end
|
||||||
end.parse!
|
end.parse!
|
||||||
# rubocop:enable Metrics/BlockLength
|
|
||||||
|
|
||||||
raise 'domain is required' unless options[:domain]
|
|
||||||
raise 'server is required' unless options[:server]
|
|
||||||
raise 'password file is required' unless options[:pw_file]
|
|
||||||
raise 'at least one of -4 or -6 required' unless options[:ipv4] || options[:ipv6]
|
|
||||||
|
|
||||||
password = options[:pw_file]
|
|
||||||
raise "file does not exist or is not readable: #{password}" unless File::readable?(password)
|
|
||||||
|
|
||||||
def error(msg)
|
def error(msg)
|
||||||
puts msg
|
puts msg
|
||||||
raise msg
|
throw msg
|
||||||
end
|
end
|
||||||
|
|
||||||
# XMPP client for Fudo Backplane
|
error("domain is required") if not options[:domain]
|
||||||
|
error("server is required") if not options[:server]
|
||||||
|
error("password file is required") if not options[:pw_file]
|
||||||
|
error("at least one of -4 or -6 required") if not (options[:ipv4] or options[:ipv6])
|
||||||
|
|
||||||
|
if not File::readable?(options[:pw_file])
|
||||||
|
error("file does not exist or is not readable")
|
||||||
|
end
|
||||||
|
password = File::open(options[:pw_file]) { |f| f.gets.strip }
|
||||||
|
|
||||||
class XMPPClient
|
class XMPPClient
|
||||||
def initialize(domain, hostname, server, password)
|
def initialize(domain, hostname, server, password)
|
||||||
@jid = "host-#{hostname}@#{server}"
|
@jid = "host-#{hostname}@#{server}"
|
||||||
|
@ -80,7 +80,7 @@ class XMPPClient
|
||||||
disconnect if connected?
|
disconnect if connected?
|
||||||
@client = Jabber::Client::new(@jid)
|
@client = Jabber::Client::new(@jid)
|
||||||
@client.connect # will use SRV records
|
@client.connect # will use SRV records
|
||||||
error('failed to initialize TLS connection') unless @client.is_tls?
|
error("failed to initialize TLS connection") if not @client.is_tls?
|
||||||
@client.auth(@password)
|
@client.auth(@password)
|
||||||
register_response_callback
|
register_response_callback
|
||||||
end
|
end
|
||||||
|
@ -94,7 +94,7 @@ class XMPPClient
|
||||||
if @client.respond_to?(:is_connected?) && @client.is_connected?
|
if @client.respond_to?(:is_connected?) && @client.is_connected?
|
||||||
begin
|
begin
|
||||||
@client.close
|
@client.close
|
||||||
rescue Errno::EPIPE, IOError
|
rescue Errno::EPIPE, IOError => e
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -110,7 +110,7 @@ class XMPPClient
|
||||||
@client.send(msg)
|
@client.send(msg)
|
||||||
response = receive_response(msg_id)
|
response = receive_response(msg_id)
|
||||||
puts "response: #{response}"
|
puts "response: #{response}"
|
||||||
response && response['status'] == 'OK'
|
response and response["status"] == "OK"
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_ip(ip)
|
def send_ip(ip)
|
||||||
|
@ -125,7 +125,7 @@ class XMPPClient
|
||||||
{
|
{
|
||||||
version: 1,
|
version: 1,
|
||||||
service: :dns,
|
service: :dns,
|
||||||
msgid: msg_id,
|
msgid: msg_id,
|
||||||
payload: req
|
payload: req
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -133,16 +133,16 @@ class XMPPClient
|
||||||
def ip_payload(ip)
|
def ip_payload(ip)
|
||||||
{
|
{
|
||||||
request: ip.ipv4? ? :change_ipv4 : :change_ipv6,
|
request: ip.ipv4? ? :change_ipv4 : :change_ipv6,
|
||||||
domain: @domain,
|
domain: @domain,
|
||||||
ip: ip.to_s
|
ip: ip.to_s
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def sshfp_payload(fingerprint)
|
def sshfp_payload(fp)
|
||||||
{
|
{
|
||||||
request: :change_sshfp,
|
request: :change_sshfp,
|
||||||
domain: @domain,
|
domain: @domain,
|
||||||
sshfp: fingerprint
|
sshfp: fp
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -158,36 +158,35 @@ class XMPPClient
|
||||||
|
|
||||||
def receive_response(msg_id)
|
def receive_response(msg_id)
|
||||||
msg = @responses.pop
|
msg = @responses.pop
|
||||||
return msg if msg && msg['msgid'] == msg_id.to_s
|
return msg if (msg and (msg["msgid"] == msg_id.to_s))
|
||||||
|
|
||||||
raise "failed to receive message: #{msg}"
|
raise "failed to receive message: #{msg}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RESERVED_V4_NETWORKS = [
|
RESERVED_V4_NETWORKS = [
|
||||||
'0.0.0.0/8',
|
"0.0.0.0/8",
|
||||||
'10.0.0.0/8',
|
"10.0.0.0/8",
|
||||||
'100.64.0.0/10',
|
"100.64.0.0/10",
|
||||||
'127.0.0.0/8',
|
"127.0.0.0/8",
|
||||||
'169.254.0.0/16',
|
"169.254.0.0/16",
|
||||||
'172.16.0.0/12',
|
"172.16.0.0/12",
|
||||||
'192.0.0.0/24',
|
"192.0.0.0/24",
|
||||||
'192.0.2.0/24',
|
"192.0.2.0/24",
|
||||||
'192.88.99.0/24',
|
"192.88.99.0/24",
|
||||||
'192.168.0.0/16',
|
"192.168.0.0/16",
|
||||||
'198.18.0.0/15',
|
"198.18.0.0/15",
|
||||||
'198.51.100.0/24',
|
"198.51.100.0/24",
|
||||||
'203.0.113.0/24',
|
"203.0.113.0/24",
|
||||||
'224.0.0.0/4',
|
"224.0.0.0/4",
|
||||||
'240.0.0.0/4',
|
"240.0.0.0/4",
|
||||||
'255.255.255.255/32'
|
"255.255.255.255/32"
|
||||||
].map { |ip| IPAddr.new(ip) }
|
].map { |ip| IPAddr.new(ip) }
|
||||||
|
|
||||||
def public_ip?(ip)
|
def public_ip?(ip)
|
||||||
if ip.ipv4?
|
if (ip.ipv4?)
|
||||||
RESERVED_V4_NETWORKS.none? { |network| network.include? ip }
|
not RESERVED_V4_NETWORKS.any? { |network| network.include? ip }
|
||||||
elsif ip.ipv6?
|
elsif (ip.ipv6?)
|
||||||
!(ip.link_local? || ip.loopback? || ip.private?)
|
not (ip.link_local? or ip.loopback? or ip.private?)
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -197,28 +196,38 @@ def to_ipaddr(addrinfo)
|
||||||
if addrinfo.ipv4?
|
if addrinfo.ipv4?
|
||||||
IPAddr.new addrinfo.ip_address
|
IPAddr.new addrinfo.ip_address
|
||||||
else
|
else
|
||||||
IPAddr.new(addrinfo.ip_address.split('%')[0])
|
IPAddr.new(addrinfo.ip_address.split("%")[0])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_addresses
|
def local_addresses
|
||||||
ips = Socket::ip_address_list.map do |addrinfo|
|
Socket::ip_address_list.map do |addrinfo|
|
||||||
to_ipaddr(addrinfo)
|
to_ipaddr(addrinfo)
|
||||||
end
|
end.select { |ip| public_ip?(ip) }
|
||||||
ips.select { |ip| public_ip?(ip) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def interface_addresses(interface)
|
def interface_addresses(interface)
|
||||||
ifaddrs = Socket::getifaddrs.select do |ifaddr|
|
Socket::getifaddrs.select do |ifaddr|
|
||||||
ifaddr.name == interface &&
|
ifaddr.name == interface
|
||||||
ifaddr.addr.ip? &&
|
end.select do |ifaddr|
|
||||||
ifaddr.flag & Socket::IFF_MULTICAST != 0
|
ifaddr.addr.ip? and (ifaddr.flags & Socket::IFF_MULTICAST != 0)
|
||||||
|
end.map do |ifaddr|
|
||||||
|
to_ipaddr(ifaddr.addr)
|
||||||
|
end.filter do |ip|
|
||||||
|
public_ip? ip
|
||||||
end
|
end
|
||||||
ifaddrs.map { |ifaddr| to_ipaddr(ifaddr.addr) }.filter(:public_ip?)
|
end
|
||||||
|
|
||||||
|
def host_sshfp(keys)
|
||||||
|
keys.flat_map { |keyfile|
|
||||||
|
`ssh-keygen -r hostname -f #{keyfile}`.split("\n")
|
||||||
|
}.map { |fp|
|
||||||
|
fp.match(/[0-9] [0-9] [a-fA-F0-9]{32,64}$/)[0]
|
||||||
|
}.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
def hostname
|
def hostname
|
||||||
Socket.gethostname.split('.').first
|
Socket.gethostname.split(".").first
|
||||||
end
|
end
|
||||||
|
|
||||||
client = XMPPClient::new(options[:domain],
|
client = XMPPClient::new(options[:domain],
|
||||||
|
@ -238,13 +247,13 @@ begin
|
||||||
end
|
end
|
||||||
|
|
||||||
if options[:ipv4]
|
if options[:ipv4]
|
||||||
ipv4 = addrs.find(:ipv4?)
|
ipv4 = addrs.find { |ip| ip.ipv4? }
|
||||||
if ipv4
|
if ipv4
|
||||||
puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN A => #{ipv4}"
|
puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN A => #{ipv4.to_s}"
|
||||||
if client.send_ip(ipv4)
|
if client.send_ip(ipv4)
|
||||||
puts 'OK'
|
puts "OK"
|
||||||
else
|
else
|
||||||
puts 'ERROR'
|
puts "ERROR"
|
||||||
success = false
|
success = false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -253,13 +262,13 @@ begin
|
||||||
end
|
end
|
||||||
|
|
||||||
if options[:ipv6]
|
if options[:ipv6]
|
||||||
ipv6 = addrs.find(:ipv6?)
|
ipv6 = addrs.find { |ip| ip.ipv6? }
|
||||||
if ipv6
|
if ipv6
|
||||||
puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN AAAA => #{ipv6}"
|
puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN AAAA => #{ipv6.to_s}"
|
||||||
if client.send_ip(ipv6)
|
if client.send_ip(ipv6)
|
||||||
puts 'OK'
|
puts "OK"
|
||||||
else
|
else
|
||||||
puts 'ERROR'
|
puts "ERROR"
|
||||||
success = false
|
success = false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -267,14 +276,18 @@ begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
unless options[:sshfp].empty?
|
if options[:sshfp]
|
||||||
fps = options[:sshfp]
|
fps = host_sshfp(options[:sshfp])
|
||||||
puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN SSHFP => #{fps}"
|
if not fps.empty?
|
||||||
if client.send_sshfp(fps)
|
puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN SSHFP => #{fps}"
|
||||||
puts 'OK'
|
if client.send_sshfp(fps)
|
||||||
|
puts "OK"
|
||||||
|
else
|
||||||
|
puts "ERROR"
|
||||||
|
success = false
|
||||||
|
end
|
||||||
else
|
else
|
||||||
puts 'ERROR'
|
puts "#{options[:server]}: no valid sshfps found"
|
||||||
success = false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
|
|
236
flake.lock
236
flake.lock
|
@ -1,236 +0,0 @@
|
||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"clj-nix": {
|
|
||||||
"inputs": {
|
|
||||||
"devshell": "devshell",
|
|
||||||
"flake-utils": "flake-utils_2",
|
|
||||||
"nixpkgs": [
|
|
||||||
"helpers",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1663870497,
|
|
||||||
"narHash": "sha256-gnoyYWvZl64WBqR3tf9bKHAznEtBCHmwx7taHghH9Lw=",
|
|
||||||
"owner": "jlesquembre",
|
|
||||||
"repo": "clj-nix",
|
|
||||||
"rev": "23d9daacc80e634df078c4c6e34d592e1593d84c",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "jlesquembre",
|
|
||||||
"repo": "clj-nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"clj2nix": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat",
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"utils": "utils"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1654804151,
|
|
||||||
"narHash": "sha256-D/fRFmem9MoSWAmeK8VE6EMtfBRF3xPpEXp9AotW+K0=",
|
|
||||||
"owner": "hlolli",
|
|
||||||
"repo": "clj2nix",
|
|
||||||
"rev": "a321028a6670fc6329272a4d1ac0054f0b25d920",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hlolli",
|
|
||||||
"repo": "clj2nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devshell": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": [
|
|
||||||
"helpers",
|
|
||||||
"clj-nix",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1658746384,
|
|
||||||
"narHash": "sha256-CCJcoMOcXyZFrV1ag4XMTpAPjLWb4Anbv+ktXFI1ry0=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "devshell",
|
|
||||||
"rev": "0ffc7937bb5e8141af03d462b468bd071eb18e1b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "devshell",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-compat": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1627913399,
|
|
||||||
"narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1642700792,
|
|
||||||
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1656928814,
|
|
||||||
"narHash": "sha256-RIFfgBuKz6Hp89yRr7+NR5tzIAbn52h8vT6vXkYjZoM=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "7e2a3b3dfd9af950a856d66b0a7d01e3c18aa249",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"helpers": {
|
|
||||||
"inputs": {
|
|
||||||
"clj-nix": "clj-nix",
|
|
||||||
"clj2nix": "clj2nix",
|
|
||||||
"nixpkgs": "nixpkgs_2",
|
|
||||||
"utils": "utils_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1674932271,
|
|
||||||
"narHash": "sha256-ArHZiRPpPMJyGSa65VKwTUG6aNICtMTf26pjOuK4snQ=",
|
|
||||||
"ref": "refs/heads/master",
|
|
||||||
"rev": "1923e4cf4ef116782c9ea29416150bdb3d532b0b",
|
|
||||||
"revCount": 17,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.fudo.org/fudo-public/nix-helpers.git"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.fudo.org/fudo-public/nix-helpers.git"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1637881340,
|
|
||||||
"narHash": "sha256-/meU5CTm8GnaETZrJa0UqBQvk9T/jKp1+MLIQQ7FTTo=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "d460f48ddb884f7270b7f7bfcbf8a7b91140caa5",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1672353432,
|
|
||||||
"narHash": "sha256-oZfgp/44/o2tWiylV30cR+DLyWTJ+5dhsdWZVpzs3e4=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "913a47cd064cc06440ea84e5e0452039a85781f0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"id": "nixpkgs",
|
|
||||||
"ref": "nixos-22.11",
|
|
||||||
"type": "indirect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1672580127,
|
|
||||||
"narHash": "sha256-3lW3xZslREhJogoOkjeZtlBtvFMyxHku7I/9IVehhT8=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "0874168639713f547c05947c76124f78441ea46c",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"id": "nixpkgs",
|
|
||||||
"ref": "nixos-22.05",
|
|
||||||
"type": "indirect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"helpers": "helpers",
|
|
||||||
"nixpkgs": "nixpkgs_3",
|
|
||||||
"utils": "utils_3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"utils": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1637014545,
|
|
||||||
"narHash": "sha256-26IZAc5yzlD9FlDT54io1oqG/bBoyka+FJk5guaX4x4=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "bba5dcc8e0b20ab664967ad83d24d64cb64ec4f4",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"utils_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1667395993,
|
|
||||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"utils_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1667395993,
|
|
||||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
34
flake.nix
34
flake.nix
|
@ -1,34 +0,0 @@
|
||||||
{
|
|
||||||
description = "Fudo Backplane Client.";
|
|
||||||
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "nixpkgs/nixos-22.05";
|
|
||||||
helpers.url = "git+https://git.fudo.org/fudo-public/nix-helpers.git";
|
|
||||||
utils.url = "github:numtide/flake-utils";
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = { nixpkgs, helpers, utils, ... }:
|
|
||||||
utils.lib.eachDefaultSystem (system:
|
|
||||||
let pkgs = nixpkgs.legacyPackages."${system}";
|
|
||||||
in {
|
|
||||||
packages = rec {
|
|
||||||
default = backplaneDnsClient;
|
|
||||||
backplaneDnsClient =
|
|
||||||
import ./dns-client.nix { inherit pkgs helpers; };
|
|
||||||
};
|
|
||||||
|
|
||||||
devShells = rec {
|
|
||||||
default = update;
|
|
||||||
update = let
|
|
||||||
update-deps = pkgs.writeShellApplication {
|
|
||||||
name = "update-deps";
|
|
||||||
runtimeInputs = with pkgs; [ bundler bundix ];
|
|
||||||
text = ''
|
|
||||||
bundle lock
|
|
||||||
bundix
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in pkgs.mkShell { buildInputs = with pkgs; [ update-deps ]; };
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
Reference in New Issue