# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0

{ config, lib, depot, pkgs, ... }:
let
  inherit (depot.ops) secrets;

  netboxConfiguration = ''
    SECRET_KEY = '${secrets.netbox.secretKey}'

    ADMINS = []
    ALLOWED_URL_SCHEMES = (
      'file', 'ftp', 'ftps', 'http', 'https', 'irc', 'mailto', 'sftp', 'ssh', 'tel', 'telnet', 'tftp', 'vnc', 'xmpp',
    )

    BANNER_TOP = ""
    BANNER_BOTTOM = ""
    BANNER_LOGIN = ""
    BASE_PATH = ""

    CHANGELOG_RETENTION = 0

    CORS_ORIGIN_ALLOW_ALL = False
    CORS_ORIGIN_WHITELIST = []
    CORS_ORIGIN_REGEX_WHITELIST = []

    CUSTOM_VALIDATORS = {}

    DEBUG = False

    EMAIL = {}

    ENFORCE_GLOBAL_UNIQUE = True

    EXEMPT_VIEW_PERMISSIONS = []

    GRAPHQL_ENABLED = False

    INTERNAL_IPS = ('127.0.0.1', '::1')

    LOGIN_REQUIRED = True
    LOGIN_TIMEOUT = None

    MAINTENANCE_MODE = False

    MAPS_URL = 'https://maps.google.com/?q='

    MAX_PAGE_SIZE = 1000

    MEDIA_ROOT = '/srv/netbox/media'

    STORAGE_BACKEND = 'storages.backends.s3boto3.S3Boto3Storage'
    STORAGE_CONFIG = {
      'AWS_ACCESS_KEY_ID': "${secrets.netbox.s3.accessKey}",
      'AWS_SECRET_ACCESS_KEY': "${secrets.netbox.s3.secretAccessKey}",
      'AWS_STORAGE_BUCKET_NAME': 'netbox',
      'AWS_S3_ENDPOINT_URL': 'https://objdump.zxcvbnm.ninja',
      'AWS_S3_REGION_NAME': 'london',
    }

    METRICS_ENABLED = False

    NAPALM_USERNAME = ""
    NAPALM_PASSWORD = ""
    NAPALM_TIMEOUT = 30
    NAPALM_ARGS = {}

    PAGINATE_COUNT = 50

    PLUGINS = []

    PREFER_IPV4 = False

    RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = 22
    RACK_ELEVATION_DEFAULT_UNIT_WIDTH = 220

    REMOTE_AUTH_ENABLED = False
    REMOTE_AUTH_BACKEND = 'netbox.authentication.RemoteUserBackend'
    REMOTE_AUTH_HEADER = 'HTTP_REMOTE_USER'
    REMOTE_AUTH_AUTO_CREATE_USER = True
    REMOTE_AUTH_DEFAULT_GROUPS = []
    REMOTE_AUTH_DEFAULT_PERMISSIONS = {}

    RELEASE_CHECK_URL = None

    REPORTS_ROOT = '/srv/netbox/reports'

    RQ_DEFAULT_TIMEOUT = 300

    SCRIPTS_ROOT = '/srv/netbox/scripts'

    SESSION_COOKIE_NAME = 'netboxsess'

    TIME_ZONE = 'UTC'

    DATE_FORMAT = 'Y-m-d'
    SHORT_DATE_FORMAT = 'Y-m-d'
    TIME_FORMAT = 'g:i a'
    SHORT_TIME_FORMAT = 'H:i:s'
    DATETIME_FORMAT = 'Y-m-d g:i a'
    SHORT_DATETIME_FORMAT = 'Y-m-d H:i'
  '';
