From 46275b41edaa6063bdfb3ba040421b79ebd27b35 Mon Sep 17 00:00:00 2001 From: tv Date: Tue, 11 Dec 2018 21:37:52 +0100 Subject: lib.krebs.genipv6: can compute suffix from name --- lib/krebs/genipv6.nix | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/krebs/genipv6.nix b/lib/krebs/genipv6.nix index 27df8bf5..8e105ab4 100644 --- a/lib/krebs/genipv6.nix +++ b/lib/krebs/genipv6.nix @@ -1,7 +1,7 @@ lib: with lib; let { - body = netname: subnetname: suffix: rec { + body = netname: subnetname: suffixSpec: rec { address = let suffix' = if hasEmptyGroup (parseAddress suffix) @@ -28,15 +28,45 @@ let { inherit subnetname; subnetCIDR = "${subnetAddress}/${toString subnetPrefixLength}"; subnetAddress = joinAddress subnetPrefix "::"; - subnetHash = hash subnetname; + subnetHash = simplify (hash 4 subnetname); subnetPrefix = joinAddress netPrefix subnetHash; subnetPrefixLength = netPrefixLength + 16; - inherit suffix; + suffix = getAttr (typeOf suffixSpec) { + set = + concatMapStringsSep + ":" + simplify + (stringToGroupsOf 4 (hash (suffixLength / 8) suffixSpec.hostName)); + string = suffixSpec; + }; suffixLength = addressLength - subnetPrefixLength; }; - hash = s: head (match "0*(.+)" (substring 0 4 (hashString "sha256" s))); + # Split string into list of chunks where each chunk is at most n chars long. + # The leftmost chunk might shorter. + # Example: stringToGroupsOf "123456" -> ["12" "3456"] + stringToGroupsOf = n: s: let + acc = + foldl' + (acc: c: if stringLength acc.chunk < n then { + chunk = acc.chunk + c; + chunks = acc.chunks; + } else { + chunk = c; + chunks = acc.chunks ++ [acc.chunk]; + }) + { + chunk = ""; + chunks = []; + } + (stringToCharacters s); + in + filter (x: x != []) ([acc.chunk] ++ acc.chunks); + + simplify = s: head (match "0*(.+)" s); + + hash = n: s: substring 0 n (hashString "sha256" s); dropLast = n: xs: reverseList (drop n (reverseList xs)); takeLast = n: xs: reverseList (take n (reverseList xs)); -- cgit v1.2.3