Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

netbox: 3.3.9 -> 3.4.7, netbox_3_3: init at 3.3.10, RFC42-style options, more tests #206983

Merged
merged 13 commits into from
Apr 5, 2023
4 changes: 4 additions & 0 deletions nixos/doc/manual/release-notes/rl-2305.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
164 changes: 125 additions & 39 deletions nixos/modules/services/web-apps/netbox.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,17 @@ 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;
};
pkg = (pkgs.netbox.overrideAttrs (old: {
configFile = pkgs.concatText "configuration.py" [ settingsFile extraConfigFile ];

pkg = (cfg.package.overrideAttrs (old: {
installPhase = old.installPhase + ''
ln -s ${configFile} $out/opt/netbox/netbox/netbox/configuration.py
'' + optionalString cfg.enableLdap ''
Expand Down Expand Up @@ -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]";
Expand All @@ -78,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;
Expand Down Expand Up @@ -117,7 +124,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.
'';
};

Expand All @@ -138,11 +145,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;

Expand Down
3 changes: 2 additions & 1 deletion nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 {};
Expand Down
Loading