From 6d7653ff0c4916edbc26b5144914730d63555033 Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 6 Mar 2024 10:23:25 +0000 Subject: [PATCH] chore: add basic template and lib --- .envrc | 4 + .gitignore | 5 + README.md | 6 + flake.lock | 392 +++++++++++++++++++++++++++++++++++++++++++ flake.nix | 88 ++++++++++ lib/default.nix | 79 +++++++++ template/default.nix | 8 + template/values.nix | 11 ++ 8 files changed, 593 insertions(+) create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 lib/default.nix create mode 100644 template/default.nix create mode 100644 template/values.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..a2d9328 --- /dev/null +++ b/.envrc @@ -0,0 +1,4 @@ +if ! use flake . --impure +then + echo "devenv could not be build. The devenv environment was not loaded. Make the necessary changes to flake.nix and hit enter to try again." >&2 +fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7ecd6b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.direnv +.devenv +.idea +result +.pre-commit-config.yaml diff --git a/README.md b/README.md index a4059bb..af2dd94 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,9 @@ This repository contains utilities for creating Nixlets and a collection of Nixlets. \ Nixlets are kinda like Helm Charts but they are defined using Kubenix and the Nix language. \ +\ +One can import the Flake and use the renderNixlet function to turn values (like in Helm) into Kubernetes manifests in YAML. + +## Examples +Check out the existing [nixlets](./nixlets/) to understand how they work. \ +There is also a bare bones [template](./template/). diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..bd2d7bb --- /dev/null +++ b/flake.lock @@ -0,0 +1,392 @@ +{ + "nodes": { + "devenv": { + "inputs": { + "flake-compat": "flake-compat", + "nix": "nix", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": [ + "pre-commit-hooks" + ] + }, + "locked": { + "lastModified": 1709596918, + "narHash": "sha256-X8tp7nYunRZds8GdSEp+ZBMPf3ym9e6VjZWN8fmzBrc=", + "owner": "cachix", + "repo": "devenv", + "rev": "4eccee9a19ad9be42a7859211b456b281d704313", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_3": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1709336216, + "narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703887061, + "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "kubenix": { + "inputs": { + "flake-compat": "flake-compat_2", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems", + "treefmt": "treefmt" + }, + "locked": { + "lastModified": 1705801181, + "narHash": "sha256-vH+n5qMnwFCx3LMON2hQMi9PjMpmTraGYXe1czJTfAg=", + "owner": "hall", + "repo": "kubenix", + "rev": "76b8053b27b062b11f0c9b495050cc55606ac9dc", + "type": "github" + }, + "original": { + "owner": "hall", + "repo": "kubenix", + "type": "github" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1676545802, + "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", + "owner": "domenkozar", + "repo": "nix", + "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "relaxed-flakes", + "repo": "nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1678875422, + "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1709237383, + "narHash": "sha256-cy6ArO4k5qTx+l5o+0mL9f5fa86tYUX3ozE1S+Txlds=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1536926ef5621b09bba54035ae2bb6d806d72ac8", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1704874635, + "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1709386671, + "narHash": "sha256-VPqfBnIJ+cfa78pd4Y5Cr6sOWVW8GYHRVucxJGmRf8Q=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "fa9a51752f1b5de583ad5213eb621be071806663", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1704842529, + "narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat_3", + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs_3", + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1708018599, + "narHash": "sha256-M+Ng6+SePmA8g06CmUZWi1AjG2tFBX9WCXElBHEKnyM=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "flake-parts": "flake-parts", + "kubenix": "kubenix", + "nixpkgs": "nixpkgs_2", + "pre-commit-hooks": "pre-commit-hooks", + "systems": "systems_3" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "id": "systems", + "type": "indirect" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "treefmt": { + "inputs": { + "nixpkgs": [ + "kubenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688026376, + "narHash": "sha256-qJmkr9BWDpqblk4E9/rCsAEl39y2n4Ycw6KRopvpUcY=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "df3f32b0cc253dfc7009b7317e8f0e7ccd70b1cf", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..2019f6b --- /dev/null +++ b/flake.nix @@ -0,0 +1,88 @@ +{ + outputs = { + self, + flake-parts, + systems, + ... + } @ inputs: + flake-parts.lib.mkFlake {inherit inputs;} { + imports = [ + inputs.devenv.flakeModule + ]; + systems = import systems; + flake = rec { + utils = import ./lib { + inherit (inputs.nixpkgs) lib; + inherit inputs; + }; + + # █▄░█ █ ▀▄▀ █░░ █▀▀ ▀█▀ █▀ + # █░▀█ █ █░█ █▄▄ ██▄ ░█░ ▄█ + nixlets = { + # = utils.mkNixlet ./nixlets/; + }; + }; + perSystem = { + pkgs, + system, + inputs', + ... + }: { + formatter = pkgs.alejandra; + devenv.shells.default = { + containers = pkgs.lib.mkForce {}; + packages = with pkgs; [ + kube-linter + ]; + + pre-commit = { + hooks = { + alejandra.enable = true; + }; + }; + }; + + # check if every nixlet successfully renders with default values + checks = + builtins.mapAttrs ( + name: nixlet: + self.utils.renderNixlet { + inherit system nixlet; + project = name; + values = {}; + } + ) + self.nixlets; + + # allow directly building every nixlet with default values + packages = + builtins.mapAttrs ( + name: nixlet: + self.utils.renderNixlet { + inherit system nixlet; + project = name; + values = {}; + } + ) + self.nixlets; + }; + }; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + # flake & devenv related + flake-parts.url = "github:hercules-ci/flake-parts"; + systems.url = "github:nix-systems/default-linux"; + devenv = { + url = "github:cachix/devenv"; + inputs.pre-commit-hooks.follows = "pre-commit-hooks"; + }; + pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + + kubenix = { + url = "github:hall/kubenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; +} diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 0000000..55b1b30 --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,79 @@ +{ + inputs, + lib, + ... +} @ attrs: +with lib; { + mkValues = file: {rawValues, ...} @ args: + (lib.evalModules { + specialArgs = { + utils = import ./. attrs; + }; + modules = [ + file + ({...}: { + # pass through all args to the values.nix module + config = + rawValues + // { + _module.args = args; + }; + }) + ]; + }) + .config; + + mkNestedOption = options: + mkOption { + type = types.submodule { + inherit options; + }; + default = {}; + }; + + mkNixlet = path: let + utils = import ./. attrs; + in + { + rawValues, + project, + ... + } @ args: { + kubenix, + lib, + ... + } @ attrs: let + values = utils.mkValues "${path}/values.nix" args; + in { + imports = [path]; + # make values accessible from every imported file + _module.args = {inherit values;}; + }; + + renderNixlet = { + system, + project, + nixlet, + values, + overrides ? {...}: {}, + }: + (inputs.kubenix.evalModules.${system} { + module = {kubenix, ...}: { + imports = with kubenix.modules; [ + k8s + helm + docker + (nixlet { + # all these args are available in values.nix + inherit project; + rawValues = values; + }) + overrides + ]; + kubenix.project = project; + }; + }) + .config + .kubernetes + .resultYAML; +} diff --git a/template/default.nix b/template/default.nix new file mode 100644 index 0000000..86a8395 --- /dev/null +++ b/template/default.nix @@ -0,0 +1,8 @@ +{values, ...}: { + imports = [ + # import other files here + ]; + kubernetes.resources = { + # define Kubernetes resources here + }; +} diff --git a/template/values.nix b/template/values.nix new file mode 100644 index 0000000..747f57d --- /dev/null +++ b/template/values.nix @@ -0,0 +1,11 @@ +{ + lib, + utils, + ... +}: +with lib; { + # for some basic values see https://github.com/helm/examples/blob/4888ba8fb8180dd0c36d1e84c1fcafc6efd81532/charts/hello-world/values.yaml + options = { + # define values here + }; +}