init
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/target
|
||||||
|
/.direnv
|
||||||
|
/result
|
||||||
36
.sops.yaml
Normal file
36
.sops.yaml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
keys:
|
||||||
|
- &laptop-laptop age1z9h9dsza2uj3gu795w99r4ze976e0pedc9m00qf6qmw3js5edy7s5qrk28
|
||||||
|
- &laptop-laptop-home age1cadp26evf04t7hjrk3yqn05hl72kwv5luzc6mc096rsf2jac3dvsmka8xp
|
||||||
|
- &laptop-linux age1rqlpv63rkjkty3np7ksagwlq6fkx35x7tq6tmrdxk0ue205dmguqg79sq7
|
||||||
|
- &server-old-server-old age18zntyz5vjf8eky95xmm27qct53prrt2pkjst5fgj9h959n20e9tskhf3pt
|
||||||
|
- &server-server age1pxw0y3z2n5gj0s07hacvr48yvlhhgnfxsnpj958cy823j05eu9sqgm2hjr
|
||||||
|
- &wawa-wawa age14l694p4kht0d5vr72vvw6d9gvynq0dpm5lmqf6ugwv3dkf09w5qsrz0v6v
|
||||||
|
- &wawa-wawa-home age1rsczygcq6kqvfc2c5yqw5plw35r6vey8r2n9qm42q744u38auesssu6vx7
|
||||||
|
- &raspi-raspi age1d290xw09nkdv6fmenst8sp9uyeppkn2dg9yh4yh2d35gnxfvl45qs4up96
|
||||||
|
- &bhyve-vm-bhyve-vm1 age1gw58chzlp0yxfmadkp7d5m4qveqqm6ysws39qekwlren9snu830s98axw3
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: secrets/.+\.(yaml|json|env|ini|bin)$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *laptop-laptop
|
||||||
|
- *laptop-laptop-home
|
||||||
|
- *laptop-linux
|
||||||
|
- *wawa-wawa
|
||||||
|
- *wawa-wawa-home
|
||||||
|
- *raspi-raspi
|
||||||
|
- *server-server
|
||||||
|
- *server-old-server-old
|
||||||
|
- *bhyve-vm-bhyve-vm1
|
||||||
|
|
||||||
|
- path_regex: secrets/.+\.(yaml|json|env|ini|bin)$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *laptop-laptop
|
||||||
|
- *laptop-laptop-home
|
||||||
|
- *laptop-linux
|
||||||
|
- *wawa-wawa
|
||||||
|
- *wawa-wawa-home
|
||||||
|
- *raspi-raspi
|
||||||
|
- *server-server
|
||||||
|
- *server-old-server-old
|
||||||
|
- *bhyve-vm-bhyve-vm1
|
||||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1768135262,
|
||||||
|
"narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1758198701,
|
||||||
|
"narHash": "sha256-7To75JlpekfUmdkUZewnT6MoBANS0XVypW6kjUOXQwc=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "0147c2f1d54b30b5dd6d4a8c8542e8d7edf93b5d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1765674936,
|
||||||
|
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
89
flake.nix
Normal file
89
flake.nix
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
description = "A very basic flake";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
||||||
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
|
||||||
|
# crane.url = "github:ipetkov/crane";
|
||||||
|
# flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
# rust-overlay = {
|
||||||
|
# url = "github:oxalica/rust-overlay";
|
||||||
|
# inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
outputs =
|
||||||
|
{ flake-parts, ... }@inputs:
|
||||||
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
|
flake.flakeModules.default = ./nix/flakeModule.nix;
|
||||||
|
};
|
||||||
|
|
||||||
|
# outputs =
|
||||||
|
# {
|
||||||
|
# nixpkgs,
|
||||||
|
# crane,
|
||||||
|
# flake-utils,
|
||||||
|
# rust-overlay,
|
||||||
|
# ...
|
||||||
|
# }:
|
||||||
|
# flake-utils.lib.eachDefaultSystem (
|
||||||
|
# system:
|
||||||
|
# let
|
||||||
|
# pkgs = import nixpkgs {
|
||||||
|
# inherit system;
|
||||||
|
# overlays = [
|
||||||
|
# (import rust-overlay)
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
|
# inherit (pkgs) lib;
|
||||||
|
#
|
||||||
|
# craneLib = (crane.mkLib pkgs).overrideToolchain (
|
||||||
|
# p:
|
||||||
|
# p.rust-bin.nightly.latest.default.override {
|
||||||
|
# extensions = [
|
||||||
|
# "rustc-codegen-cranelift-preview"
|
||||||
|
# "rust-analyzer"
|
||||||
|
# "rust-src"
|
||||||
|
# ];
|
||||||
|
# }
|
||||||
|
# );
|
||||||
|
# src = craneLib.cleanCargoSource ./.;
|
||||||
|
# commonArgs = {
|
||||||
|
# inherit src;
|
||||||
|
# strictDeps = true;
|
||||||
|
# };
|
||||||
|
# cargoArtifacts = craneLib.buildDepsOnly commonArgs;
|
||||||
|
# individualCrateArgs = commonArgs // {
|
||||||
|
# inherit cargoArtifacts;
|
||||||
|
# inherit (craneLib.crateNameFromCargoToml { inherit src; }) version;
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# fileSetForCrate =
|
||||||
|
# crate:
|
||||||
|
# lib.fileset.toSource {
|
||||||
|
# root = ./.;
|
||||||
|
# fileset = lib.fileset.unions [
|
||||||
|
# ./Cargo.toml
|
||||||
|
# ./Cargo.lock
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
|
# server = craneLib.buildPackage (
|
||||||
|
# individualCrateArgs
|
||||||
|
# // {
|
||||||
|
# }
|
||||||
|
# );
|
||||||
|
# in
|
||||||
|
# {
|
||||||
|
# devShells.default = craneLib.devShell {
|
||||||
|
# packages = with pkgs; [
|
||||||
|
# mold
|
||||||
|
# llvmPackages.clang
|
||||||
|
# llvmPackages.lld
|
||||||
|
# sea-orm-cli
|
||||||
|
# watchexec
|
||||||
|
# pnpm
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
|
# }
|
||||||
|
# );
|
||||||
|
}
|
||||||
149
nix/flakeModule.nix
Normal file
149
nix/flakeModule.nix
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
flake-parts-lib,
|
||||||
|
inputs,
|
||||||
|
den,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
cfg = config.secrets;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.secrets = {
|
||||||
|
masterKeys = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "A list of master keys for encrypting secrets.";
|
||||||
|
};
|
||||||
|
secretsDir = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Path to the directory containing secrets relative to flake root.";
|
||||||
|
};
|
||||||
|
formatter = mkOption {
|
||||||
|
type = lib.types.functionTo lib.types.unspecified;
|
||||||
|
default = pkgs: pkgs.prettier;
|
||||||
|
description = "The formatter function to use for formatting sops file";
|
||||||
|
};
|
||||||
|
nixosModule = mkOption {
|
||||||
|
type = types.deferredModule;
|
||||||
|
readOnly = true;
|
||||||
|
description = "NixOS module configuration for managing sops secrets.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
secrets = builtins.fromJSON (builtins.readFile "${inputs.self}/${cfg.secretsDir}/secrets.json");
|
||||||
|
all_keys = lib.flatten (lib.concatAttrValues per_host_keys);
|
||||||
|
per_host_keys = lib.mergeAttrsList (
|
||||||
|
lib.flatten (
|
||||||
|
map (
|
||||||
|
x:
|
||||||
|
builtins.mapAttrs (
|
||||||
|
name: value:
|
||||||
|
let
|
||||||
|
v = value.sopsPublic or [ ];
|
||||||
|
type = builtins.typeOf v;
|
||||||
|
vv =
|
||||||
|
if type == "string" then
|
||||||
|
[ v ]
|
||||||
|
else if type == "list" then
|
||||||
|
v
|
||||||
|
else
|
||||||
|
throw "Unexpected type ${type} for sopsPublic in host ${name}";
|
||||||
|
in
|
||||||
|
vv
|
||||||
|
) x
|
||||||
|
) (builtins.attrValues den.hosts)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
secret_map = lib.mapAttrs (
|
||||||
|
name: value:
|
||||||
|
let
|
||||||
|
keys = lib.unique (
|
||||||
|
lib.flatten (map (k: per_host_keys.${k}) value.hosts)
|
||||||
|
++ (lib.optionals value.global all_keys)
|
||||||
|
++ cfg.masterKeys
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit (value)
|
||||||
|
format
|
||||||
|
neededForUsers
|
||||||
|
hosts
|
||||||
|
global
|
||||||
|
;
|
||||||
|
inherit keys;
|
||||||
|
}
|
||||||
|
) secrets;
|
||||||
|
rules = lib.mapAttrsToList (name: value: {
|
||||||
|
path_regex = "${cfg.secretsDir}/${name}$";
|
||||||
|
key_groups = [ { age = value.keys; } ];
|
||||||
|
}) secret_map;
|
||||||
|
sops_secrets_map = lib.concatMapAttrs (
|
||||||
|
name: value:
|
||||||
|
let
|
||||||
|
hasHost = (lib.elem "wawa" value.hosts) || value.global;
|
||||||
|
in
|
||||||
|
if hasHost then
|
||||||
|
{
|
||||||
|
${name} = {
|
||||||
|
inherit (value) format neededForUsers;
|
||||||
|
sopsFile = inputs.self + "/${cfg.secretsDir}/${name}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ }
|
||||||
|
) secret_map;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
secrets.nixosModule =
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
config.sops.secrets = sops_secrets_map;
|
||||||
|
};
|
||||||
|
perSystem =
|
||||||
|
{ pkgs, self', ... }:
|
||||||
|
let
|
||||||
|
formatted =
|
||||||
|
let
|
||||||
|
unformatted = (pkgs.formats.yaml { }).generate ".sops.yaml" {
|
||||||
|
creation_rules = rules;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
name = ".sops-yaml-formatted";
|
||||||
|
src = unformatted;
|
||||||
|
phases = [ "format" ];
|
||||||
|
format = ''
|
||||||
|
cp $src .sops.yaml
|
||||||
|
chmod +w .sops.yaml
|
||||||
|
${lib.getExe (cfg.formatter pkgs)} .sops.yaml
|
||||||
|
cp .sops.yaml $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
packages.write-sops-config = pkgs.writeShellApplication {
|
||||||
|
name = "write-sops-config";
|
||||||
|
text = ''
|
||||||
|
cp ${formatted} .sops.yaml
|
||||||
|
find ${cfg.secretsDir} -type f ! -name "secrets.json" -exec ${pkgs.lib.getExe pkgs.sops} updatekeys -y {} \;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
checks.check-sops-config =
|
||||||
|
pkgs.runCommand "check-sops-config"
|
||||||
|
{
|
||||||
|
nativeBuildInputs = [ pkgs.diffutils ];
|
||||||
|
}
|
||||||
|
''
|
||||||
|
set -e
|
||||||
|
diff -u ${inputs.self}/.sops.yaml ${formatted}
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
14
treefmt.nix
Normal file
14
treefmt.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{ rust-toolchain }:
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
# Used to find the project root
|
||||||
|
projectRootFile = "flake.nix";
|
||||||
|
# Enable the terraform formatter
|
||||||
|
programs = {
|
||||||
|
nixfmt.enable = true;
|
||||||
|
rustfmt.enable = true;
|
||||||
|
rustfmt.package = rust-toolchain pkgs;
|
||||||
|
leptosfmt.enable = true;
|
||||||
|
taplo.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user