From bc4b08acbe7f40ecdf0cabb90d8833092e6c233d Mon Sep 17 00:00:00 2001 From: Minijackson Date: Tue, 20 Dec 2022 09:58:54 +0100 Subject: [PATCH 01/13] netbox: 3.3.9 -> 3.4.1 --- pkgs/servers/web-apps/netbox/default.nix | 12 +++-------- .../web-apps/netbox/graphql-3_2_0.patch | 21 ------------------- 2 files changed, 3 insertions(+), 30 deletions(-) delete mode 100644 pkgs/servers/web-apps/netbox/graphql-3_2_0.patch diff --git a/pkgs/servers/web-apps/netbox/default.nix b/pkgs/servers/web-apps/netbox/default.nix index aeeb57fa3792..76ce3fbe47e7 100644 --- a/pkgs/servers/web-apps/netbox/default.nix +++ b/pkgs/servers/web-apps/netbox/default.nix @@ -18,7 +18,7 @@ let in py.pkgs.buildPythonApplication rec { pname = "netbox"; - version = "3.3.9"; + version = "3.4.1"; format = "other"; @@ -26,18 +26,12 @@ py.pkgs.buildPythonApplication rec { owner = "netbox-community"; repo = pname; rev = "refs/tags/v${version}"; - sha256 = "sha256-KhnxD5pjlEIgISl4RMbhLCDwgUDfGFRi88ZcP1ndMhI="; + sha256 = "sha256-qwgheyhekbYdwSKPR9h/iJprsXFbdiaWmfXqG/HDspo="; }; patches = [ # Allow setting the STATIC_ROOT from within the configuration and setting a custom redis URL ./config.patch - ./graphql-3_2_0.patch - # fix compatibility ith django 4.1 - (fetchpatch { - url = "https://github.com/netbox-community/netbox/pull/10341/commits/ce6bf9e5c1bc08edc80f6ea1e55cf1318ae6e14b.patch"; - sha256 = "sha256-aCPQp6k7Zwga29euASAd+f13hIcZnIUu3RPAzNPqgxc="; - }) ]; propagatedBuildInputs = with py.pkgs; [ @@ -111,6 +105,6 @@ py.pkgs.buildPythonApplication rec { homepage = "https://github.com/netbox-community/netbox"; description = "IP address management (IPAM) and data center infrastructure management (DCIM) tool"; license = licenses.asl20; - maintainers = with maintainers; [ n0emis raitobezarius ]; + maintainers = with maintainers; [ minijackson n0emis raitobezarius ]; }; } diff --git a/pkgs/servers/web-apps/netbox/graphql-3_2_0.patch b/pkgs/servers/web-apps/netbox/graphql-3_2_0.patch deleted file mode 100644 index 1e97b7d85ce0..000000000000 --- a/pkgs/servers/web-apps/netbox/graphql-3_2_0.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/netbox/netbox/graphql/scalars.py b/netbox/netbox/graphql/scalars.py -index 7d14189dd..0a18e79d2 100644 ---- a/netbox/netbox/graphql/scalars.py -+++ b/netbox/netbox/graphql/scalars.py -@@ -1,6 +1,6 @@ - from graphene import Scalar - from graphql.language import ast --from graphql.type.scalars import MAX_INT, MIN_INT -+from graphql.type.scalars import GRAPHQL_MAX_INT, GRAPHQL_MIN_INT - - - class BigInt(Scalar): -@@ -10,7 +10,7 @@ class BigInt(Scalar): - @staticmethod - def to_float(value): - num = int(value) -- if num > MAX_INT or num < MIN_INT: -+ if num > GRAPHQL_MAX_INT or num < GRAPHQL_MIN_INT: - return float(num) - return num - From 2cb6dc90acfa16a37c055f6786de06a031f12326 Mon Sep 17 00:00:00 2001 From: Minijackson Date: Tue, 20 Dec 2022 10:18:33 +0100 Subject: [PATCH 02/13] formats.pythonVars: init --- pkgs/pkgs-lib/formats.nix | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/pkgs/pkgs-lib/formats.nix b/pkgs/pkgs-lib/formats.nix index 13aada3681f7..3a47d3dc849c 100644 --- a/pkgs/pkgs-lib/formats.nix +++ b/pkgs/pkgs-lib/formats.nix @@ -417,4 +417,39 @@ rec { ''; }; + # Outputs a succession of Python variable assignments + # Useful for many Django-based services + pythonVars = {}: { + type = with lib.types; let + valueType = nullOr(oneOf [ + bool + float + int + path + str + (attrsOf valueType) + (listOf valueType) + ]) // { + description = "Python value"; + }; + in attrsOf valueType; + generate = name: value: pkgs.callPackage ({ runCommand, python3, black }: runCommand name { + nativeBuildInputs = [ python3 black ]; + value = builtins.toJSON value; + pythonGen = '' + import json + import os + + with open(os.environ["valuePath"], "r") as f: + for key, value in json.load(f).items(): + print(f"{key} = {repr(value)}") + ''; + passAsFile = [ "value" "pythonGen" ]; + } '' + cat "$valuePath" + python3 "$pythonGenPath" > $out + black $out + '') {}; + }; + } From 36a550c6f9fd5b7a2300c3b9d4d1b698858fe18d Mon Sep 17 00:00:00 2001 From: Minijackson Date: Tue, 20 Dec 2022 10:19:42 +0100 Subject: [PATCH 03/13] nixos/netbox: RFC42-style options - allows specifying allowed hosts - setup sane default for logging --- nixos/modules/services/web-apps/netbox.nix | 149 ++++++++++++++++----- 1 file changed, 112 insertions(+), 37 deletions(-) diff --git a/nixos/modules/services/web-apps/netbox.nix b/nixos/modules/services/web-apps/netbox.nix index e028f16004ef..661a55fd5e7e 100644 --- a/nixos/modules/services/web-apps/netbox.nix +++ b/nixos/modules/services/web-apps/netbox.nix @@ -4,44 +4,16 @@ with lib; let cfg = config.services.netbox; + pythonFmt = pkgs.formats.pythonVars {}; staticDir = cfg.dataDir + "/static"; - configFile = pkgs.writeTextFile { - name = "configuration.py"; - text = '' - STATIC_ROOT = '${staticDir}' - MEDIA_ROOT = '${cfg.dataDir}/media' - REPORTS_ROOT = '${cfg.dataDir}/reports' - SCRIPTS_ROOT = '${cfg.dataDir}/scripts' - ALLOWED_HOSTS = ['*'] - DATABASE = { - 'NAME': 'netbox', - 'USER': 'netbox', - 'HOST': '/run/postgresql', - } - - # Redis database settings. Redis is used for caching and for queuing background tasks such as webhook events. A separate - # configuration exists for each. Full connection details are required in both sections, and it is strongly recommended - # to use two separate database IDs. - REDIS = { - 'tasks': { - 'URL': 'unix://${config.services.redis.servers.netbox.unixSocket}?db=0', - 'SSL': False, - }, - 'caching': { - 'URL': 'unix://${config.services.redis.servers.netbox.unixSocket}?db=1', - 'SSL': False, - } - } - - with open("${cfg.secretKeyFile}", "r") as file: - SECRET_KEY = file.readline() - - ${optionalString cfg.enableLdap "REMOTE_AUTH_BACKEND = 'netbox.authentication.LDAPBackend'"} - - ${cfg.extraConfig} - ''; + settingsFile = pythonFmt.generate "netbox-settings.py" cfg.settings; + extraConfigFile = pkgs.writeTextFile { + name = "netbox-extraConfig.py"; + text = cfg.extraConfig; }; + configFile = pkgs.concatText "configuration.py" [ settingsFile extraConfigFile ]; + pkg = (pkgs.netbox.overrideAttrs (old: { installPhase = old.installPhase + '' ln -s ${configFile} $out/opt/netbox/netbox/netbox/configuration.py @@ -70,6 +42,30 @@ in { ''; }; + settings = lib.mkOption { + description = lib.mdDoc '' + Configuration options to set in `configuration.py`. + See the [documentation](https://docs.netbox.dev/en/stable/configuration/) for more possible options. + ''; + + default = { }; + + type = lib.types.submodule { + freeformType = pythonFmt.type; + + options = { + ALLOWED_HOSTS = lib.mkOption { + type = with lib.types; listOf str; + default = ["*"]; + description = lib.mdDoc '' + A list of valid fully-qualified domain names (FQDNs) and/or IP + addresses that can be used to reach the NetBox service. + ''; + }; + }; + }; + }; + listenAddress = mkOption { type = types.str; default = "[::1]"; @@ -117,7 +113,7 @@ in { default = ""; description = lib.mdDoc '' Additional lines of configuration appended to the `configuration.py`. - See the [documentation](https://netbox.readthedocs.io/en/stable/configuration/optional-settings/) for more possible options. + See the [documentation](https://docs.netbox.dev/en/stable/configuration/) for more possible options. ''; }; @@ -138,11 +134,90 @@ in { Path to the Configuration-File for LDAP-Authentication, will be loaded as `ldap_config.py`. See the [documentation](https://netbox.readthedocs.io/en/stable/installation/6-ldap/#configuration) for possible options. ''; + example = '' + import ldap + from django_auth_ldap.config import LDAPSearch, PosixGroupType + + AUTH_LDAP_SERVER_URI = "ldaps://ldap.example.com/" + + AUTH_LDAP_USER_SEARCH = LDAPSearch( + "ou=accounts,ou=posix,dc=example,dc=com", + ldap.SCOPE_SUBTREE, + "(uid=%(user)s)", + ) + + AUTH_LDAP_GROUP_SEARCH = LDAPSearch( + "ou=groups,ou=posix,dc=example,dc=com", + ldap.SCOPE_SUBTREE, + "(objectClass=posixGroup)", + ) + AUTH_LDAP_GROUP_TYPE = PosixGroupType() + + # Mirror LDAP group assignments. + AUTH_LDAP_MIRROR_GROUPS = True + + # For more granular permissions, we can map LDAP groups to Django groups. + AUTH_LDAP_FIND_GROUP_PERMS = True + ''; }; }; config = mkIf cfg.enable { - services.netbox.plugins = mkIf cfg.enableLdap (ps: [ ps.django-auth-ldap ]); + services.netbox = { + plugins = mkIf cfg.enableLdap (ps: [ ps.django-auth-ldap ]); + settings = { + STATIC_ROOT = staticDir; + MEDIA_ROOT = "${cfg.dataDir}/media"; + REPORTS_ROOT = "${cfg.dataDir}/reports"; + SCRIPTS_ROOT = "${cfg.dataDir}/scripts"; + + DATABASE = { + NAME = "netbox"; + USER = "netbox"; + HOST = "/run/postgresql"; + }; + + # Redis database settings. Redis is used for caching and for queuing + # background tasks such as webhook events. A separate configuration + # exists for each. Full connection details are required in both + # sections, and it is strongly recommended to use two separate database + # IDs. + REDIS = { + tasks = { + URL = "unix://${config.services.redis.servers.netbox.unixSocket}?db=0"; + SSL = false; + }; + caching = { + URL = "unix://${config.services.redis.servers.netbox.unixSocket}?db=1"; + SSL = false; + }; + }; + + REMOTE_AUTH_BACKEND = lib.mkIf cfg.enableLdap "netbox.authentication.LDAPBackend"; + + LOGGING = lib.mkDefault { + version = 1; + + formatters.precise.format = "[%(levelname)s@%(name)s] %(message)s"; + + handlers.console = { + class = "logging.StreamHandler"; + formatter = "precise"; + }; + + # log to console/systemd instead of file + root = { + level = "INFO"; + handlers = [ "console" ]; + }; + }; + }; + + extraConfig = '' + with open("${cfg.secretKeyFile}", "r") as file: + SECRET_KEY = file.readline() + ''; + }; services.redis.servers.netbox.enable = true; From 949763988a53fa6155087c436eaf295495b1105a Mon Sep 17 00:00:00 2001 From: Minijackson Date: Tue, 20 Dec 2022 10:20:48 +0100 Subject: [PATCH 04/13] nixos/tests/netbox: test through proxy, REST API, GraphQL, LDAP integration --- nixos/tests/web-apps/netbox.nix | 296 +++++++++++++++++++++++++++++++- 1 file changed, 291 insertions(+), 5 deletions(-) diff --git a/nixos/tests/web-apps/netbox.nix b/nixos/tests/web-apps/netbox.nix index 35decdd49e87..9a828dde3822 100644 --- a/nixos/tests/web-apps/netbox.nix +++ b/nixos/tests/web-apps/netbox.nix @@ -1,21 +1,145 @@ -import ../make-test-python.nix ({ lib, pkgs, ... }: { +let + ldapDomain = "example.org"; + ldapSuffix = "dc=example,dc=org"; + + ldapRootUser = "admin"; + ldapRootPassword = "foobar"; + + testUser = "alice"; + testPassword = "verySecure"; + testGroup = "netbox-users"; +in import ../make-test-python.nix ({ lib, pkgs, ... }: { name = "netbox"; meta = with lib.maintainers; { - maintainers = [ n0emis ]; + maintainers = [ minijackson n0emis ]; }; - nodes.machine = { ... }: { + nodes.machine = { config, ... }: { services.netbox = { enable = true; secretKeyFile = pkgs.writeText "secret" '' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ''; + + enableLdap = true; + ldapConfigPath = pkgs.writeText "ldap_config.py" '' + import ldap + from django_auth_ldap.config import LDAPSearch, PosixGroupType + + AUTH_LDAP_SERVER_URI = "ldap://localhost/" + + AUTH_LDAP_USER_SEARCH = LDAPSearch( + "ou=accounts,ou=posix,${ldapSuffix}", + ldap.SCOPE_SUBTREE, + "(uid=%(user)s)", + ) + + AUTH_LDAP_GROUP_SEARCH = LDAPSearch( + "ou=groups,ou=posix,${ldapSuffix}", + ldap.SCOPE_SUBTREE, + "(objectClass=posixGroup)", + ) + AUTH_LDAP_GROUP_TYPE = PosixGroupType() + + # Mirror LDAP group assignments. + AUTH_LDAP_MIRROR_GROUPS = True + + # For more granular permissions, we can map LDAP groups to Django groups. + AUTH_LDAP_FIND_GROUP_PERMS = True + ''; }; + + services.nginx = { + enable = true; + + recommendedProxySettings = true; + + virtualHosts.netbox = { + default = true; + locations."/".proxyPass = "http://localhost:${toString config.services.netbox.port}"; + locations."/static/".alias = "/var/lib/netbox/static/"; + }; + }; + + # Adapted from the sssd-ldap NixOS test + services.openldap = { + enable = true; + settings = { + children = { + "cn=schema".includes = [ + "${pkgs.openldap}/etc/schema/core.ldif" + "${pkgs.openldap}/etc/schema/cosine.ldif" + "${pkgs.openldap}/etc/schema/inetorgperson.ldif" + "${pkgs.openldap}/etc/schema/nis.ldif" + ]; + "olcDatabase={1}mdb" = { + attrs = { + objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; + olcDatabase = "{1}mdb"; + olcDbDirectory = "/var/lib/openldap/db"; + olcSuffix = ldapSuffix; + olcRootDN = "cn=${ldapRootUser},${ldapSuffix}"; + olcRootPW = ldapRootPassword; + }; + }; + }; + }; + declarativeContents = { + ${ldapSuffix} = '' + dn: ${ldapSuffix} + objectClass: top + objectClass: dcObject + objectClass: organization + o: ${ldapDomain} + + dn: ou=posix,${ldapSuffix} + objectClass: top + objectClass: organizationalUnit + + dn: ou=accounts,ou=posix,${ldapSuffix} + objectClass: top + objectClass: organizationalUnit + + dn: uid=${testUser},ou=accounts,ou=posix,${ldapSuffix} + objectClass: person + objectClass: posixAccount + userPassword: ${testPassword} + homeDirectory: /home/${testUser} + uidNumber: 1234 + gidNumber: 1234 + cn: "" + sn: "" + + dn: ou=groups,ou=posix,${ldapSuffix} + objectClass: top + objectClass: organizationalUnit + + dn: cn=${testGroup},ou=groups,ou=posix,${ldapSuffix} + objectClass: posixGroup + gidNumber: 2345 + memberUid: ${testUser} + ''; + }; + }; + + users.users.nginx.extraGroups = [ "netbox" ]; + + networking.firewall.allowedTCPPorts = [ 80 ]; }; - testScript = '' - machine.start() + testScript = let + changePassword = pkgs.writeText "change-password.py" '' + from django.contrib.auth.models import User + u = User.objects.get(username='netbox') + u.set_password('netbox') + u.save() + ''; + in '' + from typing import Any, Dict + import json + + start_all() machine.wait_for_unit("netbox.target") machine.wait_until_succeeds("journalctl --since -1m --unit netbox --grep Listening") @@ -26,5 +150,167 @@ import ../make-test-python.nix ({ lib, pkgs, ... }: { with subtest("Staticfiles are generated"): machine.succeed("test -e /var/lib/netbox/static/netbox.js") + + with subtest("Superuser can be created"): + machine.succeed( + "netbox-manage createsuperuser --noinput --username netbox --email netbox@example.com" + ) + # Django doesn't have a "clean" way of inputting the password from the command line + machine.succeed("cat '${changePassword}' | netbox-manage shell") + + machine.wait_for_unit("network.target") + + with subtest("Home screen loads from nginx"): + machine.succeed( + "curl -sSfL http://localhost | grep 'Home | NetBox'" + ) + + with subtest("Staticfiles can be fetched"): + machine.succeed("curl -sSfL http://localhost/static/netbox.js") + machine.succeed("curl -sSfL http://localhost/static/docs/") + + with subtest("Can interact with API"): + json.loads( + machine.succeed("curl -sSfL -H 'Accept: application/json' 'http://localhost/api/'") + ) + + def login(username: str, password: str): + encoded_data = json.dumps({"username": username, "password": password}) + uri = "/users/tokens/provision/" + result = json.loads( + machine.succeed( + "curl -sSfL " + "-X POST " + "-H 'Accept: application/json' " + "-H 'Content-Type: application/json' " + f"'http://localhost/api{uri}' " + f"--data '{encoded_data}'" + ) + ) + return result["key"] + + with subtest("Can login"): + auth_token = login("netbox", "netbox") + + def get(uri: str): + return json.loads( + machine.succeed( + "curl -sSfL " + "-H 'Accept: application/json' " + f"-H 'Authorization: Token {auth_token}' " + f"'http://localhost/api{uri}'" + ) + ) + + def delete(uri: str): + return machine.succeed( + "curl -sSfL " + f"-X DELETE " + "-H 'Accept: application/json' " + f"-H 'Authorization: Token {auth_token}' " + f"'http://localhost/api{uri}'" + ) + + + def data_request(uri: str, method: str, data: Dict[str, Any]): + encoded_data = json.dumps(data) + return json.loads( + machine.succeed( + "curl -sSfL " + f"-X {method} " + "-H 'Accept: application/json' " + "-H 'Content-Type: application/json' " + f"-H 'Authorization: Token {auth_token}' " + f"'http://localhost/api{uri}' " + f"--data '{encoded_data}'" + ) + ) + + def post(uri: str, data: Dict[str, Any]): + return data_request(uri, "POST", data) + + def patch(uri: str, data: Dict[str, Any]): + return data_request(uri, "PATCH", data) + + with subtest("Can create objects"): + result = post("/dcim/sites/", {"name": "Test site", "slug": "test-site"}) + site_id = result["id"] + + # Example from: + # http://netbox.extra.cea.fr/static/docs/integrations/rest-api/#creating-a-new-object + post("/ipam/prefixes/", {"prefix": "192.0.2.0/24", "site": site_id}) + + result = post( + "/dcim/manufacturers/", + {"name": "Test manufacturer", "slug": "test-manufacturer"} + ) + manufacturer_id = result["id"] + + # Had an issue with device-types before NetBox 3.4.0 + result = post( + "/dcim/device-types/", + { + "model": "Test device type", + "manufacturer": manufacturer_id, + "slug": "test-device-type", + }, + ) + device_type_id = result["id"] + + with subtest("Can list objects"): + result = get("/dcim/sites/") + + assert result["count"] == 1 + assert result["results"][0]["id"] == site_id + assert result["results"][0]["name"] == "Test site" + assert result["results"][0]["description"] == "" + + result = get("/dcim/device-types/") + assert result["count"] == 1 + assert result["results"][0]["id"] == device_type_id + assert result["results"][0]["model"] == "Test device type" + + with subtest("Can update objects"): + new_description = "Test site description" + patch(f"/dcim/sites/{site_id}/", {"description": new_description}) + result = get(f"/dcim/sites/{site_id}/") + assert result["description"] == new_description + + with subtest("Can delete objects"): + # Delete a device-type since no object depends on it + delete(f"/dcim/device-types/{device_type_id}/") + + result = get("/dcim/device-types/") + assert result["count"] == 0 + + with subtest("Can use the GraphQL API"): + encoded_data = json.dumps({ + "query": "query { prefix_list { prefix, site { id, description } } }", + }) + result = json.loads( + machine.succeed( + "curl -sSfL " + "-H 'Accept: application/json' " + "-H 'Content-Type: application/json' " + f"-H 'Authorization: Token {auth_token}' " + "'http://localhost/graphql/' " + f"--data '{encoded_data}'" + ) + ) + + assert len(result["data"]["prefix_list"]) == 1 + assert result["data"]["prefix_list"][0]["prefix"] == "192.0.2.0/24" + assert result["data"]["prefix_list"][0]["site"]["id"] == str(site_id) + assert result["data"]["prefix_list"][0]["site"]["description"] == new_description + + with subtest("Can login with LDAP"): + machine.wait_for_unit("openldap.service") + login("alice", "${testPassword}") + + with subtest("Can associate LDAP groups"): + result = get("/users/users/?username=${testUser}") + + assert result["count"] == 1 + assert any(group["name"] == "${testGroup}" for group in result["results"][0]["groups"]) ''; }) From 70e95c699a21cfa453441fbe939672d50a4926aa Mon Sep 17 00:00:00 2001 From: Minijackson Date: Tue, 20 Dec 2022 10:28:43 +0100 Subject: [PATCH 05/13] nixos/doc: add release notes for NetBox changes --- nixos/doc/manual/release-notes/rl-2305.section.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index cbc58c6bdc5f..12f5a30af4b5 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -231,6 +231,10 @@ In addition to numerous new and upgraded packages, this release has the followin - `services.openssh.ciphers` to `services.openssh.settings.Ciphers` - `services.openssh.gatewayPorts` to `services.openssh.settings.GatewayPorts` +- `netbox` was updated to 3.4. NixOS' `services.netbox.package` still defaults to 3.3 if `stateVersion` is earlier than 23.05. Please review upstream's [breaking changes](https://github.com/netbox-community/netbox/releases/tag/v3.4.0), and upgrade NetBox by changing `services.netbox.package`. Database migrations will be run automatically. + +- `services.netbox` now support RFC42-style options, through `services.netbox.settings`. + - `services.mastodon` gained a tootctl wrapped named `mastodon-tootctl` similar to `nextcloud-occ` which can be executed from any user and switches to the configured mastodon user with sudo and sources the environment variables. - DocBook option documentation, which has been deprecated since 22.11, will now cause a warning when documentation is built. Out-of-tree modules should migrate to using CommonMark documentation as outlined in [](#sec-option-declarations) to silence this warning. From 52f3031f23ee770c986307ce0577c7feb5812474 Mon Sep 17 00:00:00 2001 From: Minijackson Date: Wed, 4 Jan 2023 10:14:19 +0100 Subject: [PATCH 06/13] netbox: 3.4.1 -> 3.4.2 --- pkgs/servers/web-apps/netbox/config.patch | 12 ++++++------ pkgs/servers/web-apps/netbox/default.nix | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkgs/servers/web-apps/netbox/config.patch b/pkgs/servers/web-apps/netbox/config.patch index 1adc0b537a4e..c7025476b4c4 100644 --- a/pkgs/servers/web-apps/netbox/config.patch +++ b/pkgs/servers/web-apps/netbox/config.patch @@ -1,8 +1,8 @@ diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py -index d5a7bfaec..68754a8c5 100644 +index 0ad211416..c70710810 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py -@@ -222,6 +222,7 @@ TASKS_REDIS_PASSWORD = TASKS_REDIS.get('PASSWORD', '') +@@ -235,6 +235,7 @@ TASKS_REDIS_PASSWORD = TASKS_REDIS.get('PASSWORD', '') TASKS_REDIS_DATABASE = TASKS_REDIS.get('DATABASE', 0) TASKS_REDIS_SSL = TASKS_REDIS.get('SSL', False) TASKS_REDIS_SKIP_TLS_VERIFY = TASKS_REDIS.get('INSECURE_SKIP_TLS_VERIFY', False) @@ -10,7 +10,7 @@ index d5a7bfaec..68754a8c5 100644 # Caching if 'caching' not in REDIS: -@@ -236,11 +237,12 @@ CACHING_REDIS_SENTINELS = REDIS['caching'].get('SENTINELS', []) +@@ -251,11 +252,12 @@ CACHING_REDIS_SENTINELS = REDIS['caching'].get('SENTINELS', []) CACHING_REDIS_SENTINEL_SERVICE = REDIS['caching'].get('SENTINEL_SERVICE', 'default') CACHING_REDIS_PROTO = 'rediss' if REDIS['caching'].get('SSL', False) else 'redis' CACHING_REDIS_SKIP_TLS_VERIFY = REDIS['caching'].get('INSECURE_SKIP_TLS_VERIFY', False) @@ -19,12 +19,12 @@ index d5a7bfaec..68754a8c5 100644 CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', -- 'LOCATION': f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_HOST}:{CACHING_REDIS_PORT}/{CACHING_REDIS_DATABASE}', +- 'LOCATION': f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_USERNAME_HOST}:{CACHING_REDIS_PORT}/{CACHING_REDIS_DATABASE}', + 'LOCATION': CACHING_REDIS_URL, 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', 'PASSWORD': CACHING_REDIS_PASSWORD, -@@ -383,7 +385,7 @@ USE_X_FORWARDED_HOST = True +@@ -404,7 +406,7 @@ USE_X_FORWARDED_HOST = True X_FRAME_OPTIONS = 'SAMEORIGIN' # Static files (CSS, JavaScript, Images) @@ -33,7 +33,7 @@ index d5a7bfaec..68754a8c5 100644 STATIC_URL = f'/{BASE_PATH}static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'project-static', 'dist'), -@@ -562,6 +564,14 @@ if TASKS_REDIS_USING_SENTINEL: +@@ -634,6 +636,14 @@ if TASKS_REDIS_USING_SENTINEL: 'socket_connect_timeout': TASKS_REDIS_SENTINEL_TIMEOUT }, } diff --git a/pkgs/servers/web-apps/netbox/default.nix b/pkgs/servers/web-apps/netbox/default.nix index 76ce3fbe47e7..ddf98da4c8e0 100644 --- a/pkgs/servers/web-apps/netbox/default.nix +++ b/pkgs/servers/web-apps/netbox/default.nix @@ -18,7 +18,7 @@ let in py.pkgs.buildPythonApplication rec { pname = "netbox"; - version = "3.4.1"; + version = "3.4.2"; format = "other"; @@ -26,7 +26,7 @@ py.pkgs.buildPythonApplication rec { owner = "netbox-community"; repo = pname; rev = "refs/tags/v${version}"; - sha256 = "sha256-qwgheyhekbYdwSKPR9h/iJprsXFbdiaWmfXqG/HDspo="; + sha256 = "sha256-NMvNI5toPngVVUnxY6+U3Pdj9VGGGXTrB8YIcrQguZE="; }; patches = [ From eeb17fca1c436efbf05609f0050a868e737dca6b Mon Sep 17 00:00:00 2001 From: Minijackson Date: Sat, 21 Jan 2023 15:55:45 +0100 Subject: [PATCH 07/13] netbox: 3.4.2 -> 3.4.3 --- pkgs/servers/web-apps/netbox/config.patch | 14 +++++++------- pkgs/servers/web-apps/netbox/default.nix | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkgs/servers/web-apps/netbox/config.patch b/pkgs/servers/web-apps/netbox/config.patch index c7025476b4c4..a2e0b0b95a87 100644 --- a/pkgs/servers/web-apps/netbox/config.patch +++ b/pkgs/servers/web-apps/netbox/config.patch @@ -1,19 +1,19 @@ diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py -index 0ad211416..c70710810 100644 +index 2de06dd10..00406af48 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py -@@ -235,6 +235,7 @@ TASKS_REDIS_PASSWORD = TASKS_REDIS.get('PASSWORD', '') - TASKS_REDIS_DATABASE = TASKS_REDIS.get('DATABASE', 0) +@@ -236,6 +236,7 @@ TASKS_REDIS_DATABASE = TASKS_REDIS.get('DATABASE', 0) TASKS_REDIS_SSL = TASKS_REDIS.get('SSL', False) TASKS_REDIS_SKIP_TLS_VERIFY = TASKS_REDIS.get('INSECURE_SKIP_TLS_VERIFY', False) + TASKS_REDIS_CA_CERT_PATH = TASKS_REDIS.get('CA_CERT_PATH', False) +TASKS_REDIS_URL = TASKS_REDIS.get('URL') # Caching if 'caching' not in REDIS: -@@ -251,11 +252,12 @@ CACHING_REDIS_SENTINELS = REDIS['caching'].get('SENTINELS', []) - CACHING_REDIS_SENTINEL_SERVICE = REDIS['caching'].get('SENTINEL_SERVICE', 'default') +@@ -253,11 +254,12 @@ CACHING_REDIS_SENTINEL_SERVICE = REDIS['caching'].get('SENTINEL_SERVICE', 'defau CACHING_REDIS_PROTO = 'rediss' if REDIS['caching'].get('SSL', False) else 'redis' CACHING_REDIS_SKIP_TLS_VERIFY = REDIS['caching'].get('INSECURE_SKIP_TLS_VERIFY', False) + CACHING_REDIS_CA_CERT_PATH = REDIS['caching'].get('CA_CERT_PATH', False) +CACHING_REDIS_URL = REDIS['caching'].get('URL', f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_HOST}:{CACHING_REDIS_PORT}/{CACHING_REDIS_DATABASE}') CACHES = { @@ -24,7 +24,7 @@ index 0ad211416..c70710810 100644 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', 'PASSWORD': CACHING_REDIS_PASSWORD, -@@ -404,7 +406,7 @@ USE_X_FORWARDED_HOST = True +@@ -410,7 +412,7 @@ USE_X_FORWARDED_HOST = True X_FRAME_OPTIONS = 'SAMEORIGIN' # Static files (CSS, JavaScript, Images) @@ -33,7 +33,7 @@ index 0ad211416..c70710810 100644 STATIC_URL = f'/{BASE_PATH}static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'project-static', 'dist'), -@@ -634,6 +636,14 @@ if TASKS_REDIS_USING_SENTINEL: +@@ -640,6 +642,14 @@ if TASKS_REDIS_USING_SENTINEL: 'socket_connect_timeout': TASKS_REDIS_SENTINEL_TIMEOUT }, } diff --git a/pkgs/servers/web-apps/netbox/default.nix b/pkgs/servers/web-apps/netbox/default.nix index ddf98da4c8e0..a685dba30c6e 100644 --- a/pkgs/servers/web-apps/netbox/default.nix +++ b/pkgs/servers/web-apps/netbox/default.nix @@ -18,7 +18,7 @@ let in py.pkgs.buildPythonApplication rec { pname = "netbox"; - version = "3.4.2"; + version = "3.4.3"; format = "other"; @@ -26,7 +26,7 @@ py.pkgs.buildPythonApplication rec { owner = "netbox-community"; repo = pname; rev = "refs/tags/v${version}"; - sha256 = "sha256-NMvNI5toPngVVUnxY6+U3Pdj9VGGGXTrB8YIcrQguZE="; + sha256 = "sha256-M/CbnlnRaWuwcJJofY5mPpVTl9zYrApsXqV9hilNyvw="; }; patches = [ From 8dbfb9e263b80ac3ca83896a2305a0e5f82ece5c Mon Sep 17 00:00:00 2001 From: Minijackson Date: Sun, 12 Mar 2023 16:15:32 +0100 Subject: [PATCH 08/13] netbox: 3.4.3 -> 3.4.5 --- pkgs/servers/web-apps/netbox/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/servers/web-apps/netbox/default.nix b/pkgs/servers/web-apps/netbox/default.nix index a685dba30c6e..f0fe142a140f 100644 --- a/pkgs/servers/web-apps/netbox/default.nix +++ b/pkgs/servers/web-apps/netbox/default.nix @@ -18,7 +18,7 @@ let in py.pkgs.buildPythonApplication rec { pname = "netbox"; - version = "3.4.3"; + version = "3.4.5"; format = "other"; @@ -26,7 +26,7 @@ py.pkgs.buildPythonApplication rec { owner = "netbox-community"; repo = pname; rev = "refs/tags/v${version}"; - sha256 = "sha256-M/CbnlnRaWuwcJJofY5mPpVTl9zYrApsXqV9hilNyvw="; + hash = "sha256-Jh+l3BfPWXw3JWv72lI3blaS/1ZVUU5J8sNZLQiYqU4="; }; patches = [ From 6e054138b05670b2285ec815be44ef683e9bc1da Mon Sep 17 00:00:00 2001 From: Minijackson Date: Tue, 14 Mar 2023 14:05:24 +0100 Subject: [PATCH 09/13] netbox: 3.4.5 -> 3.4.6 --- pkgs/servers/web-apps/netbox/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/servers/web-apps/netbox/default.nix b/pkgs/servers/web-apps/netbox/default.nix index f0fe142a140f..8da95ef59d66 100644 --- a/pkgs/servers/web-apps/netbox/default.nix +++ b/pkgs/servers/web-apps/netbox/default.nix @@ -18,7 +18,7 @@ let in py.pkgs.buildPythonApplication rec { pname = "netbox"; - version = "3.4.5"; + version = "3.4.6"; format = "other"; @@ -26,7 +26,7 @@ py.pkgs.buildPythonApplication rec { owner = "netbox-community"; repo = pname; rev = "refs/tags/v${version}"; - hash = "sha256-Jh+l3BfPWXw3JWv72lI3blaS/1ZVUU5J8sNZLQiYqU4="; + hash = "sha256-j2Iwh+yGp0xMnZ+Fh7kepb5xzT3GRNhaAiztITgPuws="; }; patches = [ From 78eb4d64e70b95389670f24d8b00631db00653b3 Mon Sep 17 00:00:00 2001 From: Minijackson Date: Tue, 14 Mar 2023 20:23:50 +0100 Subject: [PATCH 10/13] netbox_3_3: init reintroduce previous version, use in NixOS module if stateVersion < 23.05 --- nixos/modules/services/web-apps/netbox.nix | 13 +- nixos/tests/all-tests.nix | 3 +- nixos/tests/web-apps/netbox.nix | 3 +- pkgs/servers/web-apps/netbox/3.3.nix | 114 ++++++++++++++++++ pkgs/servers/web-apps/netbox/config_3_3.patch | 50 ++++++++ .../web-apps/netbox/graphql-3_2_0.patch | 21 ++++ pkgs/top-level/all-packages.nix | 2 + 7 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 pkgs/servers/web-apps/netbox/3.3.nix create mode 100644 pkgs/servers/web-apps/netbox/config_3_3.patch create mode 100644 pkgs/servers/web-apps/netbox/graphql-3_2_0.patch diff --git a/nixos/modules/services/web-apps/netbox.nix b/nixos/modules/services/web-apps/netbox.nix index 661a55fd5e7e..0ecb20e8c2c0 100644 --- a/nixos/modules/services/web-apps/netbox.nix +++ b/nixos/modules/services/web-apps/netbox.nix @@ -14,7 +14,7 @@ let }; configFile = pkgs.concatText "configuration.py" [ settingsFile extraConfigFile ]; - pkg = (pkgs.netbox.overrideAttrs (old: { + pkg = (cfg.package.overrideAttrs (old: { installPhase = old.installPhase + '' ln -s ${configFile} $out/opt/netbox/netbox/netbox/configuration.py '' + optionalString cfg.enableLdap '' @@ -74,6 +74,17 @@ in { ''; }; + package = mkOption { + type = types.package; + default = if versionAtLeast config.system.stateVersion "23.05" then pkgs.netbox else pkgs.netbox_3_3; + defaultText = literalExpression '' + if versionAtLeast config.system.stateVersion "23.05" then pkgs.netbox else pkgs.netbox_3_3; + ''; + description = lib.mdDoc '' + NetBox package to use. + ''; + }; + port = mkOption { type = types.port; default = 8001; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a155510450b1..0783f3bf68e2 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -460,7 +460,8 @@ in { netdata = handleTest ./netdata.nix {}; networking.networkd = handleTest ./networking.nix { networkd = true; }; networking.scripted = handleTest ./networking.nix { networkd = false; }; - netbox = handleTest ./web-apps/netbox.nix {}; + netbox = handleTest ./web-apps/netbox.nix { inherit (pkgs) netbox; }; + netbox_3_3 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_3; }; # TODO: put in networking.nix after the test becomes more complete networkingProxy = handleTest ./networking-proxy.nix {}; nextcloud = handleTest ./nextcloud {}; diff --git a/nixos/tests/web-apps/netbox.nix b/nixos/tests/web-apps/netbox.nix index 9a828dde3822..30de74f1886c 100644 --- a/nixos/tests/web-apps/netbox.nix +++ b/nixos/tests/web-apps/netbox.nix @@ -8,7 +8,7 @@ let testUser = "alice"; testPassword = "verySecure"; testGroup = "netbox-users"; -in import ../make-test-python.nix ({ lib, pkgs, ... }: { +in import ../make-test-python.nix ({ lib, pkgs, netbox, ... }: { name = "netbox"; meta = with lib.maintainers; { @@ -18,6 +18,7 @@ in import ../make-test-python.nix ({ lib, pkgs, ... }: { nodes.machine = { config, ... }: { services.netbox = { enable = true; + package = netbox; secretKeyFile = pkgs.writeText "secret" '' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ''; diff --git a/pkgs/servers/web-apps/netbox/3.3.nix b/pkgs/servers/web-apps/netbox/3.3.nix new file mode 100644 index 000000000000..5420bbc22c89 --- /dev/null +++ b/pkgs/servers/web-apps/netbox/3.3.nix @@ -0,0 +1,114 @@ +{ lib +, pkgs +, fetchFromGitHub +, fetchpatch +, nixosTests +, python3 + +, plugins ? ps: [] }: + +let + py = python3.override { + packageOverrides = self: super: { + django = super.django_4; + }; + }; + + extraBuildInputs = plugins py.pkgs; +in +py.pkgs.buildPythonApplication rec { + pname = "netbox"; + version = "3.3.9"; + + format = "other"; + + src = fetchFromGitHub { + owner = "netbox-community"; + repo = pname; + rev = "refs/tags/v${version}"; + sha256 = "sha256-KhnxD5pjlEIgISl4RMbhLCDwgUDfGFRi88ZcP1ndMhI="; + }; + + patches = [ + # Allow setting the STATIC_ROOT from within the configuration and setting a custom redis URL + ./config_3_3.patch + ./graphql-3_2_0.patch + # fix compatibility ith django 4.1 + (fetchpatch { + url = "https://github.com/netbox-community/netbox/pull/10341/commits/ce6bf9e5c1bc08edc80f6ea1e55cf1318ae6e14b.patch"; + sha256 = "sha256-aCPQp6k7Zwga29euASAd+f13hIcZnIUu3RPAzNPqgxc="; + }) + ]; + + propagatedBuildInputs = with py.pkgs; [ + bleach + django_4 + django-cors-headers + django-debug-toolbar + django-filter + django-graphiql-debug-toolbar + django-mptt + django-pglocks + django-prometheus + django-redis + django-rq + django-tables2 + django-taggit + django-timezone-field + djangorestframework + drf-yasg + swagger-spec-validator # from drf-yasg[validation] + graphene-django + jinja2 + markdown + markdown-include + netaddr + pillow + psycopg2 + pyyaml + sentry-sdk + social-auth-core + social-auth-app-django + svgwrite + tablib + jsonschema + ] ++ extraBuildInputs; + + buildInputs = with py.pkgs; [ + mkdocs-material + mkdocs-material-extensions + mkdocstrings + mkdocstrings-python + ]; + + nativeBuildInputs = [ + py.pkgs.mkdocs + ]; + + postBuild = '' + PYTHONPATH=$PYTHONPATH:netbox/ + python -m mkdocs build + ''; + + installPhase = '' + mkdir -p $out/opt/netbox + cp -r . $out/opt/netbox + chmod +x $out/opt/netbox/netbox/manage.py + makeWrapper $out/opt/netbox/netbox/manage.py $out/bin/netbox \ + --prefix PYTHONPATH : "$PYTHONPATH" + ''; + + passthru = { + # PYTHONPATH of all dependencies used by the package + pythonPath = python3.pkgs.makePythonPath propagatedBuildInputs; + + tests.netbox = nixosTests.netbox_3_3; + }; + + meta = with lib; { + homepage = "https://github.com/netbox-community/netbox"; + description = "IP address management (IPAM) and data center infrastructure management (DCIM) tool"; + license = licenses.asl20; + maintainers = with maintainers; [ n0emis raitobezarius ]; + }; + } diff --git a/pkgs/servers/web-apps/netbox/config_3_3.patch b/pkgs/servers/web-apps/netbox/config_3_3.patch new file mode 100644 index 000000000000..1adc0b537a4e --- /dev/null +++ b/pkgs/servers/web-apps/netbox/config_3_3.patch @@ -0,0 +1,50 @@ +diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py +index d5a7bfaec..68754a8c5 100644 +--- a/netbox/netbox/settings.py ++++ b/netbox/netbox/settings.py +@@ -222,6 +222,7 @@ TASKS_REDIS_PASSWORD = TASKS_REDIS.get('PASSWORD', '') + TASKS_REDIS_DATABASE = TASKS_REDIS.get('DATABASE', 0) + TASKS_REDIS_SSL = TASKS_REDIS.get('SSL', False) + TASKS_REDIS_SKIP_TLS_VERIFY = TASKS_REDIS.get('INSECURE_SKIP_TLS_VERIFY', False) ++TASKS_REDIS_URL = TASKS_REDIS.get('URL') + + # Caching + if 'caching' not in REDIS: +@@ -236,11 +237,12 @@ CACHING_REDIS_SENTINELS = REDIS['caching'].get('SENTINELS', []) + CACHING_REDIS_SENTINEL_SERVICE = REDIS['caching'].get('SENTINEL_SERVICE', 'default') + CACHING_REDIS_PROTO = 'rediss' if REDIS['caching'].get('SSL', False) else 'redis' + CACHING_REDIS_SKIP_TLS_VERIFY = REDIS['caching'].get('INSECURE_SKIP_TLS_VERIFY', False) ++CACHING_REDIS_URL = REDIS['caching'].get('URL', f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_HOST}:{CACHING_REDIS_PORT}/{CACHING_REDIS_DATABASE}') + + CACHES = { + 'default': { + 'BACKEND': 'django_redis.cache.RedisCache', +- 'LOCATION': f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_HOST}:{CACHING_REDIS_PORT}/{CACHING_REDIS_DATABASE}', ++ 'LOCATION': CACHING_REDIS_URL, + 'OPTIONS': { + 'CLIENT_CLASS': 'django_redis.client.DefaultClient', + 'PASSWORD': CACHING_REDIS_PASSWORD, +@@ -383,7 +385,7 @@ USE_X_FORWARDED_HOST = True + X_FRAME_OPTIONS = 'SAMEORIGIN' + + # Static files (CSS, JavaScript, Images) +-STATIC_ROOT = BASE_DIR + '/static' ++STATIC_ROOT = getattr(configuration, 'STATIC_ROOT', os.path.join(BASE_DIR, 'static')).rstrip('/') + STATIC_URL = f'/{BASE_PATH}static/' + STATICFILES_DIRS = ( + os.path.join(BASE_DIR, 'project-static', 'dist'), +@@ -562,6 +564,14 @@ if TASKS_REDIS_USING_SENTINEL: + 'socket_connect_timeout': TASKS_REDIS_SENTINEL_TIMEOUT + }, + } ++elif TASKS_REDIS_URL: ++ RQ_PARAMS = { ++ 'URL': TASKS_REDIS_URL, ++ 'PASSWORD': TASKS_REDIS_PASSWORD, ++ 'SSL': TASKS_REDIS_SSL, ++ 'SSL_CERT_REQS': None if TASKS_REDIS_SKIP_TLS_VERIFY else 'required', ++ 'DEFAULT_TIMEOUT': RQ_DEFAULT_TIMEOUT, ++ } + else: + RQ_PARAMS = { + 'HOST': TASKS_REDIS_HOST, diff --git a/pkgs/servers/web-apps/netbox/graphql-3_2_0.patch b/pkgs/servers/web-apps/netbox/graphql-3_2_0.patch new file mode 100644 index 000000000000..1e97b7d85ce0 --- /dev/null +++ b/pkgs/servers/web-apps/netbox/graphql-3_2_0.patch @@ -0,0 +1,21 @@ +diff --git a/netbox/netbox/graphql/scalars.py b/netbox/netbox/graphql/scalars.py +index 7d14189dd..0a18e79d2 100644 +--- a/netbox/netbox/graphql/scalars.py ++++ b/netbox/netbox/graphql/scalars.py +@@ -1,6 +1,6 @@ + from graphene import Scalar + from graphql.language import ast +-from graphql.type.scalars import MAX_INT, MIN_INT ++from graphql.type.scalars import GRAPHQL_MAX_INT, GRAPHQL_MIN_INT + + + class BigInt(Scalar): +@@ -10,7 +10,7 @@ class BigInt(Scalar): + @staticmethod + def to_float(value): + num = int(value) +- if num > MAX_INT or num < MIN_INT: ++ if num > GRAPHQL_MAX_INT or num < GRAPHQL_MIN_INT: + return float(num) + return num + diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a2983fd2fa4d..fcb5c50128f2 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -10202,6 +10202,8 @@ with pkgs; netbox = callPackage ../servers/web-apps/netbox { }; + netbox_3_3 = callPackage ../servers/web-apps/netbox/3.3.nix { }; + netcat = libressl.nc; netcat-gnu = callPackage ../tools/networking/netcat { }; From c1081bf20b18c1e004ca063dba108cfd824c7da1 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Tue, 4 Apr 2023 11:11:36 +0200 Subject: [PATCH 11/13] netbox: 3.4.6 -> 3.4.7 --- pkgs/servers/web-apps/netbox/default.nix | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pkgs/servers/web-apps/netbox/default.nix b/pkgs/servers/web-apps/netbox/default.nix index 8da95ef59d66..8f19be44a6c3 100644 --- a/pkgs/servers/web-apps/netbox/default.nix +++ b/pkgs/servers/web-apps/netbox/default.nix @@ -1,7 +1,5 @@ { lib -, pkgs , fetchFromGitHub -, fetchpatch , nixosTests , python3 @@ -18,7 +16,7 @@ let in py.pkgs.buildPythonApplication rec { pname = "netbox"; - version = "3.4.6"; + version = "3.4.7"; format = "other"; @@ -26,7 +24,7 @@ py.pkgs.buildPythonApplication rec { owner = "netbox-community"; repo = pname; rev = "refs/tags/v${version}"; - hash = "sha256-j2Iwh+yGp0xMnZ+Fh7kepb5xzT3GRNhaAiztITgPuws="; + hash = "sha256-pWHGyzLc0tqfehWbCMF1l96L1pewb5FXBUkw9EqPtP8="; }; patches = [ From 03497d4ab4c6dc383130d83ba5a469f58379692b Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Tue, 4 Apr 2023 11:43:03 +0200 Subject: [PATCH 12/13] netbox: introduce common function for generic packages, mark 3.3.9 EOL --- pkgs/servers/web-apps/netbox/3.3.nix | 114 -------------------- pkgs/servers/web-apps/netbox/default.nix | 128 +++++------------------ pkgs/servers/web-apps/netbox/generic.nix | 110 +++++++++++++++++++ pkgs/top-level/all-packages.nix | 5 +- 4 files changed, 141 insertions(+), 216 deletions(-) delete mode 100644 pkgs/servers/web-apps/netbox/3.3.nix create mode 100644 pkgs/servers/web-apps/netbox/generic.nix diff --git a/pkgs/servers/web-apps/netbox/3.3.nix b/pkgs/servers/web-apps/netbox/3.3.nix deleted file mode 100644 index 5420bbc22c89..000000000000 --- a/pkgs/servers/web-apps/netbox/3.3.nix +++ /dev/null @@ -1,114 +0,0 @@ -{ lib -, pkgs -, fetchFromGitHub -, fetchpatch -, nixosTests -, python3 - -, plugins ? ps: [] }: - -let - py = python3.override { - packageOverrides = self: super: { - django = super.django_4; - }; - }; - - extraBuildInputs = plugins py.pkgs; -in -py.pkgs.buildPythonApplication rec { - pname = "netbox"; - version = "3.3.9"; - - format = "other"; - - src = fetchFromGitHub { - owner = "netbox-community"; - repo = pname; - rev = "refs/tags/v${version}"; - sha256 = "sha256-KhnxD5pjlEIgISl4RMbhLCDwgUDfGFRi88ZcP1ndMhI="; - }; - - patches = [ - # Allow setting the STATIC_ROOT from within the configuration and setting a custom redis URL - ./config_3_3.patch - ./graphql-3_2_0.patch - # fix compatibility ith django 4.1 - (fetchpatch { - url = "https://github.com/netbox-community/netbox/pull/10341/commits/ce6bf9e5c1bc08edc80f6ea1e55cf1318ae6e14b.patch"; - sha256 = "sha256-aCPQp6k7Zwga29euASAd+f13hIcZnIUu3RPAzNPqgxc="; - }) - ]; - - propagatedBuildInputs = with py.pkgs; [ - bleach - django_4 - django-cors-headers - django-debug-toolbar - django-filter - django-graphiql-debug-toolbar - django-mptt - django-pglocks - django-prometheus - django-redis - django-rq - django-tables2 - django-taggit - django-timezone-field - djangorestframework - drf-yasg - swagger-spec-validator # from drf-yasg[validation] - graphene-django - jinja2 - markdown - markdown-include - netaddr - pillow - psycopg2 - pyyaml - sentry-sdk - social-auth-core - social-auth-app-django - svgwrite - tablib - jsonschema - ] ++ extraBuildInputs; - - buildInputs = with py.pkgs; [ - mkdocs-material - mkdocs-material-extensions - mkdocstrings - mkdocstrings-python - ]; - - nativeBuildInputs = [ - py.pkgs.mkdocs - ]; - - postBuild = '' - PYTHONPATH=$PYTHONPATH:netbox/ - python -m mkdocs build - ''; - - installPhase = '' - mkdir -p $out/opt/netbox - cp -r . $out/opt/netbox - chmod +x $out/opt/netbox/netbox/manage.py - makeWrapper $out/opt/netbox/netbox/manage.py $out/bin/netbox \ - --prefix PYTHONPATH : "$PYTHONPATH" - ''; - - passthru = { - # PYTHONPATH of all dependencies used by the package - pythonPath = python3.pkgs.makePythonPath propagatedBuildInputs; - - tests.netbox = nixosTests.netbox_3_3; - }; - - meta = with lib; { - homepage = "https://github.com/netbox-community/netbox"; - description = "IP address management (IPAM) and data center infrastructure management (DCIM) tool"; - license = licenses.asl20; - maintainers = with maintainers; [ n0emis raitobezarius ]; - }; - } diff --git a/pkgs/servers/web-apps/netbox/default.nix b/pkgs/servers/web-apps/netbox/default.nix index 8f19be44a6c3..a73ab9b186b8 100644 --- a/pkgs/servers/web-apps/netbox/default.nix +++ b/pkgs/servers/web-apps/netbox/default.nix @@ -1,108 +1,38 @@ -{ lib -, fetchFromGitHub -, nixosTests -, python3 - -, plugins ? ps: [] }: - +{ lib, nixosTests, callPackage, fetchpatch }: let - py = python3 // { - pkgs = python3.pkgs.overrideScope (self: super: { - django = super.django_4; - }); + generic = import ./generic.nix; +in +{ + netbox_3_3 = callPackage generic { + version = "3.3.9"; + hash = "sha256-KhnxD5pjlEIgISl4RMbhLCDwgUDfGFRi88ZcP1ndMhI="; + extraPatches = [ + # Allow setting the STATIC_ROOT from within the configuration and setting a custom redis URL + ./config_3_3.patch + ./graphql-3_2_0.patch + # fix compatibility ith django 4.1 + (fetchpatch { + url = "https://github.com/netbox-community/netbox/pull/10341/commits/ce6bf9e5c1bc08edc80f6ea1e55cf1318ae6e14b.patch"; + sha256 = "sha256-aCPQp6k7Zwga29euASAd+f13hIcZnIUu3RPAzNPqgxc="; + }) + ]; + + tests.netbox = nixosTests.netbox_3_3; + maintainers = with lib.maintainers; [ n0emis raitobezarius ]; + eol = true; }; - extraBuildInputs = plugins py.pkgs; -in -py.pkgs.buildPythonApplication rec { - pname = "netbox"; + netbox = callPackage generic { version = "3.4.7"; - - format = "other"; - - src = fetchFromGitHub { - owner = "netbox-community"; - repo = pname; - rev = "refs/tags/v${version}"; - hash = "sha256-pWHGyzLc0tqfehWbCMF1l96L1pewb5FXBUkw9EqPtP8="; - }; - - patches = [ + hash = "sha256-pWHGyzLc0tqfehWbCMF1l96L1pewb5FXBUkw9EqPtP8="; + extraPatches = [ # Allow setting the STATIC_ROOT from within the configuration and setting a custom redis URL ./config.patch ]; - - propagatedBuildInputs = with py.pkgs; [ - bleach - django_4 - django-cors-headers - django-debug-toolbar - django-filter - django-graphiql-debug-toolbar - django-mptt - django-pglocks - django-prometheus - django-redis - django-rq - django-tables2 - django-taggit - django-timezone-field - djangorestframework - drf-yasg - swagger-spec-validator # from drf-yasg[validation] - graphene-django - jinja2 - markdown - markdown-include - netaddr - pillow - psycopg2 - pyyaml - sentry-sdk - social-auth-core - social-auth-app-django - svgwrite - tablib - jsonschema - ] ++ extraBuildInputs; - - buildInputs = with py.pkgs; [ - mkdocs-material - mkdocs-material-extensions - mkdocstrings - mkdocstrings-python - ]; - - nativeBuildInputs = [ - py.pkgs.mkdocs - ]; - - postBuild = '' - PYTHONPATH=$PYTHONPATH:netbox/ - python -m mkdocs build - ''; - - installPhase = '' - mkdir -p $out/opt/netbox - cp -r . $out/opt/netbox - chmod +x $out/opt/netbox/netbox/manage.py - makeWrapper $out/opt/netbox/netbox/manage.py $out/bin/netbox \ - --prefix PYTHONPATH : "$PYTHONPATH" - ''; - - passthru = { - # PYTHONPATH of all dependencies used by the package - pythonPath = python3.pkgs.makePythonPath propagatedBuildInputs; - - tests = { - inherit (nixosTests) netbox; - }; + tests = { + inherit (nixosTests) netbox; }; - meta = with lib; { - homepage = "https://github.com/netbox-community/netbox"; - description = "IP address management (IPAM) and data center infrastructure management (DCIM) tool"; - license = licenses.asl20; - maintainers = with maintainers; [ minijackson n0emis raitobezarius ]; - }; - } + maintainers = with lib.maintainers; [ minijackson n0emis raitobezarius ]; + }; +} diff --git a/pkgs/servers/web-apps/netbox/generic.nix b/pkgs/servers/web-apps/netbox/generic.nix new file mode 100644 index 000000000000..ace3e4f011f0 --- /dev/null +++ b/pkgs/servers/web-apps/netbox/generic.nix @@ -0,0 +1,110 @@ +{ lib +, fetchFromGitHub +, python3 +, version +, hash +, plugins ? ps: [] +, extraPatches ? [] +, tests ? {} +, maintainers ? [] +, eol ? false +}: + let + py = python3 // { + pkgs = python3.pkgs.overrideScope (self: super: { + django = super.django_4; + }); + }; + + extraBuildInputs = plugins py.pkgs; + in + py.pkgs.buildPythonApplication rec { + pname = "netbox"; + inherit version; + + format = "other"; + + src = fetchFromGitHub { + owner = "netbox-community"; + repo = pname; + rev = "refs/tags/v${version}"; + inherit hash; + }; + + patches = extraPatches; + + propagatedBuildInputs = with py.pkgs; [ + bleach + django_4 + django-cors-headers + django-debug-toolbar + django-filter + django-graphiql-debug-toolbar + django-mptt + django-pglocks + django-prometheus + django-redis + django-rq + django-tables2 + django-taggit + django-timezone-field + djangorestframework + drf-yasg + swagger-spec-validator # from drf-yasg[validation] + graphene-django + jinja2 + markdown + markdown-include + netaddr + pillow + psycopg2 + pyyaml + sentry-sdk + social-auth-core + social-auth-app-django + svgwrite + tablib + jsonschema + ] ++ extraBuildInputs; + + buildInputs = with py.pkgs; [ + mkdocs-material + mkdocs-material-extensions + mkdocstrings + mkdocstrings-python + ]; + + nativeBuildInputs = [ + py.pkgs.mkdocs + ]; + + postBuild = '' + PYTHONPATH=$PYTHONPATH:netbox/ + python -m mkdocs build + ''; + + installPhase = '' + mkdir -p $out/opt/netbox + cp -r . $out/opt/netbox + chmod +x $out/opt/netbox/netbox/manage.py + makeWrapper $out/opt/netbox/netbox/manage.py $out/bin/netbox \ + --prefix PYTHONPATH : "$PYTHONPATH" + ''; + + passthru = { + # PYTHONPATH of all dependencies used by the package + pythonPath = python3.pkgs.makePythonPath propagatedBuildInputs; + inherit tests; + }; + + meta = { + homepage = "https://github.com/netbox-community/netbox"; + description = "IP address management (IPAM) and data center infrastructure management (DCIM) tool"; + license = lib.licenses.asl20; + knownVulnerabilities = (lib.optional eol "Netbox version ${version} is EOL; please upgrade by following the current release notes instructions."); + # Warning: + # Notice the missing `lib` in the inherit: it is using this function argument rather than a `with lib;` argument. + # If you replace this by `with lib;`, pay attention it does not inherit all maintainers in nixpkgs. + inherit maintainers; + }; + } diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index fcb5c50128f2..77d5064a2d06 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -10200,9 +10200,8 @@ with pkgs; netbootxyz-efi = callPackage ../tools/misc/netbootxyz-efi { }; - netbox = callPackage ../servers/web-apps/netbox { }; - - netbox_3_3 = callPackage ../servers/web-apps/netbox/3.3.nix { }; + inherit (callPackage ../servers/web-apps/netbox { }) + netbox_3_3 netbox; netcat = libressl.nc; From e965c5cc5f9b6d39f118f939fe8fa7024178a621 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Tue, 4 Apr 2023 11:43:26 +0200 Subject: [PATCH 13/13] netbox_3_3: 3.3.9 -> 3.3.10 --- pkgs/servers/web-apps/netbox/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/servers/web-apps/netbox/default.nix b/pkgs/servers/web-apps/netbox/default.nix index a73ab9b186b8..fb9e8a6aa57f 100644 --- a/pkgs/servers/web-apps/netbox/default.nix +++ b/pkgs/servers/web-apps/netbox/default.nix @@ -4,8 +4,8 @@ let in { netbox_3_3 = callPackage generic { - version = "3.3.9"; - hash = "sha256-KhnxD5pjlEIgISl4RMbhLCDwgUDfGFRi88ZcP1ndMhI="; + version = "3.3.10"; + hash = "sha256-MeOfTU5IxNDoUh7FyvwAQNRC/CE0R6p40WnlF+3RuxA="; extraPatches = [ # Allow setting the STATIC_ROOT from within the configuration and setting a custom redis URL ./config_3_3.patch