···
-
ldapDomain = "example.org";
-
ldapSuffix = "dc=example,dc=org";
-
ldapRootUser = "admin";
-
ldapRootPassword = "foobar";
-
testPassword = "verySecure";
-
testGroup = "netbox-users";
-
import ../make-test-python.nix (
-
meta = with lib.maintainers; {
-
virtualisation.memorySize = 2048;
-
secretKeyFile = pkgs.writeText "secret" ''
-
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
-
ldapConfigPath = pkgs.writeText "ldap_config.py" ''
-
from django_auth_ldap.config import LDAPSearch, PosixGroupType
-
AUTH_LDAP_SERVER_URI = "ldap://localhost/"
-
AUTH_LDAP_USER_SEARCH = LDAPSearch(
-
"ou=accounts,ou=posix,${ldapSuffix}",
-
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
-
"ou=groups,ou=posix,${ldapSuffix}",
-
"(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
-
recommendedProxySettings = true;
-
virtualHosts.netbox = {
-
locations."/".proxyPass = "http://localhost:${toString config.services.netbox.port}";
-
locations."/static/".alias = "/var/lib/netbox/static/";
-
# Adapted from the sssd-ldap NixOS test
-
"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" = {
-
olcDatabase = "{1}mdb";
-
olcDbDirectory = "/var/lib/openldap/db";
-
olcSuffix = ldapSuffix;
-
olcRootDN = "cn=${ldapRootUser},${ldapSuffix}";
-
olcRootPW = ldapRootPassword;
-
declarativeContents = {
-
objectClass: organization
-
dn: ou=posix,${ldapSuffix}
-
objectClass: organizationalUnit
-
dn: ou=accounts,ou=posix,${ldapSuffix}
-
objectClass: organizationalUnit
-
dn: uid=${testUser},ou=accounts,ou=posix,${ldapSuffix}
-
objectClass: posixAccount
-
userPassword: ${testPassword}
-
homeDirectory: /home/${testUser}
-
dn: ou=groups,ou=posix,${ldapSuffix}
-
objectClass: organizationalUnit
-
dn: cn=${testGroup},ou=groups,ou=posix,${ldapSuffix}
-
objectClass: posixGroup
-
users.users.nginx.extraGroups = [ "netbox" ];
-
networking.firewall.allowedTCPPorts = [ 80 ];
-
changePassword = pkgs.writeText "change-password.py" ''
-
from users.models import User
-
u = User.objects.get(username='netbox')
-
u.set_password('netbox')
-
from typing import Any, Dict
-
machine.wait_for_unit("netbox.target")
-
machine.wait_until_succeeds("journalctl --since -1m --unit netbox --grep Listening")
-
with subtest("Home screen loads"):
-
"curl -sSfL http://[::1]:8001 | grep '<title>Home | NetBox</title>'"
-
with subtest("Staticfiles are generated"):
-
machine.succeed("test -e /var/lib/netbox/static/netbox.js")
-
with subtest("Superuser can be created"):
-
"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"):
-
"curl -sSfL http://localhost | grep '<title>Home | NetBox</title>'"
-
with subtest("Staticfiles can be fetched"):
-
machine.succeed("curl -sSfL http://localhost/static/netbox.js")
-
machine.succeed("curl -sSfL http://localhost/static/docs/")
-
def login(username: str, password: str):
-
encoded_data = json.dumps({"username": username, "password": password})
-
uri = "/users/tokens/provision/"
-
"-H 'Accept: application/json' "
-
"-H 'Content-Type: application/json' "
-
f"'http://localhost/api{uri}' "
-
f"--data '{encoded_data}'"
-
with subtest("Can login"):
-
auth_token = login("netbox", "netbox")
-
"-H 'Accept: application/json' "
-
f"-H 'Authorization: Token {auth_token}' "
-
f"'http://localhost/api{uri}'"
-
return machine.succeed(
-
"-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)
-
"-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"})
-
# 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})
-
"/dcim/manufacturers/",
-
{"name": "Test manufacturer", "slug": "test-manufacturer"}
-
manufacturer_id = result["id"]
-
# Had an issue with device-types before NetBox 3.4.0
-
"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 } } }",
-
"-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"])