let lib = import ; getDevices = net: if net ? devices && builtins.isAttrs net.devices then net.devices else throw "config/network.nix must define devices as an attrset."; getLocalDevices = devices: lib.filterAttrs (deviceName: device: if !builtins.isAttrs device then throw "Device '${deviceName}' must be an attrset." else if !(device ? type) || !builtins.isString device.type then throw "Device '${deviceName}' must define type as a string." else if !(device ? ip) || !builtins.isString device.ip || device.ip == "" then throw "Device '${deviceName}' must define ip as a non-empty string." else device.type == "local" ) devices; validateReservationShape = deviceName: reservation: let _ = if !builtins.isAttrs reservation then throw "Device '${deviceName}' reservation must be an attrset." else null; _hw = if reservation ? hw_address && builtins.isString reservation.hw_address && reservation.hw_address != "" then null else throw "Device '${deviceName}' reservation must define hw_address as a non-empty string."; _host = if reservation ? hostname && builtins.isString reservation.hostname && reservation.hostname != "" then null else throw "Device '${deviceName}' reservation must define hostname as a non-empty string."; in reservation; in { inherit getDevices getLocalDevices validateReservationShape; }