nipap: init at v0.32.7 (#417076)

Changed files
+746
nixos
doc
manual
release-notes
modules
services
web-apps
tests
pkgs
by-name
ni
nipap
nipap-cli
nipap-www
development
python-modules
flask-xml-rpc-re
nipap
pynipap
servers
sql
postgresql
ext
top-level
+2
nixos/doc/manual/release-notes/rl-2511.section.md
···
- [Szurubooru](https://github.com/rr-/szurubooru), an image board engine inspired by services such as Danbooru, dedicated for small and medium communities. Available as [services.szurubooru](#opt-services.szurubooru.enable).
+
- The [Neat IP Address Planner](https://spritelink.github.io/NIPAP/) (NIPAP) can now be enabled through [services.nipap.enable](#opt-services.nipap.enable).
+
- [nix-store-veritysetup](https://github.com/nikstur/nix-store-veritysetup-generator), a systemd generator to unlock the Nix Store as a dm-verity protected block device. Available as [boot.initrd.nix-store-veritysetup](options.html#opt-boot.initrd.nix-store-veritysetup.enable).
- [SuiteNumérique Docs](https://github.com/suitenumerique/docs), a collaborative note taking, wiki and documentation web platform and alternative to Notion or Outline. Available as [services.lasuite-docs](#opt-services.lasuite-docs.enable).
+1
nixos/modules/module-list.nix
···
./services/web-apps/nextjs-ollama-llm-ui.nix
./services/web-apps/nexus.nix
./services/web-apps/nifi.nix
+
./services/web-apps/nipap.nix
./services/web-apps/node-red.nix
./services/web-apps/nostr-rs-relay.nix
./services/web-apps/ocis.nix
+331
nixos/modules/services/web-apps/nipap.nix
···
+
{
+
config,
+
lib,
+
pkgs,
+
...
+
}:
+
+
let
+
cfg = config.services.nipap;
+
iniFmt = pkgs.formats.ini { };
+
+
configFile = iniFmt.generate "nipap.conf" cfg.settings;
+
+
defaultUser = "nipap";
+
defaultAuthBackend = "local";
+
dataDir = "/var/lib/nipap";
+
+
defaultServiceConfig = {
+
WorkingDirectory = dataDir;
+
User = cfg.user;
+
Group = config.users.users."${cfg.user}".group;
+
Restart = "on-failure";
+
RestartSec = 30;
+
};
+
+
escapedHost = host: if lib.hasInfix ":" host then "[${host}]" else host;
+
in
+
{
+
options.services.nipap = {
+
enable = lib.mkEnableOption "global Neat IP Address Planner (NIPAP) configuration";
+
+
user = lib.mkOption {
+
type = lib.types.str;
+
description = "User to use for running NIPAP services.";
+
default = defaultUser;
+
};
+
+
settings = lib.mkOption {
+
description = ''
+
Configuration options to set in /etc/nipap/nipap.conf.
+
'';
+
+
default = { };
+
+
type = lib.types.submodule {
+
freeformType = iniFmt.type;
+
+
options = {
+
nipapd = {
+
listen = lib.mkOption {
+
type = lib.types.str;
+
default = "::1";
+
description = "IP address to bind nipapd to.";
+
};
+
port = lib.mkOption {
+
type = lib.types.port;
+
default = 1337;
+
description = "Port to bind nipapd to.";
+
};
+
+
foreground = lib.mkOption {
+
type = lib.types.bool;
+
default = true;
+
description = "Remain in foreground rather than forking to background.";
+
};
+
debug = lib.mkOption {
+
type = lib.types.bool;
+
default = false;
+
description = "Enable debug logging.";
+
};
+
+
db_host = lib.mkOption {
+
type = lib.types.str;
+
default = "";
+
description = "PostgreSQL host to connect to. Empty means use UNIX socket.";
+
};
+
db_name = lib.mkOption {
+
type = lib.types.str;
+
default = cfg.user;
+
defaultText = defaultUser;
+
description = "Name of database to use on PostgreSQL server.";
+
};
+
};
+
+
auth = {
+
default_backend = lib.mkOption {
+
type = lib.types.str;
+
default = defaultAuthBackend;
+
description = "Name of auth backend to use by default.";
+
};
+
auth_cache_timeout = lib.mkOption {
+
type = lib.types.int;
+
default = 3600;
+
description = "Seconds to store cached auth entries for.";
+
};
+
};
+
};
+
};
+
};
+
+
authBackendSettings = lib.mkOption {
+
description = ''
+
auth.backends options to set in /etc/nipap/nipap.conf.
+
'';
+
+
default = {
+
"${defaultAuthBackend}" = {
+
type = "SqliteAuth";
+
db_path = "${dataDir}/local_auth.db";
+
};
+
};
+
+
type = lib.types.submodule {
+
freeformType = iniFmt.type;
+
};
+
};
+
+
nipapd = {
+
enable = lib.mkEnableOption "nipapd server";
+
package = lib.mkPackageOption pkgs "nipap" { };
+
+
database.createLocally = lib.mkOption {
+
type = lib.types.bool;
+
default = true;
+
description = "Create a nipap database automatically.";
+
};
+
};
+
+
nipap-www = {
+
enable = lib.mkEnableOption "nipap-www server";
+
package = lib.mkPackageOption pkgs "nipap-www" { };
+
+
xmlrpcURIFile = lib.mkOption {
+
type = lib.types.nullOr lib.types.path;
+
default = null;
+
description = "Path to file containing XMLRPC URI for use by web UI - this is a secret, since it contains auth credentials. If null, it will be initialized assuming that the auth database is local.";
+
};
+
+
workers = lib.mkOption {
+
type = lib.types.int;
+
default = 4;
+
description = "Number of worker processes for Gunicorn to fork.";
+
};
+
umask = lib.mkOption {
+
type = lib.types.str;
+
default = "0";
+
description = "umask for files written by Gunicorn, including UNIX socket.";
+
};
+
+
unixSocket = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
default = null;
+
description = "Path to UNIX socket to bind to.";
+
example = "/run/nipap/nipap-www.sock";
+
};
+
host = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
default = "::";
+
description = "Host to bind to.";
+
};
+
port = lib.mkOption {
+
type = lib.types.nullOr lib.types.port;
+
default = 21337;
+
description = "Port to bind to.";
+
};
+
};
+
};
+
+
config = lib.mkIf cfg.enable (
+
lib.mkMerge [
+
{
+
systemd.tmpfiles.rules = [
+
"d '${dataDir}' - ${cfg.user} ${config.users.users."${cfg.user}".group} - -"
+
];
+
+
environment.etc."nipap/nipap.conf" = {
+
source = configFile;
+
};
+
+
services.nipap.settings = lib.attrsets.mapAttrs' (name: value: {
+
name = "auth.backends.${name}";
+
inherit value;
+
}) cfg.authBackendSettings;
+
+
services.nipap.nipapd.enable = lib.mkDefault true;
+
services.nipap.nipap-www.enable = lib.mkDefault true;
+
+
environment.systemPackages = [
+
cfg.nipapd.package
+
];
+
}
+
(lib.mkIf (cfg.user == defaultUser) {
+
users.users."${defaultUser}" = {
+
isSystemUser = true;
+
group = defaultUser;
+
home = dataDir;
+
};
+
users.groups."${defaultUser}" = { };
+
})
+
(lib.mkIf (cfg.nipapd.enable && cfg.nipapd.database.createLocally) {
+
services.postgresql = {
+
enable = true;
+
extensions = ps: with ps; [ ip4r ];
+
ensureUsers = [
+
{
+
name = cfg.user;
+
}
+
];
+
ensureDatabases = [ cfg.settings.nipapd.db_name ];
+
};
+
+
systemd.services.postgresql.serviceConfig.ExecStartPost =
+
let
+
sqlFile = pkgs.writeText "nipapd-setup.sql" ''
+
CREATE EXTENSION IF NOT EXISTS ip4r;
+
+
ALTER SCHEMA public OWNER TO "${cfg.user}";
+
ALTER DATABASE "${cfg.settings.nipapd.db_name}" OWNER TO "${cfg.user}";
+
'';
+
in
+
[
+
''
+
${lib.getExe' config.services.postgresql.finalPackage "psql"} -d "${cfg.settings.nipapd.db_name}" -f "${sqlFile}"
+
''
+
];
+
})
+
(lib.mkIf cfg.nipapd.enable {
+
systemd.services.nipapd =
+
let
+
pkg = cfg.nipapd.package;
+
in
+
{
+
description = "Neat IP Address Planner";
+
after = [
+
"network.target"
+
"systemd-tmpfiles-setup.service"
+
] ++ lib.optional (cfg.settings.nipapd.db_host == "") "postgresql.service";
+
requires = lib.optional (cfg.settings.nipapd.db_host == "") "postgresql.service";
+
wantedBy = [ "multi-user.target" ];
+
preStart = lib.optionalString (cfg.settings.auth.default_backend == defaultAuthBackend) ''
+
# Create/upgrade local auth database
+
umask 077
+
${pkg}/bin/nipap-passwd create-database >/dev/null 2>&1
+
${pkg}/bin/nipap-passwd upgrade-database >/dev/null 2>&1
+
'';
+
serviceConfig = defaultServiceConfig // {
+
KillSignal = "SIGINT";
+
ExecStart = ''
+
${pkg}/bin/nipapd \
+
--auto-install-db \
+
--auto-upgrade-db \
+
--foreground \
+
--no-pid-file
+
'';
+
};
+
};
+
})
+
(lib.mkIf cfg.nipap-www.enable {
+
assertions = [
+
{
+
assertion =
+
cfg.nipap-www.xmlrpcURIFile == null -> cfg.settings.auth.default_backend == defaultAuthBackend;
+
message = "If no XMLRPC URI secret file is specified, then the default auth backend must be in use to automatically generate credentials.";
+
}
+
];
+
+
# Ensure that _something_ exists in the [www] group.
+
services.nipap.settings.www = lib.mkDefault { };
+
+
systemd.services.nipap-www =
+
let
+
pkg = cfg.nipap-www.package;
+
in
+
{
+
description = "Neat IP Address Planner web server";
+
after = [
+
"network.target"
+
"systemd-tmpfiles-setup.service"
+
] ++ lib.optional cfg.nipapd.enable "nipapd.service";
+
wantedBy = [ "multi-user.target" ];
+
environment = {
+
PYTHONPATH = pkg.pythonPath;
+
};
+
serviceConfig = defaultServiceConfig;
+
script =
+
let
+
bind =
+
if cfg.nipap-www.unixSocket != null then
+
"unix:${cfg.nipap-www.unixSocket}"
+
else
+
"${escapedHost cfg.nipap-www.host}:${toString cfg.nipap-www.port}";
+
generateXMLRPC = cfg.nipap-www.xmlrpcURIFile == null;
+
xmlrpcURIFile = if generateXMLRPC then "${dataDir}/www_xmlrpc_uri" else cfg.nipap-www.xmlrpcURIFile;
+
in
+
''
+
test -f "${dataDir}/www_secret" || {
+
umask 0077
+
${pkg.python}/bin/python -c "import secrets; print(secrets.token_hex())" > "${dataDir}/www_secret"
+
}
+
export FLASK_SECRET_KEY="$(cat "${dataDir}/www_secret")"
+
+
# Ensure that we have an XMLRPC URI.
+
${
+
if generateXMLRPC then
+
''
+
test -f "${dataDir}/www_xmlrpc_uri" || {
+
umask 0077
+
www_password="$(${pkg.python}/bin/python -c "import secrets; print(secrets.token_hex())")"
+
${cfg.nipapd.package}/bin/nipap-passwd add --username nipap-www --password "''${www_password}" --name "User account for the web UI" --trusted
+
+
echo "http://nipap-www@${defaultAuthBackend}:''${www_password}@${escapedHost cfg.settings.nipapd.listen}:${toString cfg.settings.nipapd.port}" > "${xmlrpcURIFile}"
+
}
+
''
+
else
+
""
+
}
+
export FLASK_XMLRPC_URI="$(cat "${xmlrpcURIFile}")"
+
+
exec "${pkg.gunicorn}/bin/gunicorn" \
+
--preload --workers ${toString cfg.nipap-www.workers} \
+
--pythonpath "${pkg}/${pkg.python.sitePackages}" \
+
--bind ${bind} --umask ${cfg.nipap-www.umask} \
+
"nipapwww:create_app()"
+
'';
+
};
+
})
+
]
+
);
+
+
meta.maintainers = with lib.maintainers; [ lukegb ];
+
}
+1
nixos/tests/all-tests.nix
···
nginx-unix-socket = runTest ./nginx-unix-socket.nix;
nginx-variants = import ./nginx-variants.nix { inherit pkgs runTest; };
nifi = runTestOn [ "x86_64-linux" ] ./web-apps/nifi.nix;
+
nipap = runTest ./web-apps/nipap.nix;
nitter = runTest ./nitter.nix;
nix-config = runTest ./nix-config.nix;
nix-ld = runTest ./nix-ld.nix;
+69
nixos/tests/web-apps/nipap.nix
···
+
{ pkgs, lib, ... }:
+
+
let
+
nipapRc = pkgs.writeText "nipaprc" ''
+
[global]
+
hostname = [::1]
+
port = 1337
+
username = nixostest
+
password = nIx0st3st
+
default_vrf_rt = -
+
default_list_vrf_rt = all
+
'';
+
in
+
{
+
name = "lukegb";
+
meta.maintainers = [ lib.maintainers.lukegb ];
+
+
nodes.main =
+
{ ... }:
+
{
+
services.nipap = {
+
enable = true;
+
};
+
+
environment.systemPackages = [
+
pkgs.nipap-cli
+
];
+
};
+
+
testScript = ''
+
main.wait_for_unit("nipapd.service")
+
main.wait_for_unit("nipap-www.service")
+
+
# Make sure the web UI is up.
+
main.wait_for_open_port(21337)
+
main.succeed("curl -fvvv -Ls http://localhost:21337/ | grep 'NIPAP'")
+
+
# Check that none of the files we created in /var/lib/nipap are readable.
+
out = main.succeed("ls -l /var/lib/nipap")
+
bad_perms = False
+
for ln in out.split("\n"):
+
ln = ln.strip()
+
if not ln or ln.startswith('total '):
+
continue
+
if not ln.startswith('-rw------- '):
+
print(f"Bad file permissions: {ln}")
+
bad_perms = True
+
if bad_perms:
+
t.fail("One or more files were overly permissive.")
+
+
# Check we created a web-frontend user.
+
main.succeed("nipap-passwd list | grep nipap-www")
+
+
# Create a test user
+
main.succeed("nipap-passwd add -u nixostest -p nIx0st3st -n 'NixOS Test User'")
+
+
# Try to log in with it on the web frontend
+
main.succeed("curl -fvvv -Ls -b \"\" -d username=nixostest -d password=nIx0st3st http://localhost:21337/auth/login | grep 'PrefixListController'")
+
+
# Try to log in with it using the CLI
+
main.copy_from_host("${nipapRc}", "/root/.nipaprc")
+
main.succeed("chmod u=rw,go= /root/.nipaprc")
+
main.succeed("nipap address add prefix 192.0.2.0/24 type assignment description RFC1166")
+
main.succeed("nipap address add prefix 192.0.2.1/32 type host description 'test host'")
+
main.succeed("nipap address add prefix 2001:db8::/32 type reservation description RFC3849")
+
main.succeed("nipap address add prefix 2001:db8:f00f::/48 type assignment description 'eye pee vee six'")
+
main.succeed("nipap address add prefix 2001:db8:f00f:face:dead:beef:cafe:feed/128 type host description 'test host 2'")
+
'';
+
}
+56
pkgs/by-name/ni/nipap-cli/package.nix
···
+
{
+
lib,
+
python312Packages,
+
nixosTests,
+
}:
+
+
let
+
python3Packages = python312Packages;
+
in
+
python3Packages.buildPythonApplication rec {
+
pname = "nipap-cli";
+
inherit (python3Packages.nipap) version src;
+
pyproject = true;
+
+
sourceRoot = "${src.name}/nipap-cli";
+
+
postPatch = ''
+
substituteInPlace pyproject.toml \
+
--replace-fail 'docutils==0.20.1' 'docutils'
+
'';
+
+
build-system = with python3Packages; [
+
setuptools
+
docutils
+
];
+
+
dependencies = with python3Packages; [
+
ipy
+
pynipap
+
];
+
+
checkInputs = with python3Packages; [
+
pythonImportsCheckHook
+
];
+
pythonImportsCheck = [
+
"nipap_cli.nipap_cli"
+
];
+
+
passthru.tests.nixos = nixosTests.nipap;
+
+
meta = {
+
description = "Neat IP Address Planner CLI";
+
longDescription = ''
+
NIPAP is the best open source IPAM in the known universe,
+
challenging classical IP address management (IPAM) systems in many areas.
+
'';
+
homepage = "https://github.com/SpriteLink/NIPAP";
+
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
+
license = lib.licenses.mit;
+
maintainers = with lib.maintainers; [
+
lukegb
+
];
+
platforms = lib.platforms.all;
+
mainProgram = "nipap";
+
};
+
}
+53
pkgs/by-name/ni/nipap-www/package.nix
···
+
{
+
lib,
+
python3Packages,
+
nixosTests,
+
}:
+
+
python3Packages.buildPythonApplication rec {
+
pname = "nipap-www";
+
inherit (python3Packages.nipap) version src;
+
pyproject = true;
+
+
sourceRoot = "${src.name}/nipap-www";
+
+
postPatch = ''
+
# Load Flask config additionally from FLASK_ environment variables.
+
# This makes providing secrets easier.
+
sed -i nipapwww/__init__.py \
+
-e '/^\s*app =/a\ app.config.from_prefixed_env()'
+
'';
+
+
pythonRelaxDeps = true; # deps are tightly specified
+
+
build-system = with python3Packages; [
+
setuptools
+
];
+
+
dependencies = with python3Packages; [
+
flask
+
nipap
+
pynipap
+
];
+
+
passthru = {
+
inherit (python3Packages) gunicorn python;
+
pythonPath = python3Packages.makePythonPath dependencies;
+
tests.nixos = nixosTests.nipap;
+
};
+
+
meta = {
+
description = "Neat IP Address Planner CLI, web UI";
+
longDescription = ''
+
NIPAP is the best open source IPAM in the known universe,
+
challenging classical IP address management (IPAM) systems in many areas.
+
'';
+
homepage = "https://github.com/SpriteLink/NIPAP";
+
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
+
license = lib.licenses.mit;
+
maintainers = with lib.maintainers; [
+
lukegb
+
];
+
platforms = lib.platforms.all;
+
};
+
}
+5
pkgs/by-name/ni/nipap/package.nix
···
+
{
+
python3Packages,
+
}:
+
+
python3Packages.toPythonApplication python3Packages.nipap
+50
pkgs/development/python-modules/flask-xml-rpc-re/default.nix
···
+
{
+
lib,
+
buildPythonPackage,
+
fetchFromGitHub,
+
setuptools,
+
flask,
+
nose2,
+
}:
+
+
buildPythonPackage rec {
+
pname = "flask-xml-rpc-re";
+
version = "0.2.0";
+
+
src = fetchFromGitHub {
+
owner = "Croydon";
+
repo = "flask-xml-rpc-reloaded";
+
tag = version;
+
hash = "sha256-S+9Ur22ExgVjKMOKG19cBz2aCVdEyOoS7uoz17CDzd8=";
+
};
+
+
build-system = [
+
setuptools
+
];
+
+
dependencies = [
+
flask
+
];
+
+
nativeCheckInputs = [
+
nose2
+
];
+
+
installCheckPhase = ''
+
runHook preInstallCheck
+
nose2 -v
+
runHook postInstallCheck
+
'';
+
+
pythonImportsCheck = [ "flask_xmlrpcre" ];
+
+
meta = {
+
description = "Let your Flask apps provide XML-RPC APIs";
+
license = lib.licenses.mit;
+
maintainers = with lib.maintainers; [
+
lukegb
+
];
+
homepage = "https://github.com/Croydon/flask-xml-rpc-reloaded";
+
changelog = "https://github.com/Croydon/flask-xml-rpc-reloaded/releases/tag/${version}";
+
};
+
}
+100
pkgs/development/python-modules/nipap/default.nix
···
+
{
+
lib,
+
buildPythonPackage,
+
fetchFromGitHub,
+
+
# build deps
+
setuptools,
+
docutils,
+
+
# dependencies
+
zipp,
+
importlib-metadata,
+
flask,
+
flask-compress,
+
flask-xml-rpc-re,
+
flask-restx,
+
requests,
+
ipy,
+
# indirect deps omitted: jinja2/markupsafe/werkzeug,
+
parsedatetime,
+
psutil,
+
psycopg2,
+
pyparsing,
+
python-dateutil,
+
pytz,
+
pyjwt,
+
tornado,
+
+
# optional deps
+
## ldap
+
python-ldap,
+
}:
+
+
buildPythonPackage rec {
+
pname = "nipap";
+
version = "0.32.7";
+
pyproject = true;
+
+
src = fetchFromGitHub {
+
owner = "SpriteLink";
+
repo = "NIPAP";
+
tag = "v${version}";
+
hash = "sha256-FnCHW/yEhWtx+2fU+G6vxz50lWC7WL3cYKYOQzmH8zs=";
+
};
+
+
sourceRoot = "${src.name}/nipap";
+
+
pythonRelaxDeps = true; # deps are tightly specified by upstream
+
+
postPatch = ''
+
substituteInPlace pyproject.toml \
+
--replace-fail 'docutils==0.20.1' 'docutils'
+
'';
+
+
build-system = [
+
setuptools
+
docutils
+
];
+
+
dependencies = [
+
zipp
+
importlib-metadata
+
flask
+
flask-compress
+
flask-xml-rpc-re
+
flask-restx
+
requests
+
ipy
+
# indirect deps omitted: jinja2/markupsafe/werkzeug
+
parsedatetime
+
psutil
+
psycopg2
+
pyparsing
+
python-dateutil
+
pytz
+
pyjwt
+
tornado
+
];
+
+
optional-dependencies = {
+
ldap = [ python-ldap ];
+
};
+
+
doCheck = false; # tests require nose, /etc/nipap/nipap.conf and a running nipapd
+
+
meta = {
+
description = "Neat IP Address Planner";
+
longDescription = ''
+
NIPAP is the best open source IPAM in the known universe,
+
challenging classical IP address management (IPAM) systems in many areas.
+
'';
+
homepage = "https://github.com/SpriteLink/NIPAP";
+
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
+
license = lib.licenses.mit;
+
maintainers = with lib.maintainers; [
+
lukegb
+
];
+
platforms = lib.platforms.all;
+
};
+
}
+38
pkgs/development/python-modules/pynipap/default.nix
···
+
{
+
lib,
+
buildPythonPackage,
+
nipap,
+
+
# build deps
+
setuptools,
+
}:
+
+
buildPythonPackage rec {
+
pname = "pynipap";
+
pyproject = true;
+
+
inherit (nipap) version src;
+
+
sourceRoot = "${src.name}/pynipap";
+
+
build-system = [
+
setuptools
+
];
+
+
doCheck = false; # tests require nose, /etc/nipap/nipap.conf and a running nipapd
+
+
meta = {
+
description = "Python client library for Neat IP Address Planner";
+
longDescription = ''
+
NIPAP is the best open source IPAM in the known universe,
+
challenging classical IP address management (IPAM) systems in many areas.
+
'';
+
homepage = "https://github.com/SpriteLink/NIPAP";
+
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
+
license = lib.licenses.mit;
+
maintainers = with lib.maintainers; [
+
lukegb
+
];
+
platforms = lib.platforms.all;
+
};
+
}
+34
pkgs/servers/sql/postgresql/ext/ip4r.nix
···
+
{
+
fetchFromGitHub,
+
lib,
+
postgresql,
+
postgresqlBuildExtension,
+
postgresqlTestExtension,
+
}:
+
+
postgresqlBuildExtension (finalAttrs: {
+
pname = "ip4r";
+
version = "2.4.2";
+
+
src = fetchFromGitHub {
+
owner = "RhodiumToad";
+
repo = "ip4r";
+
tag = "${finalAttrs.version}";
+
hash = "sha256-3chAD4f4A6VlXVSI0kfC/ANcnFy4vBp4FZpT6QRAueQ=";
+
};
+
+
passthru.tests = {
+
extension = postgresqlTestExtension {
+
inherit (finalAttrs) finalPackage;
+
sql = "CREATE EXTENSION ip4r;";
+
};
+
};
+
+
meta = {
+
description = "IPv4/v6 and IPv4/v6 range index type for PostgreSQL";
+
homepage = "https://github.com/RhodiumToad/ip4r";
+
license = lib.licenses.postgresql;
+
maintainers = with lib.maintainers; [ lukegb ];
+
inherit (postgresql.meta) platforms;
+
};
+
})
+6
pkgs/top-level/python-packages.nix
···
flask-wtf = callPackage ../development/python-modules/flask-wtf { };
+
flask-xml-rpc-re = callPackage ../development/python-modules/flask-xml-rpc-re { };
+
flatbencode = callPackage ../development/python-modules/flatbencode { };
flatbuffers = callPackage ../development/python-modules/flatbuffers { inherit (pkgs) flatbuffers; };
···
ninja = callPackage ../development/python-modules/ninja { inherit (pkgs) ninja; };
+
nipap = callPackage ../development/python-modules/nipap { };
+
nipreps-versions = callPackage ../development/python-modules/nipreps-versions { };
nipy = callPackage ../development/python-modules/nipy { };
···
pyngrok = callPackage ../development/python-modules/pyngrok { };
pynina = callPackage ../development/python-modules/pynina { };
+
+
pynipap = callPackage ../development/python-modules/pynipap { };
pynisher = callPackage ../development/python-modules/pynisher { };