nix/pkgs/subnetplan: init

This commit is contained in:
Astro 2021-11-17 23:57:16 +01:00
parent 7c9c6c4a9e
commit 557f63b7c1
7 changed files with 243 additions and 2 deletions

View File

@ -79,8 +79,13 @@ let
starlink = import ./starlink {
inherit pkgs;
};
subnetplans = import ./subnetplans.nix {
inherit self nixpkgs system;
};
in
rootfs-packages // vm-packages // device-templates // network-graphs // starlink // {
rootfs-packages // vm-packages // device-templates // network-graphs // starlink // subnetplans // {
inherit export-openwrt-models export-config dns-slaves
encrypt-secrets decrypt-secrets switch-to-production;
encrypt-secrets decrypt-secrets switch-to-production
;
}

View File

@ -0,0 +1,3 @@
source "https://rubygems.org"
gem "ipaddress_2", "~> 0.14"

View File

@ -0,0 +1,13 @@
GEM
remote: https://rubygems.org/
specs:
ipaddress_2 (0.14.0)
PLATFORMS
ruby
DEPENDENCIES
ipaddress_2 (~> 0.14)
BUNDLED WITH
2.1.4

View File

@ -0,0 +1,15 @@
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
let
gems = bundlerEnv {
name = "gems-for-subnetplan";
gemdir = ./.;
};
in stdenv.mkDerivation rec {
name = "subnetplan";
buildInputs = [ gems.wrappedRuby ];
buildCommand = ''
install -D -m755 ${./render.rb} $out/bin/${name}
patchShebangs $out/bin/${name}
'';
}

View File

@ -0,0 +1,12 @@
{
ipaddress_2 = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1wdy1ka0i9mncjqid2kv3ng6gi95y5xb9ykl0ar8lnrriia42v1c";
type = "gem";
};
version = "0.14.0";
};
}

View File

@ -0,0 +1,139 @@
#!/usr/bin/env ruby
require 'ipaddress_2'
require 'erb'
TABLE_WIDTH = 8
class Subnet
attr_reader :addr, :desc
attr_accessor :addr_visible
def initialize addr, desc
@addr = addr
@desc = desc
@addr_visible = false
end
end
class Group
attr_accessor :net, :blocks
def initialize net, blocks
@net = net
@blocks = blocks
end
end
class Block
attr_accessor :label, :name
def initialize label, name
@label = label
@name = name
end
end
nets = []
while line = gets
a, desc = line.split(/ /, 2)
addr = IPAddress.parse a
desc.chomp!
nets << Subnet.new(addr, desc)
end
nets.sort_by! { |net| net.addr }
collisions = 0
prev = nil
nets.each do |net|
if prev and (net.addr.include?(prev.addr) or prev.addr.include?(net.addr))
STDERR.puts "#{prev.addr} and #{net.addr} overlap"
collisions += 1
end
prev = net
end
exit 1 if collisions > 0
GROUP_PREFIX = 16
groups = {}
nets.each do |net|
group = net.addr.supernet(GROUP_PREFIX).to_s
(groups[group] ||= []) << net
end
max_prefix = groups.collect { nets.collect { |net| net.addr.prefix }.max }.max
groups = groups.collect do |group, nets|
allnet = nets[0].addr.clone
while allnet.prefix > 0 and not allnet.include?(nets[nets.size - 1].addr)
allnet = allnet.supernet(allnet.prefix - 1)
end
blocks = []
row = []
allnet.subnet(max_prefix).each do |addr|
net = nets.select { |net| net.addr.include? addr }[0]
label = net ? "#{addr}/#{net.addr.prefix}" : addr.to_s
row << Block.new(label, net ? net.desc : "")
if row.size >= TABLE_WIDTH
blocks << row
row = []
end
end
blocks << row if row.size > 0
blocks.each do |row|
prev_name = nil
row.each_with_index do |block|
block.label = "" if prev_name == block.name
prev_name = block.name
end
end
Group.new(allnet, blocks)
end
def background_color desc
case desc
when "core"
"#9F9F9F"
when "mgmt"
"#FF3F3F"
when "c3d2"
"yellow"
when "serv", "cluster"
"orange"
when "pub"
"#7FFF7F"
when /priv(\d+)/
"hsl(240, 80%, #{60 + 5 * ($1.to_i % 8)}%)"
else
"white"
end
end
html = ERB::new <<~EOF
<html>
<head>
<title>Subnetwork Plan</title>
</head>
<body>
<table border="1">
<% groups.each do |group| %>
<tr>
<th colspan="<%= TABLE_WIDTH %>"><%= group.net.to_string %></th>
</tr>
<% group.blocks.each do |row| %>
<tr>
<% row.each do |block| %>
<td style="background-color: <%= background_color(block.name) %>"><%= block.label %> <%= block.name %></td>
<% end %>
</tr>
<% end %>
<% end %>
</table>
</body>
</html>
EOF
puts html.result

54
nix/pkgs/subnetplans.nix Normal file
View File

@ -0,0 +1,54 @@
{ self, nixpkgs, system }:
with nixpkgs.legacyPackages.${system};
let
config = self.lib.config;
in
rec {
subnetplan4 =
stdenv.mkDerivation {
name = "subnetplan4.html";
src = builtins.toFile "subnets4.txt" (
lib.concatMapStringsSep "\n" (net:
"${config.site.net.${net}.subnet4} ${net}"
) (builtins.attrNames (
lib.filterAttrs (_: { subnet4, ... }: subnet4 != null)
config.site.net
))
);
buildInputs = [
(import ./subnetplan { inherit pkgs; })
];
buildCommand = ''
subnetplan < $src > $out
'';
};
subnetplan6 =
stdenv.mkDerivation {
name = "subnetplan6.html";
src = builtins.toFile "subnets6.txt" (
lib.concatMapStrings (net:
lib.concatMapStrings (ctx: ''
${config.site.net.${net}.subnets6.${ctx}} ${net}
'') (builtins.attrNames config.site.net.${net}.subnets6)
) (builtins.attrNames config.site.net)
);
buildInputs = [
(import ./subnetplan { inherit pkgs; })
];
buildCommand = ''
subnetplan < $src > $out
'';
};
subnetplans = runCommand "subnetplans" {} ''
DIR=$out/share/doc/zentralwerk
mkdir -p $DIR $out/nix-support
${lib.concatMapStrings (pkg: ''
ln -s ${pkg} $DIR/${pkg.name}
echo doc report $DIR/${pkg.name} >> $out/nix-support/hydra-build-products
'') [ subnetplan4 subnetplan6 ]}
'';
}