in {
  imports = [
    ../lib/bvm.nix
  ];

  # Networking!
  networking = {
    hostName = "bvm-netbox";
    hostId = "e70e18a5";

    interfaces.enp1s0 = {
      ipv4.addresses = [{ address = "10.100.0.206"; prefixLength = 23; }];
    };
    interfaces.enp2s0 = {
      ipv4.addresses = [{ address = "92.118.28.8"; prefixLength = 24; }];
      ipv6.addresses = [{ address = "2a09:a441::8"; prefixLength = 32; }];
    };
    defaultGateway = { address = "92.118.28.1"; interface = "enp2s0"; };
    defaultGateway6 = { address = "2a09:a441::1"; interface = "enp2s0"; };
  };
  networking.firewall.allowedTCPPorts = [ 80 443 ];
  my.ip.tailscale = "100.81.27.52";
  my.ip.tailscale6 = "fd7a:115c:a1e0:ab12:4843:cd96:6251:1b34";

  services.postgresqlBackup.enable = true;

  my.vault.secrets.netbox-secret-key = {
    restartUnits = ["netbox.service"];
    group = "root";
    template = ''
      {{ with secret "kv/apps/netbox" }}
      {{ .Data.data.secret-key }}
      {{ end }}
    '';
  };
  my.vault.secrets.netbox-s3-access-key = {
    restartUnits = ["netbox.service"];
    group = "root";
    template = ''
      {{ with secret "kv/apps/netbox" }}
      {{ .Data.data.s3-access-key }}
      {{ end }}
    '';
  };
  my.vault.secrets.netbox-s3-secret-access-key = {
    restartUnits = ["netbox.service"];
    group = "root";
    template = ''
      {{ with secret "kv/apps/netbox" }}
      {{ .Data.data.s3-secret-access-key }}
      {{ end }}
    '';
  };

  services.netbox = {
    enable = true;
    dataDir = "/srv/netbox";
    extraConfig = lib.mkAfter (netboxConfiguration + ''
      with open("${config.my.vault.secrets.netbox-s3-access-key.path}", "r") as f:
        STORAGE_CONFIG['AWS_ACCESS_KEY_ID'] = f.readline()
      with open("${config.my.vault.secrets.netbox-s3-secret-access-key.path}", "r") as f:
        STORAGE_CONFIG['AWS_SECRET_ACCESS_KEY'] = f.readline()
    '');
    listenAddress = "127.0.0.1";
    port = 8001;
    package = pkgs.netbox_3_7;
    secretKeyFile = config.my.vault.secrets.netbox-secret-key.path;
    settings = {
      ALLOWED_HOSTS = ["netbox.int.lukegb.com"];
    };
  };

  services.nginx = {
    enable = true;
    recommendedProxySettings = true;
    virtualHosts."netbox.int.lukegb.com" = {
      locations."/static/" = {
        alias = "/srv/netbox/static";
      };
      locations."/" = {
        proxyPass = "http://127.0.0.1:8001";
      };
    };
    virtualHosts."livetaild.lukegb.dev" = {
      forceSSL = true;
      sslCertificate = "/var/lib/acme/livetaild.lukegb.dev/fullchain.pem";
      sslCertificateKey = "/var/lib/acme/livetaild.lukegb.dev/privkey.pem";
      sslTrustedCertificate = "/var/lib/acme/livetaild.lukegb.dev/chain.pem";
      locations."/" = {
        extraConfig = ''
          return 403;
        '';
      };
      locations."/.auth/return" = {
        extraConfig = ''
          if ($arg_state ~ ^a-) {
            return 303 https://a.livetaild.lukegb.dev$request_uri;
          }
          if ($arg_state ~ ^b-) {
            return 303 https://b.livetaild.lukegb.dev$request_uri;
          }
          if ($arg_state ~ ^localhost-) {
            return 303 http://localhost:13371$request_uri;
          }
          return 403;
        '';
      };
    };
    virtualHosts."a.livetaild.lukegb.dev" = {
      forceSSL = true;
      sslCertificate = "/var/lib/acme/livetaild.lukegb.dev/fullchain.pem";
      sslCertificateKey = "/var/lib/acme/livetaild.lukegb.dev/privkey.pem";
      sslTrustedCertificate = "/var/lib/acme/livetaild.lukegb.dev/chain.pem";
      locations."/" = {
        proxyPass = "http://10.222.0.2:13371";
      };
    };
    virtualHosts."b.livetaild.lukegb.dev" = {
      forceSSL = true;
      sslCertificate = "/var/lib/acme/livetaild.lukegb.dev/fullchain.pem";
      sslCertificateKey = "/var/lib/acme/livetaild.lukegb.dev/privkey.pem";
      sslTrustedCertificate = "/var/lib/acme/livetaild.lukegb.dev/chain.pem";
      locations."/" = {
        proxyPass = "http://10.222.0.3:13371";
      };
    };
  };
  my.vault.acmeCertificates."livetaild.lukegb.dev" = {
    hostnames = [
      "livetaild.lukegb.dev"
      "*.livetaild.lukegb.dev"
    ];
    reloadOrRestartUnits = [ "nginx.service" ];
  };
  users.groups.acme = {};
  users.users.nginx.extraGroups = lib.mkAfter [ "acme" ];

  users.groups.ninovpn = {};
  users.users.ninovpn = {
    group = "ninovpn";
    isNormalUser = true;
    openssh.authorizedKeys.keys = [
      "command=\"/bin/false\",restrict,port-forwarding ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIISTSUEIzxpqa9kZwfryFlYA5FJaHJiDJHnw13Vg4NHg root@nino-010-worker"
      "command=\"/bin/false\",restrict,port-forwarding ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHGK5a+5jekPlsI+44PCy9CZWQFqFzNVEuCo4LVZxo3O root@nino-011-worker"
    ];
  };

  systemd.network.netdevs."20-wg0" = {
    netdevConfig = {
      Kind = "wireguard";
      Name = "wg0";
    };
    wireguardConfig = {
      Address = "10.222.0.1/24";
      PrivateKeyFile = "/home/ninovpn/wg-priv";
    };
    wireguardPeers = [{
      wireguardPeerConfig = {
        PublicKey = "0WX1QmQaSDavNTAIp5vRsoG+UNXOP1ttZ+2VahoHR0c=";
        AllowedIPs = ["10.222.0.2/32"];
      };
    } {
      wireguardPeerConfig = {
        PublicKey = "oeRBlP5C3vHc3GDqgRT9F2qly6MAoy1+CjRHsU4F6Bo=";
        AllowedIPs = ["10.222.0.3/32"];
      };
    }];
  };
  systemd.network.networks."20-wg0" = {
    matchConfig.Name = "wg0";
    linkConfig.RequiredForOnline = "no";
    addresses = [{
      addressConfig = {
        Address = "10.222.0.1/24";
      };
    }];
  };

  system.stateVersion = "23.11";
}