diff options
Diffstat (limited to 'nix')
| -rw-r--r-- | nix/default.nix | 16 | ||||
| -rw-r--r-- | nix/derivation.nix | 21 | ||||
| -rw-r--r-- | nix/dev.nix | 41 | ||||
| -rw-r--r-- | nix/module.nix | 118 | ||||
| -rw-r--r-- | nix/packages.nix | 25 | ||||
| -rw-r--r-- | nix/server.nix | 6 | ||||
| -rw-r--r-- | nix/vm.nix | 42 |
7 files changed, 232 insertions, 37 deletions
diff --git a/nix/default.nix b/nix/default.nix deleted file mode 100644 index fca9993..0000000 --- a/nix/default.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ - lib, - python311Packages, - version, -}: -python311Packages.buildPythonPackage { - pname = "guzzle-api"; - inherit version; - - src = lib.cleanSource ../.; - format = "flit"; - doCheck = false; - - propagatedBuildInputs = with python311Packages; [fastapi pydantic uvicorn]; - propagatedNativeBuildInputs = with python311Packages; [flit-core]; -} diff --git a/nix/derivation.nix b/nix/derivation.nix new file mode 100644 index 0000000..4e32095 --- /dev/null +++ b/nix/derivation.nix @@ -0,0 +1,21 @@ +{ + lib, + buildPythonPackage, + flit-core, + fastapi, + pydantic, + uvicorn, + self, + version, +}: +buildPythonPackage { + pname = "guzzle-api"; + inherit version; + + src = lib.cleanSource self; + format = "flit"; + doCheck = false; + + propagatedBuildInputs = [fastapi pydantic uvicorn]; + propagatedNativeBuildInputs = [flit-core]; +} diff --git a/nix/dev.nix b/nix/dev.nix new file mode 100644 index 0000000..b394c6c --- /dev/null +++ b/nix/dev.nix @@ -0,0 +1,41 @@ +{ + inputs, + self, + withSystem, + ... +}: { + perSystem = { + config, + pkgs, + ... + }: { + pre-commit = { + settings.hooks = { + isort.enable = true; + pylint.enable = true; + yapf = { + enable = true; + name = "yapf"; + entry = "${pkgs.python311Packages.yapf}/bin/yapf -i"; + types = ["file" "python"]; + }; + }; + }; + + devShells.default = pkgs.mkShell { + shellHook = config.pre-commit.installationScript; + packages = [ + (pkgs.python311.withPackages (p: with p; [isort yapf pylint])) + ]; + }; + }; + + flake.tests.x86_64-linux.module = withSystem "x86_64-linux" ({pkgs, ...}: + (import (inputs.nixpkgs + "/nixos/lib") {}).runTest { + imports = [./vm.nix]; + + hostPkgs = pkgs; + + _module.args = {inherit self;}; + }); +} diff --git a/nix/module.nix b/nix/module.nix index 4234e19..10f09c3 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -1,43 +1,125 @@ -{ +self: { config, lib, + modulesPath, pkgs, ... }: let cfg = config.services.guzzle-api; - inherit (lib) mkDefault mkEnableOption mkOption mkIf types; + inherit + (lib) + literalExpression + mkDefault + mkDoc + mkEnableOption + mkIf + mkMerge + mkOption + mkPackageOption + types + ; + + proto = "http${lib.optionalString cfg.nginx.addSSL "s"}"; + + hostPortSubmodule = { + options = { + host = mkOption { + description = mkDoc "the hostname"; + type = types.str; + }; + + port = mkOption { + description = mkDoc "the port"; + type = types.port; + }; + }; + }; in { options.services.guzzle-api = { - enable = mkEnableOption "enable guzzle-api"; - url = mkOption { - type = types.str; - default = ""; - description = "url string for guzzle-api"; + enable = mkEnableOption "guzzle-api"; + + listen = mkOption { + description = mkDoc "address and port to listen to"; + type = types.submodule hostPortSubmodule; + default = { + host = "localhost"; + port = 7240; + }; + defaultText = literalExpression '' + { + address = "localhost"; + port = 7240; + } + ''; }; - port = mkOption { + + domain = mkOption { + description = mkDoc "FQDN for guzzle_api endpoint"; type = types.str; - default = "8080"; - description = "port for guzzle-api"; }; - package = mkOption { - type = types.package; - default = pkgs.guzzle-api-server; - description = "package for guzzle-api wrapper"; + + nginx = mkOption { + description = mkDoc '' + With this option, you can customize an nginx virtual host which already has sensible defaults for Dolibarr. + Set to {} if you do not need any customization to the virtual host. + If enabled, then by default, the {option}`serverName` is + `''${domain}`, + If this is set to null (the default), no nginx virtualHost will be configured. + ''; + + type = types.nullOr (types.submodule ( + import (modulesPath + "/services/web-servers/nginx/vhost-options.nix") {inherit config lib;} + )); + + default = null; + example = literalExpression '' + { + enableACME = true; + forceSSL = true; + } + ''; }; + + package = mkPackageOption self.packages.${pkgs.stdenv.hostPlatform.system} "guzzle-api-server" {}; }; - config.systemd.services = mkIf cfg.enable { - guzzle-api = { + config = mkIf cfg.enable { + systemd.services.guzzle-api = { enable = mkDefault true; wantedBy = ["multi-user.target"]; after = ["network.target"]; script = '' - URL=${cfg.url} ${cfg.package}/bin/guzzle-api-server --host 0.0.0.0 --port "${cfg.port}" + URL="${proto}://${cfg.domain}" ${cfg.package}/bin/guzzle-api-server --host ${cfg.listen.host} --port ${toString cfg.listen.port} ''; serviceConfig = mkDefault { - Restart = "always"; Type = "simple"; + Restart = "always"; + + # hardening + DynamicUser = true; + PrivateTmp = true; + NoNewPrivileges = true; + RestrictNamespaces = "uts ipc pid user cgroup"; + ProtectSystem = "strict"; + ProtectHome = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + PrivateDevices = true; + RestrictSUIDSGID = true; }; }; + + services.nginx = mkIf (cfg.nginx != null) { + enable = true; + virtualHosts."${cfg.domain}" = mkMerge [ + { + locations."/" = { + proxyPass = "http://${cfg.listen.host}:${toString cfg.listen.port}"; + }; + } + cfg.nginx + ]; + }; }; } diff --git a/nix/packages.nix b/nix/packages.nix new file mode 100644 index 0000000..0adf42f --- /dev/null +++ b/nix/packages.nix @@ -0,0 +1,25 @@ +{self, ...}: let + version = builtins.substring 0 8 self.lastModifiedDate or "dirty"; + commonArgs = {inherit self version;}; +in { + perSystem = {pkgs, ...}: { + packages = rec { + guzzle-api = pkgs.python311Packages.callPackage ./derivation.nix commonArgs; + guzzle-api-server = pkgs.python311Packages.callPackage ./server.nix {inherit guzzle-api;}; + default = guzzle-api; + }; + }; + + flake.overlays.default = final: prev: { + python = prev.python.override { + packageOverrides = _: prev': { + guzzle-api = prev'.callPackage ./derivation.nix commonArgs; + }; + }; + + pythonPackages = final.python.pkgs; + + guzzle-api = final.pythonPackages.callPackage ./derivation.nix commonArgs; + guzzle-api-server = final.pythonPackages.callPackage ./server.nix {}; + }; +} diff --git a/nix/server.nix b/nix/server.nix index 18e4673..eaa3ead 100644 --- a/nix/server.nix +++ b/nix/server.nix @@ -1,12 +1,12 @@ { writeShellApplication, - python311, + python, + uvicorn, guzzle-api, - ... }: writeShellApplication { name = "guzzle-api-server"; - runtimeInputs = [(python311.withPackages (p: [p.uvicorn guzzle-api]))]; + runtimeInputs = [(python.withPackages (_: [uvicorn guzzle-api]))]; text = '' uvicorn guzzle_api.api:app "$@" ''; diff --git a/nix/vm.nix b/nix/vm.nix new file mode 100644 index 0000000..b4d1f8a --- /dev/null +++ b/nix/vm.nix @@ -0,0 +1,42 @@ +{self, ...}: { + name = "guzzle_api-test"; + + nodes.machine = _: { + imports = [self.nixosModules.default]; + + boot.loader.grub.enable = true; + virtualisation = { + memorySize = 2048; + writableStore = true; + }; + + services = { + nginx = { + enable = true; + + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + }; + + guzzle-api = { + enable = true; + domain = "test.com"; + listen = { + host = "0.0.0.0"; + port = 8080; + }; + nginx = {}; + }; + }; + }; + + testScript = _: '' + machine.start() + machine.wait_for_unit("nginx.service") + machine.wait_for_unit("guzzle-api.service") + machine.wait_for_open_port(8080) + machine.succeed("curl 0.0.0.0:8080/get_random_teawie | grep url") + ''; +} |
