Compare commits
12 commits
main
...
feature/ni
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9aaf0f0a2b | ||
|
|
5d8c897b4d | ||
|
|
3a6672cad9 | ||
|
|
69c6d85754 | ||
|
|
de1bc287d5 | ||
|
|
4bd4327a6d | ||
|
|
7e6beb208d | ||
|
|
cfb9d086b8 | ||
|
|
a1316fdf0e | ||
|
|
98362802d5 | ||
|
|
3921693f84 | ||
|
|
8228418b7f |
76 changed files with 661 additions and 4354 deletions
2
.envrc
2
.envrc
|
|
@ -1,2 +0,0 @@
|
||||||
# shellcheck shell=bash
|
|
||||||
use flake
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
name: Test action
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
kaas:
|
|
||||||
runs-on: nix
|
|
||||||
steps:
|
|
||||||
- name: Echo
|
|
||||||
run: |
|
|
||||||
nix --version
|
|
||||||
4
.gitattributes
vendored
4
.gitattributes
vendored
|
|
@ -1,4 +0,0 @@
|
||||||
* text=auto
|
|
||||||
core.autocrlf=false
|
|
||||||
core.eol=lf
|
|
||||||
core.filemode=false
|
|
||||||
8
.gitignore
vendored
8
.gitignore
vendored
|
|
@ -1,8 +1,2 @@
|
||||||
# ---> Nix
|
|
||||||
# Ignore build outputs from performing a nix-build or `nix build` command
|
|
||||||
result
|
result
|
||||||
result-*
|
*.qcow2
|
||||||
|
|
||||||
# Ignore automatically generated direnv output
|
|
||||||
.direnv
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
def RESET: "0";
|
|
||||||
def BOLD: "1";
|
|
||||||
def DIM: "2";
|
|
||||||
def ITALIC: "3";
|
|
||||||
def UNDERLINE: "4";
|
|
||||||
def BLINKING: "5";
|
|
||||||
def INVERSE: "7";
|
|
||||||
def HIDDEN: "8";
|
|
||||||
def STRIKETHROUGH: "9";
|
|
||||||
def RESET_FONT: "22";
|
|
||||||
|
|
||||||
def BLACK: 0;
|
|
||||||
def RED: 1;
|
|
||||||
def GREEN: 2;
|
|
||||||
def YELLOW: 3;
|
|
||||||
def BLUE: 4;
|
|
||||||
def MAGENTA: 5;
|
|
||||||
def CYAN: 6;
|
|
||||||
def WHITE: 7;
|
|
||||||
def DEFAULT: 9;
|
|
||||||
|
|
||||||
def foreground(color): 30 + color;
|
|
||||||
def background(color): 40 + color;
|
|
||||||
def bright(color): 60 + color;
|
|
||||||
|
|
||||||
def escape(options):
|
|
||||||
(if ((options|type) == "array") then options else [options] end) as $o
|
|
||||||
| "\u001b[\($o | map(tostring) | join(";"))m";
|
|
||||||
|
|
||||||
def style(options): escape(options) + . + escape([RESET]);
|
|
||||||
|
|
||||||
def to_title:
|
|
||||||
(.|ascii_upcase) as $str
|
|
||||||
| escape([BOLD, foreground(BLACK), background(WHITE)]) + " " + $str + " " + escape([RESET]);
|
|
||||||
59
.jq/table.jq
59
.jq/table.jq
|
|
@ -1,59 +0,0 @@
|
||||||
import "format" as _ {search:"./"};
|
|
||||||
|
|
||||||
def n_max(limit):
|
|
||||||
if . > limit then limit else . end;
|
|
||||||
|
|
||||||
def n_min(limit):
|
|
||||||
if . < limit then limit else . end;
|
|
||||||
|
|
||||||
def pad_right(width):
|
|
||||||
(. | tostring) as $s
|
|
||||||
| ($s | length) as $l
|
|
||||||
| ((width - $l) | n_min(0)) as $w
|
|
||||||
| ($s + (" " * $w));
|
|
||||||
|
|
||||||
def to_cells(sizes; fn):
|
|
||||||
to_entries
|
|
||||||
| map(
|
|
||||||
(sizes[.key]) as $size
|
|
||||||
| (" " + .value)
|
|
||||||
| pad_right($size + 2)
|
|
||||||
| fn // .
|
|
||||||
);
|
|
||||||
|
|
||||||
def to_cells(sizes): to_cells(sizes; null);
|
|
||||||
|
|
||||||
def to_line(left; joiner; right):
|
|
||||||
[left, .[1], (.[1:] | map([joiner, .]) ), right] | flatten | join("");
|
|
||||||
|
|
||||||
def create(data; header_callback; cell_callback):
|
|
||||||
(data[0] | to_entries | map(.key)) as $keys
|
|
||||||
| ([$keys]) as $header
|
|
||||||
| (data | map(to_entries | map(.value))) as $rows
|
|
||||||
| ($header + $rows) as $cells
|
|
||||||
| (
|
|
||||||
$keys # Use keys so that we have an array of the correct size
|
|
||||||
| to_entries
|
|
||||||
| map(
|
|
||||||
(.key) as $i
|
|
||||||
| $cells
|
|
||||||
| map(.[$i] | length)
|
|
||||||
| max
|
|
||||||
)
|
|
||||||
) as $column_sizes
|
|
||||||
| (
|
|
||||||
[
|
|
||||||
($column_sizes | map("═" * (. + 2)) | to_line("╔"; "╤"; "╗")),
|
|
||||||
($keys | to_cells($column_sizes; header_callback) | to_line("║"; "│"; "║")),
|
|
||||||
($rows | map([
|
|
||||||
($column_sizes | map("─" * (. + 2)) | to_line("╟"; "┼"; "╢")),
|
|
||||||
(. | to_cells($column_sizes; cell_callback) | to_line("║"; "│"; "║"))
|
|
||||||
])),
|
|
||||||
($column_sizes | map("═" * (. + 2)) | to_line("╚"; "╧"; "╝"))
|
|
||||||
]
|
|
||||||
| flatten
|
|
||||||
| join("\n")
|
|
||||||
);
|
|
||||||
|
|
||||||
def create(data; header_callback): create(data; header_callback; null);
|
|
||||||
def create(data): create(data; _::style(_::BOLD); null);
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
@_default: list
|
|
||||||
|
|
||||||
[doc('List machines')]
|
|
||||||
@list:
|
|
||||||
ls -1 ../systems/x86_64-linux/
|
|
||||||
|
|
||||||
[doc('Update the target machine')]
|
|
||||||
[no-exit-message]
|
|
||||||
@update machine:
|
|
||||||
just assert '-d "../systems/x86_64-linux/{{ machine }}"' "Machine {{ machine }} does not exist, must be one of: $(ls ../systems/x86_64-linux/ | sed ':a;N;$!ba;s/\n/, /g')"
|
|
||||||
nixos-rebuild switch -L --sudo --target-host {{ machine }} --flake ..#{{ machine }}
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
set unstable := true
|
|
||||||
set quiet := true
|
|
||||||
|
|
||||||
_default:
|
|
||||||
just --list
|
|
||||||
|
|
||||||
[script]
|
|
||||||
list:
|
|
||||||
cd .. && just vars get ulmo zitadel/users | jq -r -C '
|
|
||||||
import ".jq/table" as table;
|
|
||||||
import ".jq/format" as f;
|
|
||||||
|
|
||||||
fromjson
|
|
||||||
| to_entries
|
|
||||||
| sort_by(.key)
|
|
||||||
| map(
|
|
||||||
(.key|f::to_title) + ":\n"
|
|
||||||
+ table::create(
|
|
||||||
.value
|
|
||||||
| to_entries
|
|
||||||
| sort_by(.key)
|
|
||||||
| map({username:.key} + .value)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
| join("\n\n┄┄┄\n\n")
|
|
||||||
';
|
|
||||||
|
|
||||||
[script]
|
|
||||||
add:
|
|
||||||
exec 5>&1
|
|
||||||
|
|
||||||
pad () { [ "$#" -gt 1 ] && [ -n "$2" ] && printf "%$2.${2#-}s" "$1"; }
|
|
||||||
|
|
||||||
input() {
|
|
||||||
local label=$1
|
|
||||||
local value=$2
|
|
||||||
|
|
||||||
local res=$(gum input --header "$label" --value "$value")
|
|
||||||
echo -e "\e[2m$(pad "$label" -11)\e[0m$res" >&5
|
|
||||||
echo $res
|
|
||||||
}
|
|
||||||
|
|
||||||
data=`cd .. && just vars get ulmo zitadel/users | jq 'fromjson'`
|
|
||||||
|
|
||||||
# Gather inputs
|
|
||||||
org=`
|
|
||||||
jq -r 'to_entries | map(.key)[]' <<< "$data" \
|
|
||||||
| gum choose --header 'Which organisation to save to?' --select-if-one
|
|
||||||
`
|
|
||||||
username=`input 'user name' 'new-user'`
|
|
||||||
email=`input 'email' 'new.user@example.com'`
|
|
||||||
first_name=`input 'first name' 'John'`
|
|
||||||
last_name=`input 'last name' 'Doe'`
|
|
||||||
|
|
||||||
user_exists=`jq --arg 'org' "$org" --arg 'username' "$username" '.[$org][$username]? | . != null' <<< "$data"`
|
|
||||||
|
|
||||||
if [ "$user_exists" == "true" ]; then
|
|
||||||
gum confirm 'User already exists, overwrite it?' --padding="1 1" || exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
next=`
|
|
||||||
jq \
|
|
||||||
--arg 'org' "$org" \
|
|
||||||
--arg 'username' "$username" \
|
|
||||||
--arg 'email' "$email" \
|
|
||||||
--arg 'first_name' "$first_name" \
|
|
||||||
--arg 'last_name' "$last_name" \
|
|
||||||
--compact-output \
|
|
||||||
'.[$org] += { $username: { email: $email, firstName: $first_name, lastName: $last_name } }' \
|
|
||||||
<<< $data
|
|
||||||
`
|
|
||||||
|
|
||||||
gum spin --title "saving..." -- echo "$(cd .. && just vars set ulmo 'zitadel/users' "$next")"
|
|
||||||
|
|
||||||
[script]
|
|
||||||
remove:
|
|
||||||
data=`cd .. && just vars get ulmo zitadel/users | jq fromjson`
|
|
||||||
|
|
||||||
# Gather inputs
|
|
||||||
org=`
|
|
||||||
jq -r 'to_entries | map(.key)[]' <<< "$data" \
|
|
||||||
| gum choose --header 'Which organisation?' --select-if-one
|
|
||||||
`
|
|
||||||
user=`
|
|
||||||
jq -r --arg org "$org" '.[$org] | to_entries | map(.key)[]' <<< "$data" \
|
|
||||||
| gum choose --header 'Which user?' --select-if-one
|
|
||||||
`
|
|
||||||
|
|
||||||
next=`
|
|
||||||
jq \
|
|
||||||
--arg 'org' "$org" \
|
|
||||||
--arg 'user' "$user" \
|
|
||||||
--compact-output \
|
|
||||||
'del(.[$org][$user])' \
|
|
||||||
<<< $data
|
|
||||||
`
|
|
||||||
|
|
||||||
gum spin --title "saving..." -- echo "$(cd .. && just vars set ulmo 'zitadel/users' "$next")"
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
set unstable := true
|
|
||||||
set quiet := true
|
|
||||||
|
|
||||||
base_path := invocation_directory() / "systems/x86_64-linux"
|
|
||||||
|
|
||||||
_default:
|
|
||||||
just --list
|
|
||||||
|
|
||||||
[doc('list all vars of the target machine')]
|
|
||||||
list machine:
|
|
||||||
sops decrypt {{ base_path }}/{{ machine }}/secrets.yml
|
|
||||||
|
|
||||||
edit machine:
|
|
||||||
sops edit {{ base_path }}/{{ machine }}/secrets.yml
|
|
||||||
|
|
||||||
@set machine key value:
|
|
||||||
sops set {{ base_path }}/{{ machine }}/secrets.yml "$(printf '%s\n' '["{{ key }}"]' | sed -E 's#/#"]["#g; s/\["([0-9]+)"\]/[\1]/g')" "\"$(echo '{{ value }}' | sed 's/\"/\\\"/g')\""
|
|
||||||
|
|
||||||
git add {{ base_path }}/{{ machine }}/secrets.yml
|
|
||||||
git commit -m 'chore(secrets): set secret "{{ key }}" for machine "{{ machine }}"' -- {{ base_path }}/{{ machine }}/secrets.yml > /dev/null
|
|
||||||
|
|
||||||
echo "Done"
|
|
||||||
|
|
||||||
get machine key:
|
|
||||||
sops decrypt {{ base_path }}/{{ machine }}/secrets.yml | yq ".$(echo "{{ key }}" | sed -E 's/\//./g')"
|
|
||||||
|
|
||||||
remove machine key:
|
|
||||||
sops unset {{ base_path }}/{{ machine }}/secrets.yml "$(printf '%s\n' '["{{ key }}"]' | sed -E 's#/#"]["#g; s/\["([0-9]+)"\]/[\1]/g')"
|
|
||||||
|
|
||||||
git add {{ base_path }}/{{ machine }}/secrets.yml
|
|
||||||
git commit -m 'chore(secrets): removed secret "{{ key }}" from machine "{{ machine }}"' -- {{ base_path }}/{{ machine }}/secrets.yml > /dev/null
|
|
||||||
|
|
||||||
echo "Done"
|
|
||||||
36
.justfile
36
.justfile
|
|
@ -1,36 +0,0 @@
|
||||||
@_default:
|
|
||||||
just --list --list-submodules
|
|
||||||
|
|
||||||
[doc('Manage vars')]
|
|
||||||
mod vars '.just/vars.just'
|
|
||||||
|
|
||||||
[doc('Manage users')]
|
|
||||||
mod users '.just/users.just'
|
|
||||||
|
|
||||||
[doc('Manage machines')]
|
|
||||||
mod machine '.just/machine.just'
|
|
||||||
|
|
||||||
[doc('Show information about project')]
|
|
||||||
@show:
|
|
||||||
echo "show"
|
|
||||||
|
|
||||||
[doc('update the flake dependencies')]
|
|
||||||
@update:
|
|
||||||
nix flake update
|
|
||||||
git commit -m 'chore: update dependencies' -- ./flake.lock > /dev/null
|
|
||||||
echo "Done"
|
|
||||||
|
|
||||||
[doc('Introspection on flake output')]
|
|
||||||
@select key:
|
|
||||||
nix eval --show-trace --json .#{{ key }} | jq .
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#===============================================================================================
|
|
||||||
# Utils
|
|
||||||
#===============================================================================================
|
|
||||||
[no-exit-message]
|
|
||||||
[no-cd]
|
|
||||||
[private]
|
|
||||||
@assert condition message:
|
|
||||||
[ {{ condition }} ] || { echo -e 1>&2 "\n\x1b[1;41m Error \x1b[0m {{ message }}\n"; exit 1; }
|
|
||||||
11
.sops.yaml
11
.sops.yaml
|
|
@ -1,11 +0,0 @@
|
||||||
keys:
|
|
||||||
- &ulmo_1 age19qfpf980tadguqq44zf6xwvjvl428dyrj46ha3n6aeqddwhtnuqqml7etq
|
|
||||||
- &ulmo_2 age1ewes0f5snqx3sh5ul6fa6qtxzhd25829v6mf5rx2wnheat6fefps5rme2x
|
|
||||||
|
|
||||||
creation_rules:
|
|
||||||
# All Machine secrets
|
|
||||||
- path_regex: systems/[^/]+/[^/]+/[^/]+\.(yml|yaml)$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *ulmo_1
|
|
||||||
- *ulmo_2
|
|
||||||
57
.sops.yml
Normal file
57
.sops.yml
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
keys:
|
||||||
|
- home:
|
||||||
|
- &chris age1ewes0f5snqx3sh5ul6fa6qtxzhd25829v6mf5rx2wnheat6fefps5rme2x
|
||||||
|
- system:
|
||||||
|
- &aule age
|
||||||
|
- &mandos age
|
||||||
|
- &manwe age10c5hmykkduvy75yvqfnchm5lcesr5puarhkwp4l7xdwpykdm397q6xdxuy
|
||||||
|
- &melkor age
|
||||||
|
- &orome age
|
||||||
|
- &tulkas age
|
||||||
|
- &varda age
|
||||||
|
- &yavanna age1ewes0f5snqx3sh5ul6fa6qtxzhd25829v6mf5rx2wnheat6fefps5rme2x
|
||||||
|
|
||||||
|
creation_rules:
|
||||||
|
#===================================================================
|
||||||
|
# HOSTS
|
||||||
|
#===================================================================
|
||||||
|
- path_regex: systems/x86_64-linux/aule/secrets.yaml$
|
||||||
|
age: *aule
|
||||||
|
|
||||||
|
- path_regex: systems/x86_64-linux/mandos/secrets.yaml$
|
||||||
|
age: *mandos
|
||||||
|
|
||||||
|
- path_regex: systems/x86_64-linux/manwe/secrets.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *manwe
|
||||||
|
- *yavanna
|
||||||
|
|
||||||
|
- path_regex: systems/x86_64-linux/melkor/secrets.yaml$
|
||||||
|
age: *melkor
|
||||||
|
|
||||||
|
- path_regex: systems/x86_64-linux/orome/secrets.yaml$
|
||||||
|
age: *orome
|
||||||
|
|
||||||
|
- path_regex: systems/x86_64-linux/tulkas/secrets.yaml$
|
||||||
|
age: *tulkas
|
||||||
|
|
||||||
|
- path_regex: systems/x86_64-linux/varda/secrets.yaml$
|
||||||
|
age: *varda
|
||||||
|
|
||||||
|
- path_regex: systems/x86_64-linux/yavanna/secrets.yaml$
|
||||||
|
age: *yavanna
|
||||||
|
|
||||||
|
#===================================================================
|
||||||
|
# USERS
|
||||||
|
#===================================================================
|
||||||
|
- path_regex: homes/x86_64-linux/chris@\w+/secrets.yaml$
|
||||||
|
age: *chris
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -18,4 +18,5 @@ nix build .#install-isoConfigurations.minimal
|
||||||
|
|
||||||
- [dafitt/dotfiles](https://github.com/dafitt/dotfiles/)
|
- [dafitt/dotfiles](https://github.com/dafitt/dotfiles/)
|
||||||
- [khaneliman/khanelinix](https://github.com/khaneliman/khanelinix)
|
- [khaneliman/khanelinix](https://github.com/khaneliman/khanelinix)
|
||||||
|
- [alex007sirois/nix-config](https://github.com/alex007sirois/nix-config) (justfile)
|
||||||
- [hmajid2301/nixicle](https://gitlab.com/hmajid2301/nixicle) (the GOAT, he did what I am aiming for!)
|
- [hmajid2301/nixicle](https://gitlab.com/hmajid2301/nixicle) (the GOAT, he did what I am aiming for!)
|
||||||
659
flake.lock
generated
659
flake.lock
generated
File diff suppressed because it is too large
Load diff
121
flake.nix
121
flake.nix
|
|
@ -9,6 +9,11 @@
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
disko = {
|
||||||
|
url = "github:nix-community/disko";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
home-manager = {
|
home-manager = {
|
||||||
url = "github:nix-community/home-manager";
|
url = "github:nix-community/home-manager";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
@ -24,14 +29,14 @@
|
||||||
url = "github:nix-community/nixos-generators";
|
url = "github:nix-community/nixos-generators";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
# neovim
|
nixos-wsl = {
|
||||||
nvf.url = "github:notashelf/nvf";
|
url = "github:nix-community/nixos-wsl";
|
||||||
|
inputs = {
|
||||||
# plymouth theme
|
nixpkgs.follows = "nixpkgs";
|
||||||
nixos-boot.url = "github:Melkor333/nixos-boot";
|
flake-compat.follows = "";
|
||||||
|
};
|
||||||
firefox.url = "github:nix-community/flake-firefox-nightly";
|
};
|
||||||
|
|
||||||
stylix.url = "github:nix-community/stylix";
|
stylix.url = "github:nix-community/stylix";
|
||||||
|
|
||||||
|
|
@ -41,10 +46,13 @@
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
zen-browser = {
|
# neovim
|
||||||
url = "github:0xc000022070/zen-browser-flake";
|
nvf.url = "github:notashelf/nvf";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
# plymouth theme
|
||||||
|
nixos-boot.url = "github:Melkor333/nixos-boot";
|
||||||
|
|
||||||
|
zen-browser.url = "github:MarceColl/zen-browser-flake";
|
||||||
|
|
||||||
nix-minecraft.url = "github:Infinidoge/nix-minecraft";
|
nix-minecraft.url = "github:Infinidoge/nix-minecraft";
|
||||||
|
|
||||||
|
|
@ -66,77 +74,42 @@
|
||||||
url = "github:Jovian-Experiments/Jovian-NixOS";
|
url = "github:Jovian-Experiments/Jovian-NixOS";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
grub2-themes = {
|
grub2-themes = {
|
||||||
url = "github:vinceliuice/grub2-themes";
|
url = "github:vinceliuice/grub2-themes";
|
||||||
};
|
};
|
||||||
|
|
||||||
nixos-wsl = {
|
|
||||||
url = "github:nix-community/nixos-wsl";
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.follows = "nixpkgs";
|
|
||||||
flake-compat.follows = "";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
terranix = {
|
|
||||||
url = "github:terranix/terranix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
clan-core = {
|
|
||||||
url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
mydia = {
|
|
||||||
url = "github:chris-kruining/mydia";
|
|
||||||
# url = "github:getmydia/mydia";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs:
|
outputs = inputs: inputs.snowfall-lib.mkFlake {
|
||||||
inputs.snowfall-lib.mkFlake {
|
inherit inputs;
|
||||||
inherit inputs;
|
src = ./.;
|
||||||
src = ./.;
|
|
||||||
|
|
||||||
snowfall = {
|
snowfall = {
|
||||||
namespace = "sneeuwvlok";
|
namespace = "sneeuwvlok";
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
name = "sneeuwvlok";
|
name = "sneeuwvlok";
|
||||||
title = "Sneeuwvlok";
|
title = "Sneeuwvlok";
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
channels-config = {
|
channels-config = {
|
||||||
allowUnfree = true;
|
allowUnfree = true;
|
||||||
permittedInsecurePackages = [
|
permittedInsecurePackages = [
|
||||||
# Due to *arr stack
|
"dotnet-sdk-6.0.428"
|
||||||
"dotnet-sdk-6.0.428"
|
"aspnetcore-runtime-6.0.36"
|
||||||
"aspnetcore-runtime-6.0.36"
|
|
||||||
|
|
||||||
# I think this is because of zen
|
|
||||||
"qtwebengine-5.15.19"
|
|
||||||
|
|
||||||
# For Nheko, the matrix client
|
|
||||||
"olm-3.2.16"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
overlays = with inputs; [
|
|
||||||
fenix.overlays.default
|
|
||||||
nix-minecraft.overlay
|
|
||||||
flux.overlays.default
|
|
||||||
];
|
|
||||||
|
|
||||||
systems.modules = with inputs; [
|
|
||||||
clan-core.nixosModules.default
|
|
||||||
];
|
|
||||||
|
|
||||||
homes.modules = with inputs; [
|
|
||||||
stylix.homeModules.stylix
|
|
||||||
plasma-manager.homeModules.plasma-manager
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
overlays = with inputs; [
|
||||||
|
fenix.overlays.default
|
||||||
|
nix-minecraft.overlay
|
||||||
|
flux.overlays.default
|
||||||
|
];
|
||||||
|
|
||||||
|
homes.modules = with inputs; [
|
||||||
|
stylix.homeModules.stylix
|
||||||
|
plasma-manager.homeManagerModules.plasma-manager
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
{osConfig, ...}: {
|
{ osConfig, ... }:
|
||||||
|
{
|
||||||
home.stateVersion = osConfig.system.stateVersion;
|
home.stateVersion = osConfig.system.stateVersion;
|
||||||
|
|
||||||
programs.git = {
|
programs.git = {
|
||||||
settings.user = {
|
userName = "Chris Kruining";
|
||||||
name = "Chris Kruining";
|
userEmail = "chris@kruining.eu";
|
||||||
email = "chris@kruining.eu";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sneeuwvlok = {
|
sneeuwvlok = {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
{osConfig, ...}: {
|
{ osConfig, ... }:
|
||||||
|
{
|
||||||
home.stateVersion = osConfig.system.stateVersion;
|
home.stateVersion = osConfig.system.stateVersion;
|
||||||
|
|
||||||
programs.git = {
|
programs.git = {
|
||||||
settings.user = {
|
userName = "Chris Kruining";
|
||||||
name = "Chris Kruining";
|
userEmail = "chris@kruining.eu";
|
||||||
email = "chris@kruining.eu";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sneeuwvlok = {
|
sneeuwvlok = {
|
||||||
|
|
@ -36,7 +35,6 @@
|
||||||
bitwarden.enable = true;
|
bitwarden.enable = true;
|
||||||
discord.enable = true;
|
discord.enable = true;
|
||||||
ladybird.enable = true;
|
ladybird.enable = true;
|
||||||
matrix.enable = true;
|
|
||||||
obs.enable = true;
|
obs.enable = true;
|
||||||
onlyoffice.enable = true;
|
onlyoffice.enable = true;
|
||||||
signal.enable = true;
|
signal.enable = true;
|
||||||
|
|
|
||||||
21
homes/x86_64-linux/chris@manwe/secrets.yaml
Normal file
21
homes/x86_64-linux/chris@manwe/secrets.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
user_level_secrets: ENC[AES256_GCM,data:TNT+via+r4bpgROz,iv:cVO6/r4Aovr5uJFhU87mE5XwRJ518y4OJdHo4m92ahM=,tag:jYInD+euh7k1zSnMRppI5Q==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age1ewes0f5snqx3sh5ul6fa6qtxzhd25829v6mf5rx2wnheat6fefps5rme2x
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTYVRQTEVSMWM3WXY3eTdW
|
||||||
|
ZkUwSnNidlJwWGVETURpNUJRRUllYXo4WjNvCmxmN21qVzNFV3N4UVR6WEV1am1W
|
||||||
|
eW1KTk9HVDluek1BUnBmSGI3Y2ZqaDQKLS0tIHlMYldYMTVORVNWbEgrWlBSanRM
|
||||||
|
bUZiMHlOU3pxYUhQSTREb0l4TmFlOEkKiasV2H481aJzAvEAvyeWqGYDOW+WKRFX
|
||||||
|
yyocZDo0o1lHz/gNXoC0/ujU+O3rSXdsy6Qdz6Rm+xeFUfe4KoD4bg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2025-08-11T13:21:38Z"
|
||||||
|
mac: ENC[AES256_GCM,data:kfMcZuYuQqxxfqtyfH7DltSkq8YNz+vroB+ZQKTIpCNC/W6vJP1o23/xLRzdnEgnnH5GfgZQFAK8Am00/bUD2BgEPyXxXNf1lG70ocFbRM9htii92BFfHgfi25zlEqCO7yrudm1HEJyYrFbZnT63H6u1OgWSC38CzEZTBsCE0kU=,iv:feWGBau48s2GSvZjnKPfP2z46SBuHbh//4zzcLv+MTY=,tag:D86akwawLxobhEu2AvBFKg==,type:str]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.9.4
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
{osConfig, ...}: {
|
{ osConfig, ... }:
|
||||||
|
{
|
||||||
home.stateVersion = osConfig.system.stateVersion;
|
home.stateVersion = osConfig.system.stateVersion;
|
||||||
|
|
||||||
programs.git = {
|
programs.git = {
|
||||||
settings.user = {
|
userName = "Chris Kruining";
|
||||||
name = "Chris Kruining";
|
userEmail = "chris@kruining.eu";
|
||||||
email = "chris@kruining.eu";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sneeuwvlok = {
|
sneeuwvlok = {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
{osConfig, ...}: {
|
{ osConfig, ... }:
|
||||||
|
{
|
||||||
home.stateVersion = osConfig.system.stateVersion;
|
home.stateVersion = osConfig.system.stateVersion;
|
||||||
|
|
||||||
programs.git = {
|
programs.git = {
|
||||||
settings.user = {
|
userName = "Chris Kruining";
|
||||||
name = "Chris Kruining";
|
userEmail = "chris@kruining.eu";
|
||||||
email = "chris@kruining.eu";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sneeuwvlok = {
|
sneeuwvlok = {
|
||||||
|
|
|
||||||
24
justfile
Normal file
24
justfile
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
[private]
|
||||||
|
default:
|
||||||
|
@just -l
|
||||||
|
|
||||||
|
[doc('Update flake dependencies')]
|
||||||
|
update:
|
||||||
|
nix flake update
|
||||||
|
|
||||||
|
[doc('install nixos on a system (uses nix-anywhere)
|
||||||
|
> profile: Which profile to use
|
||||||
|
> host: How to reach the target system in the standard format of `user@host`
|
||||||
|
')]
|
||||||
|
install profile host:
|
||||||
|
nix run nixpkgs#nixos-anywhere -- \
|
||||||
|
--flake .#{{profile}} \
|
||||||
|
--generate-hardware-config nixos-generate-config ./hardware-configuration.nix \
|
||||||
|
{{host}}
|
||||||
|
|
||||||
|
[doc('builds the configuration for the host')]
|
||||||
|
build host:
|
||||||
|
nh os build . -H {{host}}
|
||||||
|
|
||||||
|
edit-secrets target:
|
||||||
|
sops --config "{{justfile_directory()}}/.sops.yml" edit "{{justfile_directory()}}/{{ if target =~ ".+@.+" { "homes" } else { "systems" } }}/x86_64-linux/{{target}}/secrets.yaml"
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
{ lib, ...}:
|
|
||||||
let
|
|
||||||
inherit (builtins) isString typeOf;
|
|
||||||
inherit (lib) mkOption types throwIfNot concatStringsSep splitStringBy toLower map;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
mkUrlOptions =
|
|
||||||
defaults:
|
|
||||||
{
|
|
||||||
host = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "host.tld";
|
|
||||||
description = ''
|
|
||||||
Hostname
|
|
||||||
'';
|
|
||||||
} // (defaults.host or {});
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 1234;
|
|
||||||
example = "1234";
|
|
||||||
description = ''
|
|
||||||
Port
|
|
||||||
'';
|
|
||||||
} // (defaults.port or {});
|
|
||||||
|
|
||||||
protocol = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "https";
|
|
||||||
example = "https";
|
|
||||||
description = ''
|
|
||||||
Which protocol to use when creating a url string
|
|
||||||
'';
|
|
||||||
} // (defaults.protocol or {});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
{ lib, ...}:
|
|
||||||
let
|
|
||||||
inherit (builtins) isString typeOf match toString head;
|
|
||||||
inherit (lib) throwIfNot concatStringsSep splitStringBy toLower map concatMapAttrsStringSep;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
strings = {
|
|
||||||
#========================================================================================
|
|
||||||
# Converts a string to snake case
|
|
||||||
#
|
|
||||||
# simply replaces any uppercase letter to its lowercase variant preceeded by an underscore
|
|
||||||
#========================================================================================
|
|
||||||
toSnakeCase =
|
|
||||||
str:
|
|
||||||
throwIfNot (isString str) "toSnakeCase only accepts string values, but got ${typeOf str}" (
|
|
||||||
str
|
|
||||||
|> splitStringBy (prev: curr: builtins.match "[a-z]" prev != null && builtins.match "[A-Z]" curr != null) true
|
|
||||||
|> map (p: toLower p)
|
|
||||||
|> concatStringsSep "_"
|
|
||||||
);
|
|
||||||
|
|
||||||
#========================================================================================
|
|
||||||
# Converts a set of url parts to a string
|
|
||||||
#========================================================================================
|
|
||||||
toUrl =
|
|
||||||
{ protocol ? null, host, port ? null, path ? null, query ? null, hash ? null }:
|
|
||||||
let
|
|
||||||
trim_slashes = str: str |> match "^\/*(.+?)\/*$" |> head;
|
|
||||||
encode_to_str = set: concatMapAttrsStringSep "&" (n: v: "${n}=${v}") set;
|
|
||||||
|
|
||||||
_protocol = if protocol != null then "${protocol}://" else "";
|
|
||||||
_port = if port != null then ":${toString port}" else "";
|
|
||||||
_path = if path != null then "/${path |> trim_slashes}" else "";
|
|
||||||
_query = if query != null then "?${query |> encode_to_str}" else "";
|
|
||||||
_hash = if hash != null then "#${hash |> encode_to_str}" else "";
|
|
||||||
in
|
|
||||||
"${_protocol}${host}${_port}${_path}${_query}${_hash}";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
{ config, lib, pkgs, namespace, osConfig ? {}, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.application.matrix;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.application.matrix = {
|
|
||||||
enable = mkEnableOption "enable Matrix client (Fractal)";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
home.packages = with pkgs; [ fractal element-desktop ];
|
|
||||||
|
|
||||||
programs.element-desktop = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +1,16 @@
|
||||||
{
|
{ inputs, config, lib, pkgs, namespace, ... }:
|
||||||
inputs,
|
let
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
inherit (lib) mkIf mkEnableOption;
|
||||||
|
|
||||||
cfg = config.${namespace}.application.onlyoffice;
|
cfg = config.${namespace}.application.onlyoffice;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.${namespace}.application.onlyoffice = {
|
options.${namespace}.application.onlyoffice = {
|
||||||
enable = mkEnableOption "enable onlyoffice";
|
enable = mkEnableOption "enable onlyoffice";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
home.packages = with pkgs; [onlyoffice-desktopeditors];
|
home.packages = with pkgs; [ onlyoffice-bin ];
|
||||||
|
# fonts.packages = with pkgs; [ corefonts ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
home.packages = with pkgs; [ protonup-ng ];
|
home.packages = with pkgs; [ protonup ];
|
||||||
|
|
||||||
home.sessionVariables = {
|
home.sessionVariables = {
|
||||||
STEAM_EXTRA_COMPAT_TOOLS_PATHS = "\${HOME}/.steam/root/compatibilitytools.d";
|
STEAM_EXTRA_COMPAT_TOOLS_PATHS = "\${HOME}/.steam/root/compatibilitytools.d";
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,6 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
home.packages = with pkgs; [ teamspeak3 teamspeak6-client ];
|
home.packages = with pkgs; [ teamspeak_client ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,61 +5,35 @@ let
|
||||||
cfg = config.${namespace}.application.zen;
|
cfg = config.${namespace}.application.zen;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
|
||||||
inputs.zen-browser.homeModules.default
|
|
||||||
];
|
|
||||||
|
|
||||||
options.${namespace}.application.zen = {
|
options.${namespace}.application.zen = {
|
||||||
enable = mkEnableOption "enable zen";
|
enable = mkEnableOption "enable zen";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ inputs.zen-browser.packages.${pkgs.system}.specific ];
|
||||||
|
|
||||||
home.sessionVariables = {
|
home.sessionVariables = {
|
||||||
MOZ_ENABLE_WAYLAND = "1";
|
MOZ_ENABLE_WAYLAND = "1";
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.zen-browser = {
|
programs.zen-browser = {
|
||||||
enable = true;
|
|
||||||
|
|
||||||
policies = {
|
policies = {
|
||||||
AutofillAddressEnabled = true;
|
AutofillAddressEnabled = true;
|
||||||
AutofillCreditCardEnabled = false;
|
AutofillCreditCardEnabled = false;
|
||||||
|
|
||||||
AppAutoUpdate = false;
|
|
||||||
DisableAppUpdate = true;
|
DisableAppUpdate = true;
|
||||||
ManualAppUpdateOnly = true;
|
|
||||||
|
|
||||||
DisableFeedbackCommands = true;
|
DisableFeedbackCommands = true;
|
||||||
DisableFirefoxStudies = true;
|
DisableFirefoxStudies = true;
|
||||||
DisablePocket = true;
|
DisablePocket = true;
|
||||||
DisableTelemetry = true;
|
DisableTelemetry = true;
|
||||||
|
# DontCheckDefaultBrowser = false;
|
||||||
DontCheckDefaultBrowser = false;
|
|
||||||
NoDefaultBookmarks = true;
|
NoDefaultBookmarks = true;
|
||||||
OfferToSaveLogins = false;
|
# OfferToSaveLogins = false;
|
||||||
EnableTrackingProtection = {
|
EnableTrackingProtection = {
|
||||||
Value = true;
|
Value = true;
|
||||||
Locked = true;
|
Locked = true;
|
||||||
Cryptomining = true;
|
Cryptomining = true;
|
||||||
Fingerprinting = true;
|
Fingerprinting = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpAllowlist = [
|
|
||||||
"http://ulmo"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
policies.ExtensionSettings = let
|
|
||||||
mkExtension = id: {
|
|
||||||
install_url = "https://addons.mozilla.org/firefox/downloads/latest/${builtins.toString id}/latest.xpi";
|
|
||||||
installation_mode = "force_installed";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
ublock_origin = 4531307;
|
|
||||||
ghostry = 4562168;
|
|
||||||
bitwarden = 4562769;
|
|
||||||
sponsorblock = 4541835;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
kwalletrc = {
|
kwalletrc = {
|
||||||
Wallet.Enabled = true;
|
Wallet.Enabled = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
plasmarc = {
|
plasmarc = {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ in {
|
||||||
programs.zed-editor = {
|
programs.zed-editor = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
extensions = [ "nix" "toml" "html" "just-ls" ];
|
extensions = [ "nix" "toml" "html" ];
|
||||||
|
|
||||||
userSettings = {
|
userSettings = {
|
||||||
assistant.enabled = false;
|
assistant.enabled = false;
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,7 @@ let
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
systemd.user.startServices = "sd-switch";
|
systemd.user.startServices = "sd-switch";
|
||||||
programs.home-manager = {
|
programs.home-manager.enable = true;
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
home.stateVersion = mkDefault (osConfig.system.stateVersion or "25.05");
|
home.stateVersion = mkDefault (osConfig.system.stateVersion or "25.05");
|
||||||
}
|
}
|
||||||
|
|
@ -17,7 +17,6 @@ in
|
||||||
eza.enable = true;
|
eza.enable = true;
|
||||||
fzf.enable = true;
|
fzf.enable = true;
|
||||||
git.enable = true;
|
git.enable = true;
|
||||||
just.enable = true;
|
|
||||||
starship.enable = true;
|
starship.enable = true;
|
||||||
tmux.enable = true;
|
tmux.enable = true;
|
||||||
yazi.enable = true;
|
yazi.enable = true;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,10 @@
|
||||||
{
|
{ config, lib, pkgs, namespace, ... }:
|
||||||
config,
|
let
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib) mkEnableOption mkIf;
|
inherit (lib) mkEnableOption mkIf;
|
||||||
|
|
||||||
cfg = config.${namespace}.shell.toolset.git;
|
cfg = config.${namespace}.shell.toolset.git;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.${namespace}.shell.toolset.git = {
|
options.${namespace}.shell.toolset.git = {
|
||||||
enable = mkEnableOption "version-control system";
|
enable = mkEnableOption "version-control system";
|
||||||
};
|
};
|
||||||
|
|
@ -16,7 +12,7 @@ in {
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
home.sessionVariables.GITHUB_TOKEN = "$(cat /run/agenix/tokenGH)";
|
home.sessionVariables.GITHUB_TOKEN = "$(cat /run/agenix/tokenGH)";
|
||||||
|
|
||||||
home.packages = with pkgs; [lazygit lazyjj jujutsu];
|
home.packages = with pkgs; [ lazygit lazyjj jujutsu ];
|
||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
zsh.initContent = ''
|
zsh.initContent = ''
|
||||||
|
|
@ -33,6 +29,12 @@ in {
|
||||||
git = {
|
git = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.gitFull;
|
package = pkgs.gitFull;
|
||||||
|
difftastic = {
|
||||||
|
enable = true;
|
||||||
|
background = "dark";
|
||||||
|
color = "always";
|
||||||
|
display = "inline";
|
||||||
|
};
|
||||||
|
|
||||||
ignores = [
|
ignores = [
|
||||||
# General:
|
# General:
|
||||||
|
|
@ -65,7 +67,7 @@ in {
|
||||||
"*.elc"
|
"*.elc"
|
||||||
];
|
];
|
||||||
|
|
||||||
settings = {
|
extraConfig = {
|
||||||
init.defaultBranch = "main";
|
init.defaultBranch = "main";
|
||||||
core = {
|
core = {
|
||||||
editor = "nvim";
|
editor = "nvim";
|
||||||
|
|
@ -102,16 +104,6 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
difftastic = {
|
|
||||||
enable = true;
|
|
||||||
git.enable = true;
|
|
||||||
options = {
|
|
||||||
background = "dark";
|
|
||||||
color = "always";
|
|
||||||
display = "inline";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
{ config, lib, pkgs, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib) mkEnableOption mkIf;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.shell.toolset.just;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.shell.toolset.just = {
|
|
||||||
enable = mkEnableOption "version-control system";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
home.packages = with pkgs; [ just gum ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -31,9 +31,7 @@ in {
|
||||||
base16Scheme = "${pkgs.base16-schemes}/share/themes/${cfg.theme}.yaml";
|
base16Scheme = "${pkgs.base16-schemes}/share/themes/${cfg.theme}.yaml";
|
||||||
image = ./${cfg.theme}.jpg;
|
image = ./${cfg.theme}.jpg;
|
||||||
polarity = cfg.polarity;
|
polarity = cfg.polarity;
|
||||||
|
targets.qt.platform = mkDefault "kde6";
|
||||||
# targets.qt.platform = mkDefault "kde";
|
|
||||||
targets.zen-browser.profileNames = [ "Chris" ];
|
|
||||||
|
|
||||||
fonts = {
|
fonts = {
|
||||||
serif = {
|
serif = {
|
||||||
|
|
@ -52,7 +50,7 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
emoji = {
|
emoji = {
|
||||||
package = pkgs.noto-fonts-color-emoji;
|
package = pkgs.noto-fonts-emoji;
|
||||||
name = "Noto Color Emoji";
|
name = "Noto Color Emoji";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
{
|
{ inputs, config, lib, pkgs, namespace, ... }:
|
||||||
inputs,
|
let
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
inherit (lib) mkIf mkEnableOption;
|
||||||
|
|
||||||
cfg = config.${namespace}.application.steam;
|
cfg = config.${namespace}.application.steam;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.${namespace}.application.steam = {
|
options.${namespace}.application.steam = {
|
||||||
enable = mkEnableOption "enable steam";
|
enable = mkEnableOption "enable steam";
|
||||||
};
|
};
|
||||||
|
|
@ -18,7 +13,7 @@ in {
|
||||||
programs = {
|
programs = {
|
||||||
steam = {
|
steam = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.steam.override {
|
package = pkgs.steam-small.override {
|
||||||
extraEnv = {
|
extraEnv = {
|
||||||
DXVK_HUD = "compiler";
|
DXVK_HUD = "compiler";
|
||||||
MANGOHUD = true;
|
MANGOHUD = true;
|
||||||
|
|
|
||||||
|
|
@ -12,18 +12,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment.plasma6.excludePackages = with pkgs.kdePackages; [
|
environment.plasma6.excludePackages = with pkgs.kdePackages; [ konsole kate ghostwriter oxygen ];
|
||||||
elisa
|
|
||||||
kmahjongg
|
|
||||||
kmines
|
|
||||||
konversation
|
|
||||||
kpat
|
|
||||||
ksudoku
|
|
||||||
konsole
|
|
||||||
kate
|
|
||||||
ghostwriter
|
|
||||||
oxygen
|
|
||||||
];
|
|
||||||
environment.sessionVariables.NIXOS_OZONE_WL = "1";
|
environment.sessionVariables.NIXOS_OZONE_WL = "1";
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,11 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
amdgpu = {
|
amdgpu = {
|
||||||
|
amdvlk = {
|
||||||
|
enable = true;
|
||||||
|
support32Bit.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
initrd.enable = true;
|
initrd.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
config = {
|
|
||||||
home-manager.backupFileExtension = "homeManagerBackup";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
{ pkgs, lib, namespace, config, ... }:
|
{ pkgs, lib, namespace, config, ... }:
|
||||||
let
|
let
|
||||||
|
inherit (lib) mkIf mkEnableOption;
|
||||||
|
|
||||||
cfg = config.${namespace}.nix;
|
cfg = config.${namespace}.nix;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.${namespace}.nix = {};
|
options.${namespace}.nix = {
|
||||||
|
enable = mkEnableOption "Enable nix command";
|
||||||
|
};
|
||||||
|
|
||||||
config = {
|
config = mkIf cfg.enable {
|
||||||
programs.git.enable = true;
|
programs.git.enable = true;
|
||||||
|
|
||||||
nix = {
|
nix = {
|
||||||
|
|
|
||||||
|
|
@ -130,23 +130,6 @@ in
|
||||||
scopes = [ "offline_access" "openid" "email" "picture" "profile" "groups" ];
|
scopes = [ "offline_access" "openid" "email" "picture" "profile" "groups" ];
|
||||||
redirect_uris = [ "http://localhost:3000/api/auth/oauth2/callback/authelia" ];
|
redirect_uris = [ "http://localhost:3000/api/auth/oauth2/callback/authelia" ];
|
||||||
}
|
}
|
||||||
{
|
|
||||||
client_id = "forgejo";
|
|
||||||
client_name = "forgejo";
|
|
||||||
# ZPuiW2gpVV6MGXIJFk5P3EeSW8V_ICgqduF.hJVCKkrnVmRqIQXRk0o~HSA8ZdCf8joA4m_F
|
|
||||||
client_secret = "$pbkdf2-sha512$310000$CzZjvJT75bz5z7MjwxsEtg$JtOiIgaY5/HcLLxJgyX4zvsQV9jIoow0e4JdlFsk/LWRDOJ0kc.PzstlYfw7QERTXtJILoWsDqPzmvpneK5Leg";
|
|
||||||
public = false;
|
|
||||||
require_pkce = true;
|
|
||||||
pkce_challenge_method = "S256";
|
|
||||||
token_endpoint_auth_method = "client_secret_post";
|
|
||||||
authorization_policy = "one_factor";
|
|
||||||
userinfo_signed_response_alg = "none";
|
|
||||||
consent_mode = "implicit";
|
|
||||||
scopes = [ "offline_access" "openid" "email" "picture" "profile" "groups" ];
|
|
||||||
response_types = [ "code" ];
|
|
||||||
grant_types = [ "authorization_code" ];
|
|
||||||
redirect_uris = [ "http://localhost:5002/user/oauth2/authelia/callback" ];
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
1
modules/nixos/services/authentication/default.nix
Normal file
1
modules/nixos/services/authentication/default.nix
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{ ... }: {}
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
{
|
{ inputs, lib, config, namespace, ... }: let
|
||||||
inputs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib) mkEnableOption mkIf;
|
inherit (lib) mkEnableOption mkIf;
|
||||||
|
|
||||||
cfg = config.${namespace}.services.authentication.himmelblau;
|
cfg = config.${namespace}.services.authentication.himmelblau;
|
||||||
in {
|
in
|
||||||
imports = [inputs.himmelblau.nixosModules.himmelblau];
|
{
|
||||||
|
imports = [ inputs.himmelblau.nixosModules.himmelblau ];
|
||||||
|
|
||||||
options.${namespace}.services.authentication.himmelblau = {
|
options.${namespace}.services.authentication.himmelblau = {
|
||||||
enable = mkEnableOption "enable azure entra ID authentication";
|
enable = mkEnableOption "enable azure entra ID authentication";
|
||||||
|
|
@ -19,7 +14,7 @@ in {
|
||||||
services.himmelblau = {
|
services.himmelblau = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
domain = "";
|
domains = [];
|
||||||
pam_allow_groups = [];
|
pam_allow_groups = [];
|
||||||
local_groups = [];
|
local_groups = [];
|
||||||
};
|
};
|
||||||
86
modules/nixos/services/authentication/zitadel.nix
Normal file
86
modules/nixos/services/authentication/zitadel.nix
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
{ config, lib, pkgs, namespace, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib) mkIf mkEnableOption;
|
||||||
|
|
||||||
|
cfg = config.${namespace}.services.authentication.zitadel;
|
||||||
|
|
||||||
|
db_name = "zitadel";
|
||||||
|
db_user = "zitadel";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.${namespace}.services.authentication.zitadel = {
|
||||||
|
enable = mkEnableOption "Zitadel";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
zitadel
|
||||||
|
];
|
||||||
|
|
||||||
|
services = {
|
||||||
|
zitadel = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
masterKeyFile = config.sops.secrets."zitadel/masterKey".path;
|
||||||
|
tlsMode = "external";
|
||||||
|
settings = {
|
||||||
|
Port = 9092;
|
||||||
|
Database = {
|
||||||
|
Host = "/run/postgresql";
|
||||||
|
# Zitadel will report error if port is not set
|
||||||
|
Port = 5432;
|
||||||
|
Database = db_name;
|
||||||
|
User.Username = db_user;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
steps = {
|
||||||
|
TestInstance = {
|
||||||
|
InstanceName = "Zitadel test";
|
||||||
|
Org = {
|
||||||
|
Name = "Kruining.eu";
|
||||||
|
Human = {
|
||||||
|
UserName = "admin";
|
||||||
|
Password = "kaas";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
postgresql = {
|
||||||
|
enable = true;
|
||||||
|
ensureDatabases = [ db_name ];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = db_user;
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
caddy = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
"auth-z.kruining.eu".extraConfig = ''
|
||||||
|
reverse_proxy h2c://127.0.0.1:9092
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
# extraConfig = ''
|
||||||
|
# (auth) {
|
||||||
|
# forward_auth h2c://127.0.0.1:9092 {
|
||||||
|
# uri /api/authz/forward-auth
|
||||||
|
# copy_headers Remote-User Remote-Groups Remote-Email Remote-Name
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# '';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
sops.secrets."zitadel/masterKey" = {
|
||||||
|
owner = "zitadel";
|
||||||
|
group = "zitadel";
|
||||||
|
restartUnits = [ "zitadel.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,733 +0,0 @@
|
||||||
{ config, lib, pkgs, namespace, system, inputs, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib) mkIf mkEnableOption mkOption types toUpper toSentenceCase nameValuePair mapAttrs mapAttrs' concatMapAttrs concatMapStringsSep filterAttrsRecursive listToAttrs imap0 head drop length literalExpression attrNames;
|
|
||||||
inherit (lib.${namespace}.strings) toSnakeCase;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.authentication.zitadel;
|
|
||||||
|
|
||||||
database = "zitadel";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.services.authentication.zitadel = {
|
|
||||||
enable = mkEnableOption "Zitadel";
|
|
||||||
|
|
||||||
organization = mkOption {
|
|
||||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
|
||||||
options =
|
|
||||||
let
|
|
||||||
org = name;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
isDefault = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
example = "true";
|
|
||||||
description = ''
|
|
||||||
True sets the '${org}' org as default org for the instance. Only one org can be default org.
|
|
||||||
Nothing happens if you set it to false until you set another org as default org.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
project = mkOption {
|
|
||||||
default = {};
|
|
||||||
type = types.attrsOf (types.submodule {
|
|
||||||
options = {
|
|
||||||
hasProjectCheck = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
example = "true";
|
|
||||||
description = ''
|
|
||||||
ZITADEL checks if the org of the user has permission to this project.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
privateLabelingSetting = mkOption {
|
|
||||||
type = types.nullOr (types.enum [ "unspecified" "enforceProjectResourceOwnerPolicy" "allowLoginUserResourceOwnerPolicy" ]);
|
|
||||||
default = null;
|
|
||||||
example = "enforceProjectResourceOwnerPolicy";
|
|
||||||
description = ''
|
|
||||||
Defines from where the private labeling should be triggered,
|
|
||||||
|
|
||||||
supported values:
|
|
||||||
- unspecified
|
|
||||||
- enforceProjectResourceOwnerPolicy
|
|
||||||
- allowLoginUserResourceOwnerPolicy
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
projectRoleAssertion = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
example = "true";
|
|
||||||
description = ''
|
|
||||||
Describes if roles of user should be added in token.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
projectRoleCheck = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
example = "true";
|
|
||||||
description = ''
|
|
||||||
ZITADEL checks if the user has at least one on this project.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
role = mkOption {
|
|
||||||
default = {};
|
|
||||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
|
||||||
options =
|
|
||||||
let
|
|
||||||
roleName = name;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
displayName = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = toSentenceCase name;
|
|
||||||
example = "RoleName";
|
|
||||||
description = ''
|
|
||||||
Name used for project role.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
example = "some_group";
|
|
||||||
description = ''
|
|
||||||
Group used for project role.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
assign = mkOption {
|
|
||||||
default = {};
|
|
||||||
type = types.attrsOf (types.listOf types.str);
|
|
||||||
};
|
|
||||||
|
|
||||||
application = mkOption {
|
|
||||||
default = {};
|
|
||||||
type = types.attrsOf (types.submodule {
|
|
||||||
options = {
|
|
||||||
redirectUris = mkOption {
|
|
||||||
type = types.nonEmptyListOf types.str;
|
|
||||||
example = ''
|
|
||||||
[ "https://example.com/redirect/url" ]
|
|
||||||
'';
|
|
||||||
description = ''
|
|
||||||
.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
grantTypes = mkOption {
|
|
||||||
type = types.nonEmptyListOf (types.enum [ "authorizationCode" "implicit" "refreshToken" "deviceCode" "tokenExchange" ]);
|
|
||||||
example = ''
|
|
||||||
[ "authorizationCode" ]
|
|
||||||
'';
|
|
||||||
description = ''
|
|
||||||
.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
responseTypes = mkOption {
|
|
||||||
type = types.nonEmptyListOf (types.enum [ "code" "idToken" "idTokenToken" ]);
|
|
||||||
example = ''
|
|
||||||
[ "code" ]
|
|
||||||
'';
|
|
||||||
description = ''
|
|
||||||
.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
exportMap =
|
|
||||||
let
|
|
||||||
strOpt = mkOption { type = types.nullOr types.str; default = null; };
|
|
||||||
in
|
|
||||||
mkOption {
|
|
||||||
type = types.submodule { options = { client_id = strOpt; client_secret = strOpt; }; };
|
|
||||||
default = {};
|
|
||||||
example = literalExpression ''
|
|
||||||
{
|
|
||||||
client_id = "SSO_CLIENT_ID";
|
|
||||||
client_secret = "SSO_CLIENT_SECRET";
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
description = ''
|
|
||||||
Remap the outputted variables to another key.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
default = {};
|
|
||||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
|
||||||
options =
|
|
||||||
let
|
|
||||||
username = name;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
email = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "someone@some.domain";
|
|
||||||
description = ''
|
|
||||||
Username.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
userName = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = username;
|
|
||||||
example = "some_user_name";
|
|
||||||
description = ''
|
|
||||||
Username. Default value is the key of the config object you created, you can overwrite that by setting this option
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
firstName = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "John";
|
|
||||||
description = ''
|
|
||||||
First name of the user.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
lastName = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "Doe";
|
|
||||||
description = ''
|
|
||||||
Last name of the user.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
roles = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
example = "[ \"ORG_OWNER\" ]";
|
|
||||||
description = ''
|
|
||||||
List of roles granted to organisation.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
instanceRoles = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
example = "[ \"IAM_OWNER\" ]";
|
|
||||||
description = ''
|
|
||||||
List of roles granted to instance.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
action = mkOption {
|
|
||||||
default = {};
|
|
||||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
|
||||||
options = {
|
|
||||||
script = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = ''
|
|
||||||
(ctx, api) => {
|
|
||||||
api.v1.claims.setClaim('some_claim', 'some_value');
|
|
||||||
};
|
|
||||||
'';
|
|
||||||
description = ''
|
|
||||||
The script to run. This must be a function that receives 2 parameters, and returns void. During the creation of the action's script this module simly does `const {{name}} = {{script}}`.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
timeout = mkOption {
|
|
||||||
type = (types.ints.between 0 20);
|
|
||||||
default = 10;
|
|
||||||
example = "10";
|
|
||||||
description = ''
|
|
||||||
After which time the action will be terminated if not finished.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
allowedToFail = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
example = "true";
|
|
||||||
description = ''
|
|
||||||
Allowed to fail.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
triggers = mkOption {
|
|
||||||
default = [];
|
|
||||||
type = types.listOf (types.submodule {
|
|
||||||
options = {
|
|
||||||
flowType = mkOption {
|
|
||||||
type = types.enum [ "authentication" "customiseToken" "internalAuthentication" "samlResponse" ];
|
|
||||||
example = "customiseToken";
|
|
||||||
description = ''
|
|
||||||
Type of the flow to which the action triggers belong.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
triggerType = mkOption {
|
|
||||||
type = types.enum [ "postAuthentication" "preCreation" "postCreation" "preUserinfoCreation" "preAccessTokenCreation" "preSamlResponse" ];
|
|
||||||
example = "postAuthentication";
|
|
||||||
description = ''
|
|
||||||
Trigger type on when the actions get triggered.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
actions = mkOption {
|
|
||||||
type = types.nonEmptyListOf types.str;
|
|
||||||
example = ''[ "action_name" ]'';
|
|
||||||
description = ''
|
|
||||||
Names of actions to trigger
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = let
|
|
||||||
_refTypeMap = {
|
|
||||||
org = { type = "org"; };
|
|
||||||
project = { type = "project"; };
|
|
||||||
user = { type = "user"; tfType = "human_user"; };
|
|
||||||
};
|
|
||||||
|
|
||||||
mapRef' = { type, tfType ? type }: name: { "${type}Id" = "\${ resource.zitadel_${tfType}.${toSnakeCase name}.id }"; };
|
|
||||||
mapRef = type: name: mapRef' (_refTypeMap.${type}) name;
|
|
||||||
mapEnum = prefix: value: "${prefix}_${value |> toSnakeCase |> toUpper}";
|
|
||||||
|
|
||||||
mapValue = type: value: ({
|
|
||||||
appType = mapEnum "OIDC_APP_TYPE" value;
|
|
||||||
grantTypes = map (t: mapEnum "OIDC_GRANT_TYPE" t) value;
|
|
||||||
responseTypes = map (t: mapEnum "OIDC_RESPONSE_TYPE" t) value;
|
|
||||||
authMethodType = mapEnum "OIDC_AUTH_METHOD_TYPE" value;
|
|
||||||
|
|
||||||
flowType = mapEnum "FLOW_TYPE" value;
|
|
||||||
triggerType = mapEnum "TRIGGER_TYPE" value;
|
|
||||||
accessTokenType = mapEnum "OIDC_TOKEN_TYPE" value;
|
|
||||||
}."${type}" or value);
|
|
||||||
|
|
||||||
toResource = name: value: nameValuePair
|
|
||||||
(toSnakeCase name)
|
|
||||||
(lib.mapAttrs' (k: v: nameValuePair (toSnakeCase k) (mapValue k v)) value);
|
|
||||||
|
|
||||||
withRef = type: name: attrs: attrs // (mapRef type name);
|
|
||||||
|
|
||||||
select = keys: callback: set:
|
|
||||||
if (length keys) == 0 then
|
|
||||||
mapAttrs' callback set
|
|
||||||
else let key = head keys; in
|
|
||||||
concatMapAttrs (k: v: select (drop 1 keys) (callback k) (v.${key} or {})) set
|
|
||||||
;
|
|
||||||
|
|
||||||
append = attrList: set: set // (listToAttrs attrList);
|
|
||||||
|
|
||||||
config' = config;
|
|
||||||
|
|
||||||
# this is a nix package, the generated json file to be exact
|
|
||||||
terraformConfiguration = inputs.terranix.lib.terranixConfiguration {
|
|
||||||
inherit system;
|
|
||||||
|
|
||||||
modules = [
|
|
||||||
({ config, lib, ... }: {
|
|
||||||
config =
|
|
||||||
let
|
|
||||||
forEach = src: key: set:
|
|
||||||
let
|
|
||||||
_key = concatMapStringsSep "_" (k: "\${item.${k}}") key;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
forEach = lib.tfRef ''{
|
|
||||||
for item in ${src} :
|
|
||||||
"''${item.org}_''${item.name}" => item
|
|
||||||
}'';
|
|
||||||
}
|
|
||||||
// set;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
terraform.required_providers.zitadel = {
|
|
||||||
source = "zitadel/zitadel";
|
|
||||||
version = "2.2.0";
|
|
||||||
};
|
|
||||||
|
|
||||||
provider.zitadel = {
|
|
||||||
domain = "auth.kruining.eu";
|
|
||||||
insecure = "false";
|
|
||||||
jwt_profile_file = "/var/lib/zitadel/machine-key.json";
|
|
||||||
};
|
|
||||||
|
|
||||||
locals = {
|
|
||||||
extra_users = lib.tfRef "
|
|
||||||
flatten([ for org, users in jsondecode(file(\"${config'.sops.secrets."zitadel/users".path}\")): [
|
|
||||||
for name, details in users: {
|
|
||||||
org = org
|
|
||||||
name = name
|
|
||||||
email = details.email
|
|
||||||
firstName = details.firstName
|
|
||||||
lastName = details.lastName
|
|
||||||
}
|
|
||||||
] ])
|
|
||||||
";
|
|
||||||
orgs = cfg.organization |> mapAttrs (org: _: lib.tfRef "resource.zitadel_org.${org}.id");
|
|
||||||
};
|
|
||||||
|
|
||||||
resource = {
|
|
||||||
# Organizations
|
|
||||||
zitadel_org = cfg.organization |> select [] (name: { isDefault, ... }:
|
|
||||||
{ inherit name isDefault; }
|
|
||||||
|> toResource name
|
|
||||||
);
|
|
||||||
|
|
||||||
# Projects per organization
|
|
||||||
zitadel_project = cfg.organization |> select [ "project" ] (org: name: { hasProjectCheck, privateLabelingSetting, projectRoleAssertion, projectRoleCheck, ... }:
|
|
||||||
{
|
|
||||||
inherit name hasProjectCheck privateLabelingSetting projectRoleAssertion projectRoleCheck;
|
|
||||||
}
|
|
||||||
|> withRef "org" org
|
|
||||||
|> toResource "${org}_${name}"
|
|
||||||
);
|
|
||||||
|
|
||||||
# Each OIDC app per project
|
|
||||||
zitadel_application_oidc = cfg.organization |> select [ "project" "application" ] (org: project: name: { redirectUris, grantTypes, responseTypes, ...}:
|
|
||||||
{
|
|
||||||
inherit name redirectUris grantTypes responseTypes;
|
|
||||||
|
|
||||||
accessTokenRoleAssertion = true;
|
|
||||||
idTokenRoleAssertion = true;
|
|
||||||
accessTokenType = "JWT";
|
|
||||||
}
|
|
||||||
|> withRef "org" org
|
|
||||||
|> withRef "project" "${org}_${project}"
|
|
||||||
|> toResource "${org}_${project}_${name}"
|
|
||||||
);
|
|
||||||
|
|
||||||
# Each project role
|
|
||||||
zitadel_project_role = cfg.organization |> select [ "project" "role" ] (org: project: name: value:
|
|
||||||
{ inherit (value) displayName group; roleKey = name; }
|
|
||||||
|> withRef "org" org
|
|
||||||
|> withRef "project" "${org}_${project}"
|
|
||||||
|> toResource "${org}_${project}_${name}"
|
|
||||||
);
|
|
||||||
|
|
||||||
# Each project role assignment
|
|
||||||
zitadel_user_grant = cfg.organization |> select [ "project" "assign" ] (org: project: user: roles:
|
|
||||||
{ roleKeys = roles; }
|
|
||||||
|> withRef "org" org
|
|
||||||
|> withRef "project" "${org}_${project}"
|
|
||||||
|> withRef "user" "${org}_${user}"
|
|
||||||
|> toResource "${org}_${project}_${user}"
|
|
||||||
);
|
|
||||||
|
|
||||||
# Users
|
|
||||||
zitadel_human_user =
|
|
||||||
cfg.organization
|
|
||||||
|> select [ "user" ] (org: name: { email, userName, firstName, lastName, ... }:
|
|
||||||
{
|
|
||||||
inherit email userName firstName lastName;
|
|
||||||
|
|
||||||
isEmailVerified = true;
|
|
||||||
}
|
|
||||||
|> withRef "org" org
|
|
||||||
|> toResource "${org}_${name}"
|
|
||||||
)
|
|
||||||
|> append
|
|
||||||
[
|
|
||||||
(forEach "local.extra_users" [ "org" "name" ] {
|
|
||||||
orgId = lib.tfRef "local.orgs[each.value.org]";
|
|
||||||
userName = lib.tfRef "each.value.name";
|
|
||||||
email = lib.tfRef "each.value.email";
|
|
||||||
firstName = lib.tfRef "each.value.firstName";
|
|
||||||
lastName = lib.tfRef "each.value.lastName";
|
|
||||||
|
|
||||||
isEmailVerified = true;
|
|
||||||
}
|
|
||||||
|> toResource "extraUsers")
|
|
||||||
]
|
|
||||||
;
|
|
||||||
|
|
||||||
# Global user roles
|
|
||||||
zitadel_instance_member =
|
|
||||||
cfg.organization
|
|
||||||
|> filterAttrsRecursive (n: v: !(v ? "instanceRoles" && (length v.instanceRoles) == 0))
|
|
||||||
|> select [ "user" ] (org: name: { instanceRoles, ... }:
|
|
||||||
{ roles = instanceRoles; }
|
|
||||||
|> withRef "user" "${org}_${name}"
|
|
||||||
|> toResource "${org}_${name}"
|
|
||||||
);
|
|
||||||
|
|
||||||
# Organazation specific roles
|
|
||||||
zitadel_org_member =
|
|
||||||
cfg.organization
|
|
||||||
|> filterAttrsRecursive (n: v: !(v ? "roles" && (length v.roles) == 0))
|
|
||||||
|> select [ "user" ] (org: name: { roles, ... }:
|
|
||||||
{ inherit roles; }
|
|
||||||
|> withRef "org" org
|
|
||||||
|> withRef "user" "${org}_${name}"
|
|
||||||
|> toResource "${org}_${name}"
|
|
||||||
);
|
|
||||||
|
|
||||||
# Organazation's actions
|
|
||||||
zitadel_action = cfg.organization |> select [ "action" ] (org: name: { timeout, allowedToFail, script, ...}:
|
|
||||||
{
|
|
||||||
inherit allowedToFail name;
|
|
||||||
timeout = "${toString timeout}s";
|
|
||||||
script = "const ${name} = ${script}";
|
|
||||||
}
|
|
||||||
|> withRef "org" org
|
|
||||||
|> toResource "${org}_${name}"
|
|
||||||
);
|
|
||||||
|
|
||||||
# Organazation's action assignments
|
|
||||||
zitadel_trigger_actions =
|
|
||||||
cfg.organization
|
|
||||||
|> concatMapAttrs (org: { triggers, ... }:
|
|
||||||
triggers
|
|
||||||
|> imap0 (i: { flowType, triggerType, actions, ... }: (let name = "trigger_${toString i}"; in
|
|
||||||
{
|
|
||||||
inherit flowType triggerType;
|
|
||||||
|
|
||||||
actionIds =
|
|
||||||
actions
|
|
||||||
|> map (action: (lib.tfRef "zitadel_action.${org}_${toSnakeCase action}.id"));
|
|
||||||
}
|
|
||||||
|> withRef "org" org
|
|
||||||
|> toResource "${org}_${name}"
|
|
||||||
))
|
|
||||||
|> listToAttrs
|
|
||||||
);
|
|
||||||
|
|
||||||
# SMTP config
|
|
||||||
zitadel_smtp_config.default = {
|
|
||||||
sender_address = "chris@kruining.eu";
|
|
||||||
sender_name = "no-reply (Zitadel)";
|
|
||||||
tls = true;
|
|
||||||
host = "black-mail.nl:587";
|
|
||||||
user = "chris@kruining.eu";
|
|
||||||
password = lib.tfRef "file(\"${config'.sops.secrets."zitadel/email".path}\")";
|
|
||||||
set_active = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Client credentials per app
|
|
||||||
local_sensitive_file = cfg.organization |> select [ "project" "application" ] (org: project: name: { exportMap, ... }:
|
|
||||||
nameValuePair "${org}_${project}_${name}" {
|
|
||||||
content = ''
|
|
||||||
${if exportMap.client_id != null then exportMap.client_id else "CLIENT_ID"}=${lib.tfRef "resource.zitadel_application_oidc.${org}_${project}_${name}.client_id"}
|
|
||||||
${if exportMap.client_secret != null then exportMap.client_secret else "CLIENT_SECRET"}=${lib.tfRef "resource.zitadel_application_oidc.${org}_${project}_${name}.client_secret"}
|
|
||||||
'';
|
|
||||||
filename = "/var/lib/zitadel/clients/${org}_${project}_${name}";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
in
|
|
||||||
mkIf cfg.enable {
|
|
||||||
${namespace}.services.persistance.postgresql.enable = true;
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
zitadel
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d /tmp/zitadelApplyTerraform 0755 zitadel zitadel -"
|
|
||||||
"d /var/lib/zitadel/clients 0755 zitadel zitadel -"
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.services.zitadelApplyTerraform = {
|
|
||||||
description = "Zitadel terraform apply";
|
|
||||||
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
wants = [ "zitadel.service" ];
|
|
||||||
|
|
||||||
script =
|
|
||||||
let
|
|
||||||
tofu = lib.getExe pkgs.opentofu;
|
|
||||||
in
|
|
||||||
''
|
|
||||||
if [ "$(systemctl is-active zitadel)" != "active" ]; then
|
|
||||||
echo "Zitadel is not running"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Print the path to the source for easier debugging
|
|
||||||
echo "config location: ${terraformConfiguration}"
|
|
||||||
|
|
||||||
# Copy infra code into workspace
|
|
||||||
cp -f ${terraformConfiguration} config.tf.json
|
|
||||||
|
|
||||||
# Initialize OpenTofu
|
|
||||||
${tofu} init
|
|
||||||
|
|
||||||
# Run the infrastructure code
|
|
||||||
${tofu} plan -refresh=false -out=tfplan
|
|
||||||
${tofu} apply -auto-approve tfplan
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
User = "zitadel";
|
|
||||||
Group = "zitadel";
|
|
||||||
|
|
||||||
WorkingDirectory = "/tmp/zitadelApplyTerraform";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
zitadel = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
masterKeyFile = config.sops.secrets."zitadel/masterKey".path;
|
|
||||||
tlsMode = "external";
|
|
||||||
settings = {
|
|
||||||
Port = 9092;
|
|
||||||
|
|
||||||
ExternalDomain = "auth.kruining.eu";
|
|
||||||
ExternalPort = 443;
|
|
||||||
ExternalSecure = true;
|
|
||||||
|
|
||||||
Metrics.Type = "otel";
|
|
||||||
Tracing.Type = "otel";
|
|
||||||
Telemetry.Enabled = true;
|
|
||||||
|
|
||||||
SystemDefaults = {
|
|
||||||
PasswordHasher.Hasher.Algorithm = "argon2id";
|
|
||||||
SecretHasher.Hasher.Algorithm = "argon2id";
|
|
||||||
};
|
|
||||||
|
|
||||||
Database.postgres = {
|
|
||||||
Host = "localhost";
|
|
||||||
# Zitadel will report error if port is not set
|
|
||||||
Port = 5432;
|
|
||||||
Database = database;
|
|
||||||
User = {
|
|
||||||
Username = database;
|
|
||||||
SSL.Mode = "disable";
|
|
||||||
};
|
|
||||||
Admin = {
|
|
||||||
Username = "postgres";
|
|
||||||
SSL.Mode = "disable";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
steps = {
|
|
||||||
FirstInstance = {
|
|
||||||
# Not sure, this option seems to be mostly irrelevant
|
|
||||||
InstanceName = "eu";
|
|
||||||
|
|
||||||
MachineKeyPath = "/var/lib/zitadel/machine-key.json";
|
|
||||||
# PatPath = "/var/lib/zitadel/machine-key.pat";
|
|
||||||
# LoginClientPatPath = "/var/lib/zitadel/machine-key.json";
|
|
||||||
|
|
||||||
Org = {
|
|
||||||
Name = "kruining";
|
|
||||||
|
|
||||||
Human = {
|
|
||||||
UserName = "chris";
|
|
||||||
FirstName = "Chris";
|
|
||||||
LastName = "Kruining";
|
|
||||||
Email = {
|
|
||||||
Address = "chris@kruining.eu";
|
|
||||||
Verified = true;
|
|
||||||
};
|
|
||||||
Password = "KaasIsAwesome1!";
|
|
||||||
};
|
|
||||||
|
|
||||||
Machine = {
|
|
||||||
Machine = {
|
|
||||||
Username = "terraform-service-user";
|
|
||||||
Name = "Terraform";
|
|
||||||
};
|
|
||||||
MachineKey = { ExpirationDate = "2026-01-01T00:00:00Z"; Type = 1; };
|
|
||||||
# Pat = { ExpirationDate = "2026-01-01T00:00:00Z"; };
|
|
||||||
};
|
|
||||||
|
|
||||||
# LoginClient.Machine = {
|
|
||||||
# Username = "terraform-service-user";
|
|
||||||
# Name = "Terraform";
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# extraStepsPaths = [
|
|
||||||
# config.sops.templates."secrets.yaml".path
|
|
||||||
# ];
|
|
||||||
};
|
|
||||||
|
|
||||||
postgresql = {
|
|
||||||
enable = true;
|
|
||||||
ensureDatabases = [ database ];
|
|
||||||
ensureUsers = [
|
|
||||||
{
|
|
||||||
name = database;
|
|
||||||
ensureDBOwnership = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
caddy = {
|
|
||||||
enable = true;
|
|
||||||
virtualHosts = {
|
|
||||||
"auth.kruining.eu".extraConfig = ''
|
|
||||||
reverse_proxy h2c://::1:9092
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
extraConfig = ''
|
|
||||||
(auth) {
|
|
||||||
forward_auth h2c://::1:9092 {
|
|
||||||
uri /api/authz/forward-auth
|
|
||||||
copy_headers Remote-User Remote-Groups Remote-Email Remote-Name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
|
||||||
|
|
||||||
# Secrets
|
|
||||||
sops = {
|
|
||||||
secrets = {
|
|
||||||
"zitadel/masterKey" = {
|
|
||||||
owner = "zitadel";
|
|
||||||
group = "zitadel";
|
|
||||||
restartUnits = [ "zitadel.service" ]; #EMGDB#6O$8qpGoLI1XjhUhnng1san@0
|
|
||||||
};
|
|
||||||
|
|
||||||
"zitadel/email" = {
|
|
||||||
owner = "zitadel";
|
|
||||||
group = "zitadel";
|
|
||||||
key = "email/chris_kruining_eu";
|
|
||||||
restartUnits = [ "zitadel.service" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
"zitadel/users" = {
|
|
||||||
owner = "zitadel";
|
|
||||||
group = "zitadel";
|
|
||||||
restartUnits = [ "zitadelApplyTerraform.service" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
templates = {
|
|
||||||
"users.yml" = {
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
{ config, lib, pkgs, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.backup.borg;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.services.backup.borg = {
|
|
||||||
enable = mkEnableOption "Borg Backup";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
programs.ssh.extraConfig = ''
|
|
||||||
Host beheer.hazelhof.nl
|
|
||||||
Port 222
|
|
||||||
User chris
|
|
||||||
AddressFamily inet
|
|
||||||
IdentityFile /home/chris/.ssh/id_ed25519
|
|
||||||
'';
|
|
||||||
|
|
||||||
services = {
|
|
||||||
borgbackup.jobs = {
|
|
||||||
media = {
|
|
||||||
paths = "/var/media/test";
|
|
||||||
encryption.mode = "none";
|
|
||||||
# environment.BORG_SSH = "ssh -4 -i /home/chris/.ssh/id_ed25519";
|
|
||||||
environment.BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK = "yes";
|
|
||||||
repo = "ssh://beheer.hazelhof.nl//media";
|
|
||||||
compression = "auto,zstd";
|
|
||||||
startAt = "daily";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,234 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (builtins) toString toJSON;
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.communication.matrix;
|
|
||||||
|
|
||||||
domain = "kruining.eu";
|
|
||||||
fqn = "matrix.${domain}";
|
|
||||||
port = 4001;
|
|
||||||
|
|
||||||
database = "synapse";
|
|
||||||
in {
|
|
||||||
options.${namespace}.services.communication.matrix = {
|
|
||||||
enable = mkEnableOption "Matrix server (Synapse)";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
${namespace}.services = {
|
|
||||||
persistance.postgresql.enable = true;
|
|
||||||
# virtualisation.podman.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [4001];
|
|
||||||
|
|
||||||
services = {
|
|
||||||
matrix-synapse = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
extras = ["oidc"];
|
|
||||||
|
|
||||||
extraConfigFiles = [
|
|
||||||
config.sops.templates."synapse-oidc.yaml".path
|
|
||||||
];
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
server_name = domain;
|
|
||||||
public_baseurl = "https://${fqn}";
|
|
||||||
|
|
||||||
enable_metrics = true;
|
|
||||||
|
|
||||||
registration_shared_secret = "tZtBnlhEmLbMwF0lQ112VH1Rl5MkZzYH9suI4pEoPXzk6nWUB8FJF4eEnwLkbstz";
|
|
||||||
|
|
||||||
url_preview_enabled = true;
|
|
||||||
precence.enabled = true;
|
|
||||||
|
|
||||||
# Since we'll be using OIDC for auth disable all local options
|
|
||||||
enable_registration = false;
|
|
||||||
enable_registration_without_verification = false;
|
|
||||||
password_config.enabled = false;
|
|
||||||
backchannel_logout_enabled = true;
|
|
||||||
|
|
||||||
sso = {
|
|
||||||
client_whitelist = ["http://[::1]:9092"];
|
|
||||||
update_profile_information = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
database = {
|
|
||||||
# this is postgresql (also the default, but I prefer to be explicit)
|
|
||||||
name = "psycopg2";
|
|
||||||
args = {
|
|
||||||
database = database;
|
|
||||||
user = database;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
listeners = [
|
|
||||||
{
|
|
||||||
bind_addresses = ["::"];
|
|
||||||
port = port;
|
|
||||||
type = "http";
|
|
||||||
tls = false;
|
|
||||||
x_forwarded = true;
|
|
||||||
|
|
||||||
resources = [
|
|
||||||
{
|
|
||||||
names = ["client" "federation" "openid" "metrics" "media" "health"];
|
|
||||||
compress = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mautrix-signal = {
|
|
||||||
enable = true;
|
|
||||||
registerToSynapse = true;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
appservice = {
|
|
||||||
provisioning.enabled = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
homeserver = {
|
|
||||||
address = "http://[::1]:${toString port}";
|
|
||||||
domain = domain;
|
|
||||||
};
|
|
||||||
|
|
||||||
bridge = {
|
|
||||||
permissions = {
|
|
||||||
"@chris:${domain}" = "admin";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mautrix-telegram = {
|
|
||||||
enable = true;
|
|
||||||
registerToSynapse = true;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
telegram = {
|
|
||||||
api_id = 32770816;
|
|
||||||
api_hash = "7b63778a976619c9d4ab62adc51cde79";
|
|
||||||
bot_token = "disabled";
|
|
||||||
|
|
||||||
catch_up = true;
|
|
||||||
sequential_updates = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
appservice = {
|
|
||||||
port = 40011;
|
|
||||||
provisioning.enabled = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
homeserver = {
|
|
||||||
address = "http://[::1]:${toString port}";
|
|
||||||
domain = domain;
|
|
||||||
};
|
|
||||||
|
|
||||||
bridge = {
|
|
||||||
permissions = {
|
|
||||||
"@chris:${domain}" = "admin";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mautrix-whatsapp = {
|
|
||||||
enable = true;
|
|
||||||
registerToSynapse = true;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
appservice = {
|
|
||||||
provisioning.enabled = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
homeserver = {
|
|
||||||
address = "http://[::1]:${toString port}";
|
|
||||||
domain = domain;
|
|
||||||
};
|
|
||||||
|
|
||||||
bridge = {
|
|
||||||
permissions = {
|
|
||||||
"@chris:${domain}" = "admin";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
postgresql = {
|
|
||||||
enable = true;
|
|
||||||
ensureDatabases = [database];
|
|
||||||
ensureUsers = [
|
|
||||||
{
|
|
||||||
name = database;
|
|
||||||
ensureDBOwnership = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
caddy = {
|
|
||||||
enable = true;
|
|
||||||
virtualHosts = let
|
|
||||||
server = {
|
|
||||||
"m.server" = "${fqn}:443";
|
|
||||||
};
|
|
||||||
client = {
|
|
||||||
"m.homeserver".base_url = "https://${fqn}";
|
|
||||||
"m.identity_server".base_url = "https://auth.kruining.eu";
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
"${domain}".extraConfig = ''
|
|
||||||
header /.well-known/matrix/* Content-Type application/json
|
|
||||||
header /.well-known/matrix/* Access-Control-Allow-Origin *
|
|
||||||
respond /.well-known/matrix/server `${toJSON server}`
|
|
||||||
respond /.well-known/matrix/client `${toJSON client}`
|
|
||||||
'';
|
|
||||||
"${fqn}".extraConfig = ''
|
|
||||||
reverse_proxy /_matrix/* http://::1:4001
|
|
||||||
reverse_proxy /_synapse/client/* http://::1:4001
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops = {
|
|
||||||
secrets = {
|
|
||||||
"synapse/oidc_id" = {};
|
|
||||||
"synapse/oidc_secret" = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
templates = {
|
|
||||||
"synapse-oidc.yaml" = {
|
|
||||||
owner = "matrix-synapse";
|
|
||||||
content = ''
|
|
||||||
oidc_providers:
|
|
||||||
- discover: true
|
|
||||||
idp_id: zitadel
|
|
||||||
idp_name: Zitadel
|
|
||||||
issuer: "https://auth.kruining.eu"
|
|
||||||
scopes:
|
|
||||||
- openid
|
|
||||||
- profile
|
|
||||||
client_id: '${config.sops.placeholder."synapse/oidc_id"}'
|
|
||||||
client_secret: '${config.sops.placeholder."synapse/oidc_secret"}'
|
|
||||||
backchannel_logout_enabled: true
|
|
||||||
user_mapping_provider:
|
|
||||||
config:
|
|
||||||
localpart_template: "{{ user.preferred_username }}"
|
|
||||||
display_name_template: "{{ user.name }}"
|
|
||||||
'';
|
|
||||||
restartUnits = ["matrix-synapse.service"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,210 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (builtins) toString;
|
|
||||||
inherit (lib) mkIf mkEnableOption mkOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.development.forgejo;
|
|
||||||
domain = "git.amarth.cloud";
|
|
||||||
in {
|
|
||||||
options.${namespace}.services.development.forgejo = {
|
|
||||||
enable = mkEnableOption "Forgejo";
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 5002;
|
|
||||||
example = "1234";
|
|
||||||
description = ''
|
|
||||||
Which port to bind forgejo to
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
${namespace}.services = {
|
|
||||||
persistance.postgresql.enable = true;
|
|
||||||
virtualisation.podman.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [forgejo];
|
|
||||||
|
|
||||||
services = {
|
|
||||||
forgejo = {
|
|
||||||
enable = true;
|
|
||||||
useWizard = false;
|
|
||||||
database.type = "postgres";
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
DEFAULT = {
|
|
||||||
APP_NAME = "Tamin Amarth";
|
|
||||||
APP_SLOGAN = "Where code is forged";
|
|
||||||
};
|
|
||||||
|
|
||||||
server = {
|
|
||||||
DOMAIN = domain;
|
|
||||||
ROOT_URL = "https://${domain}/";
|
|
||||||
HTTP_PORT = cfg.port;
|
|
||||||
LANDING_PAGE = "explore";
|
|
||||||
};
|
|
||||||
|
|
||||||
cors = {
|
|
||||||
ENABLED = true;
|
|
||||||
ALLOW_DOMAIN = "https://*.amarth.cloud";
|
|
||||||
};
|
|
||||||
|
|
||||||
security = {
|
|
||||||
INSTALL_LOCK = true;
|
|
||||||
PASSWORD_HASH_ALGO = "argon2";
|
|
||||||
DISABLE_WEBHOOKS = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
ui = {
|
|
||||||
EXPLORE_PAGING_NUM = 50;
|
|
||||||
ISSUE_PAGING_NUM = 50;
|
|
||||||
MEMBERS_PAGING_NUM = 50;
|
|
||||||
};
|
|
||||||
|
|
||||||
"ui.meta" = {
|
|
||||||
AUTHOR = "Where code is forged!";
|
|
||||||
DESCRIPTION = "Self-hosted solution for git, because FOSS is the anvil of the future";
|
|
||||||
};
|
|
||||||
|
|
||||||
admin = {
|
|
||||||
USER_DISABLED_FEATURES = "manage_gpg_keys";
|
|
||||||
EXTERNAL_USER_DISABLE_FEATURES = "manage_gpg_keys";
|
|
||||||
};
|
|
||||||
|
|
||||||
service = {
|
|
||||||
# Auth
|
|
||||||
ENABLE_BASIC_AUTHENTICATION = false;
|
|
||||||
DISABLE_REGISTRATION = false;
|
|
||||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
|
||||||
SHOW_REGISTRATION_BUTTON = false;
|
|
||||||
|
|
||||||
# Privacy
|
|
||||||
DEFAULT_KEEP_EMAIL_PRIVATE = true;
|
|
||||||
DEFAULT_USER_VISIBILITY = "private";
|
|
||||||
DEFAULT_ORG_VISIBILITY = "private";
|
|
||||||
|
|
||||||
# Common sense
|
|
||||||
VALID_SITE_URL_SCHEMES = "https";
|
|
||||||
};
|
|
||||||
|
|
||||||
openid = {
|
|
||||||
ENABLE_OPENID_SIGNIN = true;
|
|
||||||
ENABLE_OPENID_SIGNUP = true;
|
|
||||||
WHITELISTED_URIS = "https://auth.kruining.eu";
|
|
||||||
};
|
|
||||||
|
|
||||||
oauth2_client = {
|
|
||||||
ENABLE_AUTO_REGISTRATION = true;
|
|
||||||
UPDATE_AVATAR = true;
|
|
||||||
ACCOUNT_LINKING = "auto";
|
|
||||||
};
|
|
||||||
|
|
||||||
actions = {
|
|
||||||
ENABLED = true;
|
|
||||||
# DEFAULT_ACTIONS_URL = "https://data.forgejo.org";
|
|
||||||
};
|
|
||||||
|
|
||||||
other = {
|
|
||||||
SHOW_FOOTER_VERSION = false;
|
|
||||||
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
metrics = {
|
|
||||||
ENABLED = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
api = {
|
|
||||||
ENABLE_SWAGGER = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
mirror = {
|
|
||||||
ENABLED = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
session = {
|
|
||||||
PROVIDER = "db";
|
|
||||||
COOKIE_SECURE = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
mailer = {
|
|
||||||
ENABLED = true;
|
|
||||||
PROTOCOL = "smtp+starttls";
|
|
||||||
SMTP_ADDR = "black-mail.nl";
|
|
||||||
SMTP_PORT = 587;
|
|
||||||
FROM = "chris@kruining.eu";
|
|
||||||
USER = "chris@kruining.eu";
|
|
||||||
PASSWD_URI = "file:${config.sops.secrets."forgejo/email".path}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
openssh.settings.AllowUsers = ["forgejo"];
|
|
||||||
|
|
||||||
gitea-actions-runner = {
|
|
||||||
package = pkgs.forgejo-runner;
|
|
||||||
instances.default = {
|
|
||||||
enable = true;
|
|
||||||
name = "default";
|
|
||||||
url = "https://git.amarth.cloud";
|
|
||||||
# Obtaining the path to the runner token file may differ
|
|
||||||
# tokenFile should be in format TOKEN=<secret>, since it's EnvironmentFile for systemd
|
|
||||||
tokenFile = config.sops.secrets."forgejo/action_runner_token".path;
|
|
||||||
# token = "ZBetud1F0IQ9VjVFpZ9bu0FXgx9zcsy1x25yvjhw";
|
|
||||||
labels = [
|
|
||||||
"default:docker://nixos/nix:latest"
|
|
||||||
"ubuntu:docker://ubuntu:24-bookworm"
|
|
||||||
"nix:docker://git.amarth.cloud/amarth/runners/default:latest"
|
|
||||||
];
|
|
||||||
settings = {
|
|
||||||
log.level = "info";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
caddy = {
|
|
||||||
enable = true;
|
|
||||||
virtualHosts = {
|
|
||||||
"${domain}".extraConfig = ''
|
|
||||||
# import auth
|
|
||||||
|
|
||||||
# stupid dumb way to prevent the login page and go to zitadel instead
|
|
||||||
# be aware that this does not disable local login at all!
|
|
||||||
# rewrite /user/login /user/oauth2/Zitadel
|
|
||||||
|
|
||||||
reverse_proxy http://127.0.0.1:${toString cfg.port}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users = {
|
|
||||||
users."gitea-runner" = {
|
|
||||||
isSystemUser = true;
|
|
||||||
group = "gitea-runner";
|
|
||||||
};
|
|
||||||
groups."gitea-runner" = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.secrets = {
|
|
||||||
"forgejo/action_runner_token" = {
|
|
||||||
owner = "gitea-runner";
|
|
||||||
group = "gitea-runner";
|
|
||||||
restartUnits = ["gitea-runner-default.service"];
|
|
||||||
};
|
|
||||||
|
|
||||||
"forgejo/email" = {
|
|
||||||
owner = "forgejo";
|
|
||||||
group = "forgejo";
|
|
||||||
key = "email/chris_kruining_eu";
|
|
||||||
restartUnits = ["forgejo.service"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +1,11 @@
|
||||||
{
|
{ pkgs, lib, namespace, config, ... }:
|
||||||
pkgs,
|
let
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib) mkIf mkEnableOption mkOption;
|
inherit (lib) mkIf mkEnableOption mkOption;
|
||||||
inherit (lib.types) str;
|
inherit (lib.types) str;
|
||||||
|
|
||||||
cfg = config.${namespace}.services.media;
|
cfg = config.${namespace}.services.media;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.${namespace}.services.media = {
|
options.${namespace}.services.media = {
|
||||||
enable = mkEnableOption "Enable media services";
|
enable = mkEnableOption "Enable media services";
|
||||||
|
|
||||||
|
|
@ -56,55 +52,105 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
# "d '${cfg.path}/series' 0770 ${cfg.user} ${cfg.group} - -"
|
"d '${cfg.path}/series' 0700 ${cfg.user} ${cfg.group} - -"
|
||||||
# "d '${cfg.path}/movies' 0770 ${cfg.user} ${cfg.group} - -"
|
"d '${cfg.path}/movies' 0700 ${cfg.user} ${cfg.group} - -"
|
||||||
# "d '${cfg.path}/music' 0770 ${cfg.user} ${cfg.group} - -"
|
"d '${cfg.path}/music' 0700 ${cfg.user} ${cfg.group} - -"
|
||||||
"d '${cfg.path}/qbittorrent' 0770 ${cfg.user} ${cfg.group} - -"
|
"d '${cfg.path}/qbittorrent' 0700 ${cfg.user} ${cfg.group} - -"
|
||||||
"d '${cfg.path}/sabnzbd' 0770 ${cfg.user} ${cfg.group} - -"
|
"d '${cfg.path}/sabnzbd' 0700 ${cfg.user} ${cfg.group} - -"
|
||||||
"d '${cfg.path}/downloads/incomplete' 0770 ${cfg.user} ${cfg.group} - -"
|
"d '${cfg.path}/reiverr/config' 0700 ${cfg.user} ${cfg.group} - -"
|
||||||
"d '${cfg.path}/downloads/done' 0770 ${cfg.user} ${cfg.group} - -"
|
"d '${cfg.path}/downloads/incomplete' 0700 ${cfg.user} ${cfg.group} - -"
|
||||||
|
"d '${cfg.path}/downloads/done' 0700 ${cfg.user} ${cfg.group} - -"
|
||||||
];
|
];
|
||||||
|
|
||||||
#=========================================================================
|
#=========================================================================
|
||||||
# Services
|
# Services
|
||||||
#=========================================================================
|
#=========================================================================
|
||||||
services = {
|
services = let
|
||||||
bazarr = {
|
serviceConf = {
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
user = cfg.user;
|
|
||||||
group = cfg.group;
|
|
||||||
listenPort = 2005;
|
|
||||||
};
|
|
||||||
|
|
||||||
flaresolverr = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
port = 2007;
|
|
||||||
};
|
|
||||||
|
|
||||||
# port is harcoded in nixpkgs module
|
|
||||||
jellyfin = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
user = cfg.user;
|
user = cfg.user;
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
};
|
};
|
||||||
|
in {
|
||||||
|
jellyfin = serviceConf;
|
||||||
|
radarr = serviceConf;
|
||||||
|
sonarr = serviceConf;
|
||||||
|
bazarr = serviceConf;
|
||||||
|
lidarr = serviceConf;
|
||||||
|
|
||||||
postgresql = {
|
jellyseerr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
prowlarr = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
qbittorrent = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
webuiPort = 5000;
|
||||||
|
|
||||||
|
serverConfig = {
|
||||||
|
LegalNotice.Accepted = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
user = cfg.user;
|
||||||
|
group = cfg.group;
|
||||||
|
};
|
||||||
|
|
||||||
|
sabnzbd = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
configFile = "${cfg.path}/sabnzbd/config.ini";
|
||||||
|
|
||||||
|
user = cfg.user;
|
||||||
|
group = cfg.group;
|
||||||
};
|
};
|
||||||
|
|
||||||
caddy = {
|
caddy = {
|
||||||
enable = true;
|
enable = true;
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
|
"media.kruining.eu".extraConfig = ''
|
||||||
|
import auth
|
||||||
|
|
||||||
|
reverse_proxy http://127.0.0.1:9494
|
||||||
|
'';
|
||||||
"jellyfin.kruining.eu".extraConfig = ''
|
"jellyfin.kruining.eu".extraConfig = ''
|
||||||
reverse_proxy http://[::1]:8096
|
reverse_proxy http://127.0.0.1:8096
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.jellyfin.serviceConfig.killSignal = lib.mkForce "SIGKILL";
|
systemd.services.jellyfin.serviceConfig.killSignal = lib.mkForce "SIGKILL";
|
||||||
|
|
||||||
|
${namespace}.services.virtualisation.podman.enable = true;
|
||||||
|
|
||||||
|
virtualisation = {
|
||||||
|
oci-containers = {
|
||||||
|
backend = "podman";
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
flaresolverr = {
|
||||||
|
image = "flaresolverr/flaresolverr";
|
||||||
|
autoStart = true;
|
||||||
|
ports = [ "127.0.0.1:8191:8191" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
reiverr = {
|
||||||
|
image = "ghcr.io/aleksilassila/reiverr:v2.2.0";
|
||||||
|
autoStart = true;
|
||||||
|
ports = [ "127.0.0.1:9494:9494" ];
|
||||||
|
volumes = [ "${cfg.path}/reiverr/config:/config" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 6969 ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,183 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.media.glance;
|
|
||||||
in {
|
|
||||||
options.${namespace}.services.media.glance = {
|
|
||||||
enable = mkEnableOption "Enable Glance";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
services.glance = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
|
|
||||||
environmentFile = config.sops.templates."glance/secrets.env".path;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
host = "0.0.0.0";
|
|
||||||
port = 2000;
|
|
||||||
};
|
|
||||||
|
|
||||||
theme = {
|
|
||||||
# Teal city predefined theme (https://github.com/glanceapp/glance/blob/main/docs/themes.md#teal-city)
|
|
||||||
background-color = "225 14 15";
|
|
||||||
primary-color = "157 47 65";
|
|
||||||
contrast-multiplier = 1.1;
|
|
||||||
};
|
|
||||||
|
|
||||||
pages = [
|
|
||||||
{
|
|
||||||
name = "Home";
|
|
||||||
columns = [
|
|
||||||
{
|
|
||||||
size = "small";
|
|
||||||
widgets = [
|
|
||||||
{
|
|
||||||
type = "calendar";
|
|
||||||
first-day-of-the-week = "monday";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
size = "full";
|
|
||||||
widgets = [
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "Services";
|
|
||||||
sites = [
|
|
||||||
{
|
|
||||||
title = "Zitadel";
|
|
||||||
url = "https://auth.kruining.eu";
|
|
||||||
icon = "sh:zitadel";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
title = "Forgejo";
|
|
||||||
url = "https://git.amarth.cloud/chris";
|
|
||||||
icon = "sh:forgejo";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
title = "Vaultwarden";
|
|
||||||
url = "https://vault.kruining.eu";
|
|
||||||
icon = "sh:vaultwarden";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "Observability";
|
|
||||||
sites = [
|
|
||||||
{
|
|
||||||
title = "Grafana";
|
|
||||||
url = "http://${config.networking.hostName}:${builtins.toString config.services.grafana.settings.server.http_port}";
|
|
||||||
icon = "sh:grafana";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
title = "Prometheus";
|
|
||||||
url = "http://${config.networking.hostName}:${builtins.toString config.services.prometheus.port}";
|
|
||||||
icon = "sh:prometheus";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "Media";
|
|
||||||
sites = [
|
|
||||||
{
|
|
||||||
title = "Jellyfin";
|
|
||||||
url = "http://${config.networking.hostName}:8096";
|
|
||||||
icon = "sh:jellyfin";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
title = "Radarr";
|
|
||||||
url = "http://${config.networking.hostName}:2001";
|
|
||||||
icon = "sh:radarr";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
title = "Sonarr";
|
|
||||||
url = "http://${config.networking.hostName}:2002";
|
|
||||||
icon = "sh:sonarr";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
title = "Lidarr";
|
|
||||||
url = "http://${config.networking.hostName}:2003";
|
|
||||||
icon = "sh:lidarr";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
title = "Prowlarr";
|
|
||||||
url = "http://${config.networking.hostName}:2004";
|
|
||||||
icon = "sh:prowlarr";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
title = "qBittorrent";
|
|
||||||
url = "http://${config.networking.hostName}:${builtins.toString config.services.qbittorrent.webuiPort}";
|
|
||||||
icon = "sh:qbittorrent";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
title = "SABnzbd";
|
|
||||||
url = "http://${config.networking.hostName}:8080";
|
|
||||||
icon = "sh:sabnzbd";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "videos";
|
|
||||||
channels = [
|
|
||||||
"UCXuqSBlHAE6Xw-yeJA0Tunw" # Linus Tech Tips
|
|
||||||
"UCR-DXc1voovS8nhAvccRZhg" # Jeff Geerling
|
|
||||||
"UCsBjURrPoezykLs9EqgamOA" # Fireship
|
|
||||||
"UCBJycsmduvYEL83R_U4JriQ" # Marques Brownlee
|
|
||||||
"UCHnyfMqiRRG1u-2MsSQLbXA" # Veritasium
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
size = "small";
|
|
||||||
widgets = [
|
|
||||||
{
|
|
||||||
type = "weather";
|
|
||||||
location = "Amsterdam, The Netherlands";
|
|
||||||
units = "metric";
|
|
||||||
hour-format = "24h";
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
type = "server-stats";
|
|
||||||
servers = [
|
|
||||||
{
|
|
||||||
type = "local";
|
|
||||||
name = "Ulmo";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.templates."glance/secrets.env" = {
|
|
||||||
# owner = config.services.glance.user;
|
|
||||||
# group = config.services.glance.group;
|
|
||||||
content = ''
|
|
||||||
RADARR_KEY="${config.sops.placeholder."radarr/apikey"}"
|
|
||||||
SONARR_KEY="${config.sops.placeholder."sonarr/apikey"}"
|
|
||||||
LIDARR_KEY="${config.sops.placeholder."lidarr/apikey"}"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
inputs,
|
|
||||||
system,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.media.mydia;
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
inputs.mydia.nixosModules.default
|
|
||||||
];
|
|
||||||
|
|
||||||
options.${namespace}.services.media.mydia = {
|
|
||||||
enable = mkEnableOption "Enable Mydia";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
services.mydia = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
port = 2010;
|
|
||||||
listenAddress = "0.0.0.0";
|
|
||||||
openFirewall = true;
|
|
||||||
|
|
||||||
mediaLibraries = [
|
|
||||||
"/var/mydia/movies"
|
|
||||||
"/var/mydia/series"
|
|
||||||
];
|
|
||||||
|
|
||||||
database = {
|
|
||||||
# type = "sqlite";
|
|
||||||
# uri = "file:///var/lib/mydia/mydia.db";
|
|
||||||
type = "postgres";
|
|
||||||
uri = "postgres://mydia@localhost:5432/mydia?sslmode=disable";
|
|
||||||
passwordFile = config.sops.templates."mydia/database_password".path;
|
|
||||||
};
|
|
||||||
|
|
||||||
secretKeyBaseFile = config.sops.secrets."mydia/secret_key_base".path;
|
|
||||||
guardianSecretKeyFile = config.sops.secrets."mydia/guardian_secret".path;
|
|
||||||
|
|
||||||
oidc = {
|
|
||||||
enable = true;
|
|
||||||
issuer = "https://auth.kruining.eu";
|
|
||||||
clientIdFile = config.sops.secrets."mydia/oidc_id".path;
|
|
||||||
clientSecretFile = config.sops.secrets."mydia/oidc_secret".path;
|
|
||||||
scopes = ["openid" "profile" "email"];
|
|
||||||
};
|
|
||||||
|
|
||||||
downloadClients = {
|
|
||||||
qbittorrent = {
|
|
||||||
type = "qbittorrent";
|
|
||||||
host = "localhost";
|
|
||||||
port = 2008;
|
|
||||||
username = "admin";
|
|
||||||
passwordFile = config.sops.secrets."mydia/qbittorrent_password".path;
|
|
||||||
useSsl = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.secrets = let
|
|
||||||
base =
|
|
||||||
["secret_key_base" "guardian_secret" "oidc_id" "oidc_secret"]
|
|
||||||
|> lib.map (name:
|
|
||||||
lib.nameValuePair "mydia/${name}" {
|
|
||||||
owner = config.services.mydia.user;
|
|
||||||
group = config.services.mydia.group;
|
|
||||||
restartUnits = ["mydia.service"];
|
|
||||||
})
|
|
||||||
|> lib.listToAttrs;
|
|
||||||
in
|
|
||||||
base
|
|
||||||
// {
|
|
||||||
"mydia/qbittorrent_password" = {
|
|
||||||
owner = config.services.mydia.user;
|
|
||||||
group = config.services.mydia.group;
|
|
||||||
restartUnits = ["mydia.service"];
|
|
||||||
key = "qbittorrent/password";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.templates."mydia/database_password" = {
|
|
||||||
owner = config.services.mydia.user;
|
|
||||||
group = config.services.mydia.group;
|
|
||||||
restartUnits = ["mydia.service"];
|
|
||||||
content = ''
|
|
||||||
DATABASE_PASSWORD=""
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,7 @@ let
|
||||||
cfg = config.${namespace}.services.media.nextcloud;
|
cfg = config.${namespace}.services.media.nextcloud;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.${namespace}.services.media.nextcloud = {
|
options.modules.services.nextcloud = {
|
||||||
enable = mkEnableOption "Nextcloud";
|
enable = mkEnableOption "Nextcloud";
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
|
|
@ -40,7 +40,7 @@ in
|
||||||
|
|
||||||
services.nextcloud = {
|
services.nextcloud = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# webserver = "caddy";
|
webserver = "caddy";
|
||||||
package = pkgs.nextcloud31;
|
package = pkgs.nextcloud31;
|
||||||
hostName = "localhost";
|
hostName = "localhost";
|
||||||
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
let
|
let
|
||||||
inherit (lib) mkIf mkEnableOption;
|
inherit (lib) mkIf mkEnableOption;
|
||||||
|
|
||||||
cfg = config.${namespace}.services.media.nfs;
|
cfg = config.${namespace}.media.nfs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.${namespace}.services.media.nfs = {
|
options.${namespace}.media.nfs = {
|
||||||
enable = mkEnableOption "Enable NFS";
|
enable = mkEnableOption "Enable NFS";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1,354 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
inputs,
|
|
||||||
system,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (builtins) toString;
|
|
||||||
inherit (lib) mkIf mkEnableOption mkOption types;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.media.servarr;
|
|
||||||
in {
|
|
||||||
options.${namespace}.services.media = {
|
|
||||||
servarr = mkOption {
|
|
||||||
type = types.attrsOf (types.submodule ({name, ...}: {
|
|
||||||
options = {
|
|
||||||
enable = mkEnableOption "Enable ${name}";
|
|
||||||
debug = mkEnableOption "Use tofu plan instead of tofu apply for ${name} ";
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
};
|
|
||||||
|
|
||||||
rootFolders = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
default = {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
services =
|
|
||||||
cfg
|
|
||||||
|> lib.mapAttrsToList (service: {
|
|
||||||
enable,
|
|
||||||
port,
|
|
||||||
...
|
|
||||||
}: (mkIf enable {
|
|
||||||
"${service}" =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
|
|
||||||
environmentFiles = [
|
|
||||||
config.sops.templates."${service}/config.env".path
|
|
||||||
];
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
auth.authenticationMethod = "External";
|
|
||||||
|
|
||||||
server = {
|
|
||||||
bindaddress = "0.0.0.0";
|
|
||||||
port = port;
|
|
||||||
};
|
|
||||||
|
|
||||||
postgres = {
|
|
||||||
host = "localhost";
|
|
||||||
port = "5432";
|
|
||||||
user = service;
|
|
||||||
maindb = service;
|
|
||||||
logdb = service;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// (lib.optionalAttrs (service != "prowlarr") {
|
|
||||||
user = service;
|
|
||||||
group = "media";
|
|
||||||
});
|
|
||||||
}))
|
|
||||||
|> lib.concat [
|
|
||||||
{
|
|
||||||
qbittorrent = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
webuiPort = 2008;
|
|
||||||
|
|
||||||
serverConfig = {
|
|
||||||
LegalNotice.Accepted = true;
|
|
||||||
|
|
||||||
Prefecences.WebUI = {
|
|
||||||
Username = "admin";
|
|
||||||
Password_PBKDF2 = "@ByteArray(JpfX3wSUcMolUFD+8AD67w==:fr5kmc6sK9xsCfGW6HkPX2K1lPYHL6g2ncLLwuOVmjphmxkwBJ8pi/XQDsDWzyM/MRh5zPhUld2Xqn8o7BWv3Q==)";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
user = "qbittorrent";
|
|
||||||
group = "media";
|
|
||||||
};
|
|
||||||
|
|
||||||
# port is harcoded in nixpkgs module
|
|
||||||
sabnzbd = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
configFile = "/var/media/sabnzbd/config.ini";
|
|
||||||
# configFile = config.sops.templates."sabnzbd/config.ini".path;
|
|
||||||
|
|
||||||
user = "sabnzbd";
|
|
||||||
group = "media";
|
|
||||||
};
|
|
||||||
|
|
||||||
postgresql = {
|
|
||||||
ensureDatabases = cfg |> lib.attrNames;
|
|
||||||
ensureUsers =
|
|
||||||
cfg
|
|
||||||
|> lib.attrNames
|
|
||||||
|> lib.map (service: {
|
|
||||||
name = service;
|
|
||||||
ensureDBOwnership = true;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|> lib.mkMerge;
|
|
||||||
|
|
||||||
systemd.services =
|
|
||||||
cfg
|
|
||||||
|> lib.mapAttrsToList (service: {
|
|
||||||
enable,
|
|
||||||
debug,
|
|
||||||
port,
|
|
||||||
rootFolders,
|
|
||||||
...
|
|
||||||
}: (mkIf enable {
|
|
||||||
"${service}ApplyTerraform" = let
|
|
||||||
config' = config;
|
|
||||||
|
|
||||||
terraformConfiguration = inputs.terranix.lib.terranixConfiguration {
|
|
||||||
inherit system;
|
|
||||||
|
|
||||||
modules = [
|
|
||||||
({
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
config = {
|
|
||||||
variable = {
|
|
||||||
api_key = {
|
|
||||||
type = "string";
|
|
||||||
description = "${service} api key";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
terraform.required_providers.${service} = {
|
|
||||||
source = "devopsarr/${service}";
|
|
||||||
version =
|
|
||||||
{
|
|
||||||
radarr = "2.3.3";
|
|
||||||
sonarr = "3.4.0";
|
|
||||||
prowlarr = "3.1.0";
|
|
||||||
lidarr = "1.13.0";
|
|
||||||
readarr = "2.1.0";
|
|
||||||
whisparr = "1.2.0";
|
|
||||||
}.${
|
|
||||||
service
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
provider.${service} = {
|
|
||||||
url = "http://127.0.0.1:${toString port}";
|
|
||||||
api_key = lib.tfRef "var.api_key";
|
|
||||||
};
|
|
||||||
|
|
||||||
resource = {
|
|
||||||
"${service}_root_folder" = mkIf (lib.elem service ["radarr" "sonarr" "whisparr"]) (
|
|
||||||
rootFolders
|
|
||||||
|> lib.imap (i: f: lib.nameValuePair "local${toString i}" {path = f;})
|
|
||||||
|> lib.listToAttrs
|
|
||||||
);
|
|
||||||
|
|
||||||
"${service}_download_client_qbittorrent" = mkIf (lib.elem service ["radarr" "sonarr" "lidarr" "whisparr"]) {
|
|
||||||
"main" = {
|
|
||||||
name = "qBittorrent";
|
|
||||||
enable = true;
|
|
||||||
priority = 1;
|
|
||||||
host = "localhost";
|
|
||||||
username = "admin";
|
|
||||||
password = "poChieN5feeph0igeaCadeJ9Xux0ohmuy6ruH5ieThaPheib3iuzoo0ahw1aiceif1feegioh9Aimau0pai5thoh5ieH0aechohw";
|
|
||||||
url_base = "/";
|
|
||||||
port = 2008;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# "${service}_download_client_sabnzbd" = mkIf (lib.elem service ["radarr" "sonarr" "lidarr" "whisparr"]) {
|
|
||||||
# "main" = {
|
|
||||||
# name = "SABnzbd";
|
|
||||||
# enable = true;
|
|
||||||
# priority = 1;
|
|
||||||
# host = "localhost";
|
|
||||||
# url_base = "/";
|
|
||||||
# port = 8080;
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
description = "${service} terraform apply";
|
|
||||||
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
wants = ["${service}.service"];
|
|
||||||
|
|
||||||
preStart = ''
|
|
||||||
install -d -m 0770 -o ${service} -g media /var/lib/${service}ApplyTerraform
|
|
||||||
${
|
|
||||||
rootFolders
|
|
||||||
|> lib.map (folder: "install -d -m 0770 -o media -g media ${folder}")
|
|
||||||
|> lib.join "\n"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
script = ''
|
|
||||||
# Sleep for a bit to give the service a chance to start up
|
|
||||||
sleep 5s
|
|
||||||
|
|
||||||
if [ "$(systemctl is-active ${service})" != "active" ]; then
|
|
||||||
echo "${service} is not running"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Print the path to the source for easier debugging
|
|
||||||
echo "config location: ${terraformConfiguration}"
|
|
||||||
|
|
||||||
# Copy infra code into workspace
|
|
||||||
cp -f ${terraformConfiguration} config.tf.json
|
|
||||||
|
|
||||||
# Initialize OpenTofu
|
|
||||||
${lib.getExe pkgs.opentofu} init
|
|
||||||
|
|
||||||
# Run the infrastructure code
|
|
||||||
${lib.getExe pkgs.opentofu} \
|
|
||||||
${
|
|
||||||
if debug
|
|
||||||
then "plan"
|
|
||||||
else "apply -auto-approve"
|
|
||||||
} \
|
|
||||||
-var-file='${config.sops.templates."${service}/config.tfvars".path}'
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
User = service;
|
|
||||||
Group = "media";
|
|
||||||
|
|
||||||
WorkingDirectory = "/var/lib/${service}ApplyTerraform";
|
|
||||||
|
|
||||||
EnvironmentFile = [
|
|
||||||
config.sops.templates."${service}/config.env".path
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}))
|
|
||||||
|> lib.mkMerge;
|
|
||||||
|
|
||||||
users =
|
|
||||||
cfg
|
|
||||||
|> lib.mapAttrsToList (service: {enable, ...}: (mkIf enable {
|
|
||||||
users.${service} = {
|
|
||||||
isSystemUser = true;
|
|
||||||
group = lib.mkDefault service;
|
|
||||||
extraGroups = ["media"];
|
|
||||||
};
|
|
||||||
groups.${service} = {};
|
|
||||||
}))
|
|
||||||
|> lib.mkMerge;
|
|
||||||
|
|
||||||
sops =
|
|
||||||
cfg
|
|
||||||
|> lib.mapAttrsToList (service: {enable, ...}: (mkIf enable {
|
|
||||||
secrets."${service}/apikey" = {
|
|
||||||
owner = service;
|
|
||||||
group = "media";
|
|
||||||
restartUnits = ["${service}.service"];
|
|
||||||
};
|
|
||||||
|
|
||||||
templates = {
|
|
||||||
"${service}/config.env" = {
|
|
||||||
owner = service;
|
|
||||||
group = "media";
|
|
||||||
restartUnits = ["${service}.service"];
|
|
||||||
content = ''
|
|
||||||
${lib.toUpper service}__AUTH__APIKEY="${config.sops.placeholder."${service}/apikey"}"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
"${service}/config.tfvars" = {
|
|
||||||
owner = service;
|
|
||||||
group = "media";
|
|
||||||
restartUnits = ["${service}.service"];
|
|
||||||
content = ''
|
|
||||||
api_key = "${config.sops.placeholder."${service}/apikey"}"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}))
|
|
||||||
|> lib.concat [
|
|
||||||
{
|
|
||||||
secrets = {
|
|
||||||
"sabnzbd/apikey" = {};
|
|
||||||
"sabnzbd/sunnyweb/username" = {};
|
|
||||||
"sabnzbd/sunnyweb/password" = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
templates = {
|
|
||||||
"sabnzbd/config.ini" = {
|
|
||||||
owner = "sabnzbd";
|
|
||||||
group = "media";
|
|
||||||
mode = "0660";
|
|
||||||
content = ''
|
|
||||||
__version__ = 19
|
|
||||||
__encoding__ = utf-8
|
|
||||||
[misc]
|
|
||||||
download_dir = /var/media/downloads/incomplete
|
|
||||||
complete_dir = /var/media/downloads/done
|
|
||||||
api_key = ${config.sops.placeholder."sabnzbd/apikey"}
|
|
||||||
log_dir = logs
|
|
||||||
|
|
||||||
[servers]
|
|
||||||
[[news.sunnyusenet.com]]
|
|
||||||
name = news.sunnyusenet.com
|
|
||||||
displayname = news.sunnyusenet.com
|
|
||||||
host = news.sunnyusenet.com
|
|
||||||
port = 563
|
|
||||||
timeout = 60
|
|
||||||
username = ${config.sops.placeholder."sabnzbd/sunnyweb/username"}
|
|
||||||
password = ${config.sops.placeholder."sabnzbd/sunnyweb/password"}
|
|
||||||
connections = 8
|
|
||||||
ssl = 1
|
|
||||||
ssl_verify = 3
|
|
||||||
ssl_ciphers = ""
|
|
||||||
enable = 1
|
|
||||||
required = 0
|
|
||||||
optional = 0
|
|
||||||
retention = 0
|
|
||||||
expire_date = ""
|
|
||||||
quota = ""
|
|
||||||
usage_at_start = 0
|
|
||||||
priority = 1
|
|
||||||
notes = ""
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|> lib.mkMerge;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"title": "Default Dash",
|
|
||||||
"description": "The default dashboard",
|
|
||||||
"timezone": "browser",
|
|
||||||
"editable": false,
|
|
||||||
"panels": []
|
|
||||||
}
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkIf;
|
|
||||||
inherit (lib.options) mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.observability.grafana;
|
|
||||||
|
|
||||||
db_user = "grafana";
|
|
||||||
db_name = "grafana";
|
|
||||||
in {
|
|
||||||
options.${namespace}.services.observability.grafana = {
|
|
||||||
enable = mkEnableOption "enable Grafana";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
services = {
|
|
||||||
grafana = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
http_port = 9001;
|
|
||||||
http_addr = "0.0.0.0";
|
|
||||||
domain = "ulmo";
|
|
||||||
};
|
|
||||||
|
|
||||||
auth = {
|
|
||||||
disable_login_form = false;
|
|
||||||
oauth_auto_login = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
"auth.basic".enable = false;
|
|
||||||
"auth.generic_oauth" = {
|
|
||||||
enable = true;
|
|
||||||
name = "Zitadel";
|
|
||||||
client_id = "$__file{${config.sops.secrets."grafana/oidc_id".path}}";
|
|
||||||
client_secret = "$__file{${config.sops.secrets."grafana/oidc_secret".path}}";
|
|
||||||
scopes = "openid email profile offline_access urn:zitadel:iam:org:project:roles";
|
|
||||||
email_attribute_path = "email";
|
|
||||||
login_attribute_path = "username";
|
|
||||||
name_attribute_path = "full_name";
|
|
||||||
role_attribute_path = "contains(urn:zitadel:iam:org:project:roles[*], 'owner') && 'GrafanaAdmin' || contains(urn:zitadel:iam:org:project:roles[*], 'contributer') && 'Editor' || 'Viewer'";
|
|
||||||
auth_url = "https://auth.kruining.eu/oauth/v2/authorize";
|
|
||||||
token_url = "https://auth.kruining.eu/oauth/v2/token";
|
|
||||||
api_url = "https://auth.kruining.eu/oidc/v1/userinfo";
|
|
||||||
allow_sign_up = true;
|
|
||||||
auto_login = true;
|
|
||||||
use_pkce = true;
|
|
||||||
usr_refresh_token = true;
|
|
||||||
allow_assign_grafana_admin = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
database = {
|
|
||||||
type = "postgres";
|
|
||||||
host = "/var/run/postgresql:5432";
|
|
||||||
name = db_name;
|
|
||||||
user = db_user;
|
|
||||||
ssl_mode = "disable";
|
|
||||||
};
|
|
||||||
|
|
||||||
users = {
|
|
||||||
allow_sign_up = false;
|
|
||||||
allow_org_create = false;
|
|
||||||
viewers_can_edit = false;
|
|
||||||
|
|
||||||
default_theme = "system";
|
|
||||||
};
|
|
||||||
|
|
||||||
analytics = {
|
|
||||||
reporting_enabled = false;
|
|
||||||
check_for_updates = false;
|
|
||||||
check_for_plugin_updates = false;
|
|
||||||
feedback_links_enabled = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
provision = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
dashboards.settings = {
|
|
||||||
apiVersion = 1;
|
|
||||||
providers = [
|
|
||||||
{
|
|
||||||
name = "Default Dashboard";
|
|
||||||
disableDeletion = true;
|
|
||||||
allowUiUpdates = false;
|
|
||||||
options = {
|
|
||||||
path = "/etc/grafana/dashboards";
|
|
||||||
foldersFromFilesStructure = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
datasources.settings.datasources = [
|
|
||||||
{
|
|
||||||
name = "Prometheus";
|
|
||||||
type = "prometheus";
|
|
||||||
url = "http://localhost:9005";
|
|
||||||
isDefault = true;
|
|
||||||
editable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
name = "Loki";
|
|
||||||
type = "loki";
|
|
||||||
url = "http://localhost:9003";
|
|
||||||
editable = false;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
postgresql = {
|
|
||||||
enable = true;
|
|
||||||
ensureDatabases = [db_name];
|
|
||||||
ensureUsers = [
|
|
||||||
{
|
|
||||||
name = db_user;
|
|
||||||
ensureDBOwnership = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.etc."/grafana/dashboards/default.json".source = ./dashboards/default.json;
|
|
||||||
|
|
||||||
sops = {
|
|
||||||
secrets = {
|
|
||||||
"grafana/oidc_id" = {
|
|
||||||
owner = "grafana";
|
|
||||||
group = "grafana";
|
|
||||||
};
|
|
||||||
"grafana/oidc_secret" = {
|
|
||||||
owner = "grafana";
|
|
||||||
group = "grafana";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
{ pkgs, config, lib, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.modules) mkIf;
|
|
||||||
inherit (lib.options) mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.observability.loki;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.services.observability.loki = {
|
|
||||||
enable = mkEnableOption "enable Grafana Loki";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
services.loki = {
|
|
||||||
enable = true;
|
|
||||||
configuration = {
|
|
||||||
auth_enabled = false;
|
|
||||||
|
|
||||||
server = {
|
|
||||||
http_listen_port = 9003;
|
|
||||||
};
|
|
||||||
|
|
||||||
common = {
|
|
||||||
ring = {
|
|
||||||
instance_addr = "127.0.0.1";
|
|
||||||
kvstore.store = "inmemory";
|
|
||||||
};
|
|
||||||
replication_factor = 1;
|
|
||||||
path_prefix = "/tmp/loki";
|
|
||||||
};
|
|
||||||
|
|
||||||
schema_config.configs = [
|
|
||||||
{
|
|
||||||
from = "2025-01-01";
|
|
||||||
store = "tsdb";
|
|
||||||
object_store = "filesystem";
|
|
||||||
schema = "v13";
|
|
||||||
index = {
|
|
||||||
prefix = "index_";
|
|
||||||
period = "24h";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 9003 ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
{ pkgs, config, lib, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (builtins) toString;
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.observability.prometheus;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.services.observability.prometheus = {
|
|
||||||
enable = mkEnableOption "enable Prometheus";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
services.prometheus = {
|
|
||||||
enable = true;
|
|
||||||
port = 9002;
|
|
||||||
|
|
||||||
globalConfig.scrape_interval = "15s";
|
|
||||||
|
|
||||||
scrapeConfigs = [
|
|
||||||
{
|
|
||||||
job_name = "prometheus";
|
|
||||||
static_configs = [
|
|
||||||
{ targets = [ "localhost:9002" ]; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
job_name = "node";
|
|
||||||
static_configs = [
|
|
||||||
{ targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ]; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
exporters = {
|
|
||||||
node = {
|
|
||||||
enable = true;
|
|
||||||
port = 9005;
|
|
||||||
enabledCollectors = [ "systemd" ];
|
|
||||||
openFirewall = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 9002 ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
{ pkgs, config, lib, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.modules) mkIf;
|
|
||||||
inherit (lib.options) mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.observability.promtail;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.services.observability.promtail = {
|
|
||||||
enable = mkEnableOption "enable Grafana Promtail";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
services.promtail = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
# Ensures proper permissions
|
|
||||||
extraFlags = [
|
|
||||||
"-config.expand-env=true"
|
|
||||||
];
|
|
||||||
|
|
||||||
configuration = {
|
|
||||||
server = {
|
|
||||||
http_listen_port = 9004;
|
|
||||||
grpc_listen_port = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
positions = {
|
|
||||||
filename = "filename";
|
|
||||||
};
|
|
||||||
|
|
||||||
clients = [
|
|
||||||
{
|
|
||||||
url = "http://::1:9003/loki/api/v1/push";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
scrape_configs = [
|
|
||||||
{
|
|
||||||
job_name = "journal";
|
|
||||||
journal = {
|
|
||||||
max_age = "12h";
|
|
||||||
labels = {
|
|
||||||
job = "systemd-journal";
|
|
||||||
host = "ulmo";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
relabel_configs = [
|
|
||||||
{ source_labels = [ "__journal__systemd_unit" ]; target_label = "unit"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 9004 ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
{ pkgs, config, lib, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (builtins) toString;
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.observability.uptime-kuma;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.services.observability.uptime-kuma = {
|
|
||||||
enable = mkEnableOption "enable uptime kuma";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
services.uptime-kuma = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
PORT = toString 9006;
|
|
||||||
HOST = "0.0.0.0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 9006 ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
{ config, lib, pkgs, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib) mkIf mkEnableOption;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.persistance.postgresql;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.services.persistance.postgresql = {
|
|
||||||
enable = mkEnableOption "Postgresql";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
services = {
|
|
||||||
postgresql = {
|
|
||||||
enable = true;
|
|
||||||
authentication = ''
|
|
||||||
# Generated file, do not edit!
|
|
||||||
# TYPE DATABASE USER ADDRESS METHOD
|
|
||||||
local all all trust
|
|
||||||
host all all 127.0.0.1/32 trust
|
|
||||||
host all all ::1/128 trust
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,219 +1,28 @@
|
||||||
{
|
{ pkgs, config, lib, namespace, ... }:
|
||||||
pkgs,
|
let
|
||||||
config,
|
inherit (lib.modules) mkIf;
|
||||||
lib,
|
inherit (lib.options) mkEnableOption;
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (builtins) toString;
|
|
||||||
inherit (lib) mkIf mkEnableOption mkOption types getAttrs toUpper concatMapAttrsStringSep;
|
|
||||||
|
|
||||||
cfg = config.${namespace}.services.security.vaultwarden;
|
cfg = config.${namespace}.services.security.vaultwarden;
|
||||||
|
in
|
||||||
databaseProviderSqlite = types.submodule ({...}: {
|
{
|
||||||
options = {
|
|
||||||
type = mkOption {
|
|
||||||
type = types.enum ["sqlite"];
|
|
||||||
};
|
|
||||||
|
|
||||||
file = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = ''
|
|
||||||
Path to sqlite database file.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
databaseProviderPostgresql = types.submodule ({...}: let
|
|
||||||
urlOptions = lib.${namespace}.options.mkUrlOptions {
|
|
||||||
host = {
|
|
||||||
description = ''
|
|
||||||
Hostname of the postgresql server
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
port = {
|
|
||||||
default = 5432;
|
|
||||||
example = "5432";
|
|
||||||
description = ''
|
|
||||||
Port of the postgresql server
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
protocol = mkOption {
|
|
||||||
default = "postgres";
|
|
||||||
example = "postgres";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
options =
|
|
||||||
{
|
|
||||||
type = mkOption {
|
|
||||||
type = types.enum ["postgresql"];
|
|
||||||
};
|
|
||||||
|
|
||||||
sslMode = mkOption {
|
|
||||||
type = types.enum ["verify-ca" "verify-full" "require" "prefer" "allow" "disabled"];
|
|
||||||
default = "verify-full";
|
|
||||||
example = "verify-ca";
|
|
||||||
description = ''
|
|
||||||
How to verify the server's ssl
|
|
||||||
|
|
||||||
| mode | eavesdropping protection | MITM protection | Statement |
|
|
||||||
|-------------|--------------------------|----------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
|
||||||
| disable | No | No | I don't care about security, and I don't want to pay the overhead of encryption. |
|
|
||||||
| allow | Maybe | No | I don't care about security, but I will pay the overhead of encryption if the server insists on it. |
|
|
||||||
| prefer | Maybe | No | I don't care about encryption, but I wish to pay the overhead of encryption if the server supports it. |
|
|
||||||
| require | Yes | No | I want my data to be encrypted, and I accept the overhead. I trust that the network will make sure I always connect to the server I want. |
|
|
||||||
| verify-ca | Yes | Depends on CA policy | I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server that I trust. |
|
|
||||||
| verify-full | Yes | Yes | I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server I trust, and that it's the one I specify. |
|
|
||||||
|
|
||||||
[Source](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// (urlOptions |> getAttrs ["protocol" "host" "port"]);
|
|
||||||
});
|
|
||||||
in {
|
|
||||||
options.${namespace}.services.security.vaultwarden = {
|
options.${namespace}.services.security.vaultwarden = {
|
||||||
enable = mkEnableOption "enable vaultwarden";
|
enable = mkEnableOption "enable vaultwarden";
|
||||||
|
|
||||||
database = mkOption {
|
|
||||||
type = types.oneOf [
|
|
||||||
(types.addCheck databaseProviderSqlite (x: x ? type && x.type == "sqlite"))
|
|
||||||
(types.addCheck databaseProviderPostgresql (x: x ? type && x.type == "postgresql"))
|
|
||||||
null
|
|
||||||
];
|
|
||||||
default = null;
|
|
||||||
description = '''';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.tmpfiles.rules = [
|
environment.systemPackages = with pkgs; [
|
||||||
"d '/var/lib/vaultwarden' 0700 vaultwarden vaultwarden - -"
|
vaultwarden
|
||||||
|
vaultwarden-postgresql
|
||||||
];
|
];
|
||||||
|
|
||||||
# systemd.services.vaultwarden.wants = [ "zitadelApplyTerraform.service" ];
|
services.vaultwarden = {
|
||||||
|
enable = true;
|
||||||
|
dbBackend = "postgresql";
|
||||||
|
|
||||||
services = {
|
config = {
|
||||||
vaultwarden = {
|
SIGNUPS_ALLOWED = false;
|
||||||
enable = true;
|
DOMAIN = "https://passwords.kruining.eu";
|
||||||
dbBackend = "postgresql";
|
|
||||||
|
|
||||||
package = pkgs.${namespace}.vaultwarden;
|
|
||||||
|
|
||||||
config = {
|
|
||||||
SIGNUPS_ALLOWED = false;
|
|
||||||
DOMAIN = "https://vault.kruining.eu";
|
|
||||||
|
|
||||||
DATABASE_URL = "postgres://localhost:5432/vaultwarden?sslmode=disable";
|
|
||||||
|
|
||||||
WEB_VAULT_ENABLED = true;
|
|
||||||
|
|
||||||
SSO_ENABLED = true;
|
|
||||||
SSO_ONLY = true;
|
|
||||||
SSO_PKCE = true;
|
|
||||||
SSO_AUTH_ONLY_NOT_SESSION = false;
|
|
||||||
SSO_ROLES_ENABLED = true;
|
|
||||||
SSO_ORGANIZATIONS_ENABLED = true;
|
|
||||||
SSO_ORGANIZATIONS_REVOCATION = true;
|
|
||||||
SSO_AUTHORITY = "https://auth.kruining.eu/";
|
|
||||||
SSO_SCOPES = "email profile offline_access";
|
|
||||||
|
|
||||||
ROCKET_ADDRESS = "::1";
|
|
||||||
ROCKET_PORT = 8222;
|
|
||||||
ROCKET_LOG = "critical";
|
|
||||||
|
|
||||||
SMTP_HOST = "black-mail.nl";
|
|
||||||
SMTP_PORT = 587;
|
|
||||||
SMTP_SECURITY = "starttls";
|
|
||||||
SMTP_USERNAME = "chris@kruining.eu";
|
|
||||||
SMTP_FROM = "chris@kruining.eu";
|
|
||||||
SMTP_FROM_NAME = "Chris' Vaultwarden";
|
|
||||||
};
|
|
||||||
|
|
||||||
environmentFile = [
|
|
||||||
"/var/lib/zitadel/clients/nix_ulmo_vaultwarden"
|
|
||||||
config.sops.templates."vaultwarden/config.env".path
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
postgresql = {
|
|
||||||
enable = true;
|
|
||||||
ensureDatabases = ["vaultwarden"];
|
|
||||||
ensureUsers = [
|
|
||||||
{
|
|
||||||
name = "vaultwarden";
|
|
||||||
ensureDBOwnership = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
caddy = {
|
|
||||||
enable = true;
|
|
||||||
virtualHosts = {
|
|
||||||
"vault.kruining.eu".extraConfig = ''
|
|
||||||
encode zstd gzip
|
|
||||||
|
|
||||||
handle_path /admin {
|
|
||||||
respond 401 {
|
|
||||||
close
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_proxy http://localhost:${toString config.services.vaultwarden.config.ROCKET_PORT} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops = {
|
|
||||||
secrets = {
|
|
||||||
"vaultwarden/email" = {
|
|
||||||
owner = config.users.users.vaultwarden.name;
|
|
||||||
group = config.users.users.vaultwarden.name;
|
|
||||||
key = "email/chris_kruining_eu";
|
|
||||||
restartUnits = ["vaultwarden.service"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
templates = {
|
|
||||||
"vaultwarden/config.env" = {
|
|
||||||
content = ''
|
|
||||||
SMTP_PASSWORD='${config.sops.placeholder."vaultwarden/email"}';
|
|
||||||
'';
|
|
||||||
owner = config.users.users.vaultwarden.name;
|
|
||||||
group = config.users.groups.vaultwarden.name;
|
|
||||||
};
|
|
||||||
temp-db-output.content = let
|
|
||||||
config =
|
|
||||||
cfg.database
|
|
||||||
|> (
|
|
||||||
{type, ...} @ db:
|
|
||||||
if type == "sqlite"
|
|
||||||
then {inherit (db) type file;}
|
|
||||||
else if type == "postgresql"
|
|
||||||
then {
|
|
||||||
inherit (db) type;
|
|
||||||
url = lib.${namespace}.strings.toUrl {
|
|
||||||
inherit (db) protocol host port;
|
|
||||||
path = "vaultwarden";
|
|
||||||
query = {
|
|
||||||
sslmode = db.sslMode;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
|> concatMapAttrsStringSep "\n" (n: v: "${toUpper n}=${v}");
|
|
||||||
in ''
|
|
||||||
# GENERATED VALUES
|
|
||||||
${config}
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ in
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
containers.enable = true;
|
containers.enable = true;
|
||||||
oci-containers.backend = "podman";
|
|
||||||
|
|
||||||
podman = {
|
podman = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
{...}: {
|
{ ... }:
|
||||||
}
|
{}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ pkgs, config, namespace, inputs, system, ... }:
|
{ pkgs, config, namespace, inputs, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.${namespace}.system.security.sops;
|
cfg = config.${namespace}.system.security.sops;
|
||||||
in
|
in
|
||||||
|
|
@ -13,14 +13,10 @@ in
|
||||||
environment.systemPackages = with pkgs; [ sops ];
|
environment.systemPackages = with pkgs; [ sops ];
|
||||||
|
|
||||||
sops = {
|
sops = {
|
||||||
defaultSopsFormat = "yaml";
|
age.keyFile = "/home/.sops-key.age";
|
||||||
defaultSopsFile = inputs.self + "/systems/${system}/${config.networking.hostName}/secrets.yml";
|
|
||||||
|
|
||||||
age = {
|
defaultSopsFile = ../../../../systems/x86_64-linux/${config.networking.hostName}/secrets.yaml;
|
||||||
# keyFile = "~/.config/sops/age/keys.txt";
|
defaultSopsFormat = "yaml";
|
||||||
# sshKeyPaths = [ "~/.ssh/id_ed25519" ];
|
|
||||||
# generateKey = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -14,8 +14,9 @@ in
|
||||||
|
|
||||||
sudo-rs = {
|
sudo-rs = {
|
||||||
enable = true;
|
enable = true;
|
||||||
execWheelOnly = true;
|
extraConfig = ''
|
||||||
extraConfig = ''Defaults env_keep += "EDITOR PATH DISPLAY"'';
|
Defaults env_keep += "EDITOR PATH DISPLAY"
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
{ lib, stdenv, rustPlatform, fetchFromGitHub, openssl, pkg-config, postgresql, dbBackend ? "postgresql", ... }:
|
|
||||||
rustPlatform.buildRustPackage rec {
|
|
||||||
pname = "vaultwarden";
|
|
||||||
version = "1.34.3";
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "Timshel";
|
|
||||||
repo = "vaultwarden";
|
|
||||||
rev = "1.34.3";
|
|
||||||
hash = "sha256-Dj0ySVRvBZ/57+UHas3VI8bi/0JBRqn0IW1Dq+405J0=";
|
|
||||||
};
|
|
||||||
|
|
||||||
cargoHash = "sha256-4sDagd2XGamBz1XvDj4ycRVJ0F+4iwHOPlj/RglNDqE=";
|
|
||||||
|
|
||||||
# used for "Server Installed" version in admin panel
|
|
||||||
env.VW_VERSION = version;
|
|
||||||
|
|
||||||
nativeBuildInputs = [ pkg-config ];
|
|
||||||
buildInputs =
|
|
||||||
[ openssl ]
|
|
||||||
++ lib.optional (dbBackend == "postgresql") postgresql;
|
|
||||||
|
|
||||||
buildFeatures = dbBackend;
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
license = licenses.agpl3Only;
|
|
||||||
mainProgram = "vaultwarden";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
395
sabnzbd.ini
395
sabnzbd.ini
|
|
@ -1,395 +0,0 @@
|
||||||
__version__ = 19
|
|
||||||
__encoding__ = utf-8
|
|
||||||
[misc]
|
|
||||||
helpful_warnings = 1
|
|
||||||
queue_complete = hibernate_pc
|
|
||||||
queue_complete_pers = 0
|
|
||||||
bandwidth_perc = 100
|
|
||||||
refresh_rate = 1
|
|
||||||
interface_settings = '{"dateFormat":"YYYY-MM-DD HH:mm","extraQueueColumns":[],"extraHistoryColumns":[],"displayCompact":false,"displayFullWidth":false,"confirmDeleteQueue":true,"confirmDeleteHistory":true,"keyboardShortcuts":true}'
|
|
||||||
queue_limit = 20
|
|
||||||
config_lock = 0
|
|
||||||
fixed_ports = 1
|
|
||||||
notified_new_skin = 2
|
|
||||||
direct_unpack_tested = 1
|
|
||||||
sorters_converted = 1
|
|
||||||
check_new_rel = 1
|
|
||||||
auto_browser = 0
|
|
||||||
language = en
|
|
||||||
enable_https_verification = 0
|
|
||||||
host = 0.0.0.0
|
|
||||||
port = 8080
|
|
||||||
https_port = ""
|
|
||||||
username = ""
|
|
||||||
password = ""
|
|
||||||
bandwidth_max = ""
|
|
||||||
cache_limit = 1G
|
|
||||||
web_dir = Glitter
|
|
||||||
web_color = Auto
|
|
||||||
https_cert = server.cert
|
|
||||||
https_key = server.key
|
|
||||||
https_chain = ""
|
|
||||||
enable_https = 0
|
|
||||||
inet_exposure = 0
|
|
||||||
api_key = 0052eba0db9d4b4f93a8a96f0cb85198
|
|
||||||
nzb_key = 171ebeb3e0044c379dc7719bef6b3144
|
|
||||||
socks5_proxy_url = ""
|
|
||||||
permissions = ""
|
|
||||||
download_dir = /var/media/downloads/incomplete
|
|
||||||
download_free = ""
|
|
||||||
complete_dir = /var/media/downloads/done
|
|
||||||
complete_free = ""
|
|
||||||
fulldisk_autoresume = 0
|
|
||||||
script_dir = ""
|
|
||||||
nzb_backup_dir = ""
|
|
||||||
admin_dir = admin
|
|
||||||
backup_dir = ""
|
|
||||||
dirscan_dir = ""
|
|
||||||
dirscan_speed = 5
|
|
||||||
password_file = ""
|
|
||||||
log_dir = logs
|
|
||||||
max_art_tries = 3
|
|
||||||
top_only = 0
|
|
||||||
sfv_check = 1
|
|
||||||
script_can_fail = 0
|
|
||||||
enable_recursive = 1
|
|
||||||
flat_unpack = 0
|
|
||||||
par_option = ""
|
|
||||||
pre_check = 0
|
|
||||||
nice = ""
|
|
||||||
win_process_prio = 3
|
|
||||||
ionice = ""
|
|
||||||
fail_hopeless_jobs = 1
|
|
||||||
fast_fail = 1
|
|
||||||
auto_disconnect = 1
|
|
||||||
pre_script = None
|
|
||||||
end_queue_script = None
|
|
||||||
no_dupes = 0
|
|
||||||
no_series_dupes = 0
|
|
||||||
no_smart_dupes = 0
|
|
||||||
dupes_propercheck = 1
|
|
||||||
pause_on_pwrar = 1
|
|
||||||
ignore_samples = 0
|
|
||||||
deobfuscate_final_filenames = 1
|
|
||||||
auto_sort = ""
|
|
||||||
direct_unpack = 0
|
|
||||||
propagation_delay = 0
|
|
||||||
folder_rename = 1
|
|
||||||
replace_spaces = 0
|
|
||||||
replace_underscores = 0
|
|
||||||
replace_dots = 0
|
|
||||||
safe_postproc = 1
|
|
||||||
pause_on_post_processing = 0
|
|
||||||
enable_all_par = 0
|
|
||||||
sanitize_safe = 0
|
|
||||||
cleanup_list = ,
|
|
||||||
unwanted_extensions = ,
|
|
||||||
action_on_unwanted_extensions = 0
|
|
||||||
unwanted_extensions_mode = 0
|
|
||||||
new_nzb_on_failure = 0
|
|
||||||
history_retention = ""
|
|
||||||
history_retention_option = all
|
|
||||||
history_retention_number = 1
|
|
||||||
quota_size = ""
|
|
||||||
quota_day = ""
|
|
||||||
quota_resume = 0
|
|
||||||
quota_period = m
|
|
||||||
enable_tv_sorting = 0
|
|
||||||
tv_sort_string = ""
|
|
||||||
tv_categories = tv,
|
|
||||||
enable_movie_sorting = 0
|
|
||||||
movie_sort_string = ""
|
|
||||||
movie_sort_extra = -cd%1
|
|
||||||
movie_categories = movies,
|
|
||||||
enable_date_sorting = 0
|
|
||||||
date_sort_string = ""
|
|
||||||
date_categories = tv,
|
|
||||||
schedlines = ,
|
|
||||||
rss_rate = 60
|
|
||||||
ampm = 0
|
|
||||||
start_paused = 0
|
|
||||||
preserve_paused_state = 0
|
|
||||||
enable_par_cleanup = 1
|
|
||||||
process_unpacked_par2 = 1
|
|
||||||
enable_multipar = 1
|
|
||||||
enable_unrar = 1
|
|
||||||
enable_7zip = 1
|
|
||||||
enable_filejoin = 1
|
|
||||||
enable_tsjoin = 1
|
|
||||||
overwrite_files = 0
|
|
||||||
ignore_unrar_dates = 0
|
|
||||||
backup_for_duplicates = 0
|
|
||||||
empty_postproc = 0
|
|
||||||
wait_for_dfolder = 0
|
|
||||||
rss_filenames = 0
|
|
||||||
api_logging = 1
|
|
||||||
html_login = 1
|
|
||||||
warn_dupl_jobs = 0
|
|
||||||
keep_awake = 1
|
|
||||||
tray_icon = 1
|
|
||||||
allow_incomplete_nzb = 0
|
|
||||||
enable_broadcast = 1
|
|
||||||
ipv6_hosting = 0
|
|
||||||
ipv6_staging = 0
|
|
||||||
api_warnings = 1
|
|
||||||
no_penalties = 0
|
|
||||||
x_frame_options = 1
|
|
||||||
allow_old_ssl_tls = 0
|
|
||||||
enable_season_sorting = 1
|
|
||||||
verify_xff_header = 0
|
|
||||||
rss_odd_titles = nzbindex.nl/, nzbindex.com/, nzbclub.com/
|
|
||||||
quick_check_ext_ignore = nfo, sfv, srr
|
|
||||||
req_completion_rate = 100.2
|
|
||||||
selftest_host = self-test.sabnzbd.org
|
|
||||||
movie_rename_limit = 100M
|
|
||||||
episode_rename_limit = 20M
|
|
||||||
size_limit = 0
|
|
||||||
direct_unpack_threads = 3
|
|
||||||
history_limit = 5
|
|
||||||
wait_ext_drive = 5
|
|
||||||
max_foldername_length = 246
|
|
||||||
nomedia_marker = ""
|
|
||||||
ipv6_servers = 1
|
|
||||||
url_base = /sabnzbd
|
|
||||||
host_whitelist = usenet.kruining.eu, ulmo
|
|
||||||
local_ranges = ,
|
|
||||||
max_url_retries = 10
|
|
||||||
downloader_sleep_time = 10
|
|
||||||
receive_threads = 2
|
|
||||||
switchinterval = 0.005
|
|
||||||
ssdp_broadcast_interval = 15
|
|
||||||
ext_rename_ignore = ,
|
|
||||||
email_server = ""
|
|
||||||
email_to = ,
|
|
||||||
email_from = ""
|
|
||||||
email_account = ""
|
|
||||||
email_pwd = ""
|
|
||||||
email_endjob = 0
|
|
||||||
email_full = 0
|
|
||||||
email_dir = ""
|
|
||||||
email_rss = 0
|
|
||||||
email_cats = *,
|
|
||||||
config_conversion_version = 4
|
|
||||||
disable_par2cmdline = 0
|
|
||||||
disable_archive = 0
|
|
||||||
unrar_parameters = ""
|
|
||||||
outgoing_nntp_ip = ""
|
|
||||||
[logging]
|
|
||||||
log_level = 1
|
|
||||||
max_log_size = 5242880
|
|
||||||
log_backups = 5
|
|
||||||
[ncenter]
|
|
||||||
ncenter_enable = 0
|
|
||||||
ncenter_cats = *,
|
|
||||||
ncenter_prio_startup = 0
|
|
||||||
ncenter_prio_download = 0
|
|
||||||
ncenter_prio_pause_resume = 0
|
|
||||||
ncenter_prio_pp = 0
|
|
||||||
ncenter_prio_complete = 1
|
|
||||||
ncenter_prio_failed = 1
|
|
||||||
ncenter_prio_disk_full = 1
|
|
||||||
ncenter_prio_new_login = 0
|
|
||||||
ncenter_prio_warning = 0
|
|
||||||
ncenter_prio_error = 0
|
|
||||||
ncenter_prio_queue_done = 0
|
|
||||||
ncenter_prio_other = 1
|
|
||||||
ncenter_prio_quota = 1
|
|
||||||
[acenter]
|
|
||||||
acenter_enable = 0
|
|
||||||
acenter_cats = *,
|
|
||||||
acenter_prio_startup = 0
|
|
||||||
acenter_prio_download = 0
|
|
||||||
acenter_prio_pause_resume = 0
|
|
||||||
acenter_prio_pp = 0
|
|
||||||
acenter_prio_complete = 1
|
|
||||||
acenter_prio_failed = 1
|
|
||||||
acenter_prio_disk_full = 1
|
|
||||||
acenter_prio_new_login = 0
|
|
||||||
acenter_prio_warning = 0
|
|
||||||
acenter_prio_error = 0
|
|
||||||
acenter_prio_queue_done = 0
|
|
||||||
acenter_prio_other = 1
|
|
||||||
acenter_prio_quota = 1
|
|
||||||
[ntfosd]
|
|
||||||
ntfosd_enable = 1
|
|
||||||
ntfosd_cats = *,
|
|
||||||
ntfosd_prio_startup = 0
|
|
||||||
ntfosd_prio_download = 0
|
|
||||||
ntfosd_prio_pause_resume = 0
|
|
||||||
ntfosd_prio_pp = 0
|
|
||||||
ntfosd_prio_complete = 1
|
|
||||||
ntfosd_prio_failed = 1
|
|
||||||
ntfosd_prio_disk_full = 1
|
|
||||||
ntfosd_prio_new_login = 0
|
|
||||||
ntfosd_prio_warning = 0
|
|
||||||
ntfosd_prio_error = 0
|
|
||||||
ntfosd_prio_queue_done = 0
|
|
||||||
ntfosd_prio_other = 1
|
|
||||||
ntfosd_prio_quota = 1
|
|
||||||
[prowl]
|
|
||||||
prowl_enable = 0
|
|
||||||
prowl_cats = *,
|
|
||||||
prowl_apikey = ""
|
|
||||||
prowl_prio_startup = -3
|
|
||||||
prowl_prio_download = -3
|
|
||||||
prowl_prio_pause_resume = -3
|
|
||||||
prowl_prio_pp = -3
|
|
||||||
prowl_prio_complete = 0
|
|
||||||
prowl_prio_failed = 1
|
|
||||||
prowl_prio_disk_full = 1
|
|
||||||
prowl_prio_new_login = -3
|
|
||||||
prowl_prio_warning = -3
|
|
||||||
prowl_prio_error = -3
|
|
||||||
prowl_prio_queue_done = -3
|
|
||||||
prowl_prio_other = 0
|
|
||||||
prowl_prio_quota = 0
|
|
||||||
[pushover]
|
|
||||||
pushover_token = ""
|
|
||||||
pushover_userkey = ""
|
|
||||||
pushover_device = ""
|
|
||||||
pushover_emergency_expire = 3600
|
|
||||||
pushover_emergency_retry = 60
|
|
||||||
pushover_enable = 0
|
|
||||||
pushover_cats = *,
|
|
||||||
pushover_prio_startup = -3
|
|
||||||
pushover_prio_download = -2
|
|
||||||
pushover_prio_pause_resume = -2
|
|
||||||
pushover_prio_pp = -3
|
|
||||||
pushover_prio_complete = -1
|
|
||||||
pushover_prio_failed = -1
|
|
||||||
pushover_prio_disk_full = 1
|
|
||||||
pushover_prio_new_login = -3
|
|
||||||
pushover_prio_warning = 1
|
|
||||||
pushover_prio_error = 1
|
|
||||||
pushover_prio_queue_done = -3
|
|
||||||
pushover_prio_other = -1
|
|
||||||
pushover_prio_quota = -1
|
|
||||||
[pushbullet]
|
|
||||||
pushbullet_enable = 0
|
|
||||||
pushbullet_cats = *,
|
|
||||||
pushbullet_apikey = ""
|
|
||||||
pushbullet_device = ""
|
|
||||||
pushbullet_prio_startup = 0
|
|
||||||
pushbullet_prio_download = 0
|
|
||||||
pushbullet_prio_pause_resume = 0
|
|
||||||
pushbullet_prio_pp = 0
|
|
||||||
pushbullet_prio_complete = 1
|
|
||||||
pushbullet_prio_failed = 1
|
|
||||||
pushbullet_prio_disk_full = 1
|
|
||||||
pushbullet_prio_new_login = 0
|
|
||||||
pushbullet_prio_warning = 0
|
|
||||||
pushbullet_prio_error = 0
|
|
||||||
pushbullet_prio_queue_done = 0
|
|
||||||
pushbullet_prio_other = 1
|
|
||||||
pushbullet_prio_quota = 1
|
|
||||||
[apprise]
|
|
||||||
apprise_enable = 0
|
|
||||||
apprise_cats = *,
|
|
||||||
apprise_urls = ""
|
|
||||||
apprise_target_startup = ""
|
|
||||||
apprise_target_startup_enable = 0
|
|
||||||
apprise_target_download = ""
|
|
||||||
apprise_target_download_enable = 0
|
|
||||||
apprise_target_pause_resume = ""
|
|
||||||
apprise_target_pause_resume_enable = 0
|
|
||||||
apprise_target_pp = ""
|
|
||||||
apprise_target_pp_enable = 0
|
|
||||||
apprise_target_complete = ""
|
|
||||||
apprise_target_complete_enable = 1
|
|
||||||
apprise_target_failed = ""
|
|
||||||
apprise_target_failed_enable = 1
|
|
||||||
apprise_target_disk_full = ""
|
|
||||||
apprise_target_disk_full_enable = 0
|
|
||||||
apprise_target_new_login = ""
|
|
||||||
apprise_target_new_login_enable = 1
|
|
||||||
apprise_target_warning = ""
|
|
||||||
apprise_target_warning_enable = 0
|
|
||||||
apprise_target_error = ""
|
|
||||||
apprise_target_error_enable = 0
|
|
||||||
apprise_target_queue_done = ""
|
|
||||||
apprise_target_queue_done_enable = 0
|
|
||||||
apprise_target_other = ""
|
|
||||||
apprise_target_other_enable = 1
|
|
||||||
apprise_target_quota = ""
|
|
||||||
apprise_target_quota_enable = 1
|
|
||||||
[nscript]
|
|
||||||
nscript_enable = 0
|
|
||||||
nscript_cats = *,
|
|
||||||
nscript_script = ""
|
|
||||||
nscript_parameters = ""
|
|
||||||
nscript_prio_startup = 0
|
|
||||||
nscript_prio_download = 0
|
|
||||||
nscript_prio_pause_resume = 0
|
|
||||||
nscript_prio_pp = 0
|
|
||||||
nscript_prio_complete = 1
|
|
||||||
nscript_prio_failed = 1
|
|
||||||
nscript_prio_disk_full = 1
|
|
||||||
nscript_prio_new_login = 0
|
|
||||||
nscript_prio_warning = 0
|
|
||||||
nscript_prio_error = 0
|
|
||||||
nscript_prio_queue_done = 0
|
|
||||||
nscript_prio_other = 1
|
|
||||||
nscript_prio_quota = 1
|
|
||||||
[categories]
|
|
||||||
[[*]]
|
|
||||||
name = *
|
|
||||||
order = 0
|
|
||||||
pp = 3
|
|
||||||
script = None
|
|
||||||
dir = ""
|
|
||||||
newzbin = ""
|
|
||||||
priority = 0
|
|
||||||
[[movies]]
|
|
||||||
name = movies
|
|
||||||
order = 1
|
|
||||||
pp = ""
|
|
||||||
script = Default
|
|
||||||
dir = ""
|
|
||||||
newzbin = ""
|
|
||||||
priority = -100
|
|
||||||
[[tv]]
|
|
||||||
name = tv
|
|
||||||
order = 2
|
|
||||||
pp = ""
|
|
||||||
script = Default
|
|
||||||
dir = ""
|
|
||||||
newzbin = ""
|
|
||||||
priority = -100
|
|
||||||
[[audio]]
|
|
||||||
name = audio
|
|
||||||
order = 3
|
|
||||||
pp = ""
|
|
||||||
script = Default
|
|
||||||
dir = ""
|
|
||||||
newzbin = ""
|
|
||||||
priority = -100
|
|
||||||
[[software]]
|
|
||||||
name = software
|
|
||||||
order = 4
|
|
||||||
pp = ""
|
|
||||||
script = Default
|
|
||||||
dir = ""
|
|
||||||
newzbin = ""
|
|
||||||
priority = -100
|
|
||||||
[servers]
|
|
||||||
[[news.sunnyusenet.com]]
|
|
||||||
name = news.sunnyusenet.com
|
|
||||||
displayname = news.sunnyusenet.com
|
|
||||||
host = news.sunnyusenet.com
|
|
||||||
port = 563
|
|
||||||
timeout = 60
|
|
||||||
username = michiel@hazelhof.nl
|
|
||||||
password = dasusenet
|
|
||||||
connections = 8
|
|
||||||
ssl = 1
|
|
||||||
ssl_verify = 3
|
|
||||||
ssl_ciphers = ""
|
|
||||||
enable = 1
|
|
||||||
required = 0
|
|
||||||
optional = 0
|
|
||||||
retention = 0
|
|
||||||
expire_date = ""
|
|
||||||
quota = ""
|
|
||||||
usage_at_start = 0
|
|
||||||
priority = 1
|
|
||||||
notes = ""
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
mkShell,
|
|
||||||
inputs,
|
|
||||||
pkgs,
|
|
||||||
stdenv,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
mkShell {
|
|
||||||
packages = with pkgs; [
|
|
||||||
bash
|
|
||||||
sops
|
|
||||||
just
|
|
||||||
yq
|
|
||||||
pwgen
|
|
||||||
alejandra
|
|
||||||
nil
|
|
||||||
nixd
|
|
||||||
openssl
|
|
||||||
inputs.clan-core.packages.${stdenv.hostPlatform.system}.clan-cli
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +1,3 @@
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
My steambox.
|
My steambox.
|
||||||
=======
|
|
||||||
My desktop, reasoning for the name being the following chain of thought:
|
|
||||||
**Manwe -> the king of the valar -> leader -> desktop is main machine**
|
|
||||||
>>>>>>> 72b0f6f8fad97a4ade1b54dfada26828a170febf
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
system.activationScripts.remove-gtkrc.text = "rm -f /home/chris/.gtkrc-2.0";
|
|
||||||
|
|
||||||
sneeuwvlok = {
|
sneeuwvlok = {
|
||||||
hardware.has = {
|
hardware.has = {
|
||||||
gpu.amd = true;
|
gpu.amd = true;
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,59 @@
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
{ config, lib, pkgs, modulesPath, inputs, ... }:
|
||||||
let
|
let
|
||||||
inherit (lib.modules) mkDefault;
|
inherit (lib.modules) mkDefault;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# TODO :: Implement disko at some point
|
imports = [
|
||||||
|
inputs.disko.nixosModules.disko
|
||||||
|
];
|
||||||
|
|
||||||
swapDevices = [];
|
config = {
|
||||||
|
swapDevices = [];
|
||||||
|
|
||||||
boot.supportedFilesystems = [ "nfs" ];
|
boot.supportedFilesystems = [ "nfs" ];
|
||||||
|
|
||||||
fileSystems = {
|
disko.devices = {
|
||||||
"/" = {
|
disk = {
|
||||||
device = "/dev/disk/by-label/nixos";
|
main = {
|
||||||
fsType = "ext4";
|
device = "/dev/nvme0";
|
||||||
|
type = "disk";
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
ESP = {
|
||||||
|
size = "100M";
|
||||||
|
type = "EF00";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
mountOptions = [ "umask=0077" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
root = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "ext4";
|
||||||
|
mountpoint = "/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fileSystems = {
|
||||||
|
"/home/chris/media" = {
|
||||||
|
device = "ulmo:/";
|
||||||
|
fsType = "nfs";
|
||||||
|
};
|
||||||
|
|
||||||
"/boot" = {
|
"/home/chris/mandos" = {
|
||||||
device = "/dev/disk/by-label/boot";
|
device = "mandos:/";
|
||||||
fsType = "vfat";
|
fsType = "nfs";
|
||||||
options = [ "fmask=0022" "dmask=0022" ];
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
"/home/chris/media" = {
|
|
||||||
device = "ulmo:/";
|
|
||||||
fsType = "nfs";
|
|
||||||
};
|
|
||||||
|
|
||||||
# "/home/chris/mandos" = {
|
|
||||||
# device = "mandos:/";
|
|
||||||
# fsType = "nfs";
|
|
||||||
# };
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
31
systems/x86_64-linux/manwe/secrets.yaml
Normal file
31
systems/x86_64-linux/manwe/secrets.yaml
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
zitadel:
|
||||||
|
masterKey: ENC[AES256_GCM,data:iSeZOloWLrdP8S+ac7ubIcv9TF3Sm8Ni,iv:8v3/ratFQ5vq2rbZOUMKfPhVTA9uQY2eFQU4IR8s3VU=,tag:9y90aDQ2PfFT//X2i2YvvA==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age10c5hmykkduvy75yvqfnchm5lcesr5puarhkwp4l7xdwpykdm397q6xdxuy
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4R0UyWmx5L3hCbGhQVXI0
|
||||||
|
NmpkMThPVlgrRHZZMnFrNTAwbzVTY1F6NEVVCjJaRHdhbHV6R1RJM2JIQzc3dkNu
|
||||||
|
a01FYlM3b1dXbmxGN2tWU3FMdXMveG8KLS0tIG1SSjNXdXZNN2ZyQ2UyZ0pIZXJJ
|
||||||
|
NmpMS2oySFE1S1RER3J1RGl4MlRQK00Ks+PcxcHmygYz+a+d0ZrzrdUpTQ50NYkA
|
||||||
|
aDFbtRtukn9e7i3bGUyD4nisSvs4YjfoQxR/pC8hs4k3f5V2jwDh2w==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1ewes0f5snqx3sh5ul6fa6qtxzhd25829v6mf5rx2wnheat6fefps5rme2x
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwaTN4clFoWDNwU2lpaHBn
|
||||||
|
M2pVeU5oM0JRNmp6NEJjQ3BHeWlzeSs3bTI0CnBocngvbzZQUXBsMG9Oc2J6dlBT
|
||||||
|
MjdtaFdmOHg5ZmZmSkViWGJFYThQYXcKLS0tIFRNd2JiVlFTREtDMTdzR2V0SlVo
|
||||||
|
Q0d5ZDVDM05LdFp4UnB4dFRPUm5vU0UKR/MAONEWaT6XXyPB1IrSIKqW5PZNIbuB
|
||||||
|
n7QX3DJIzlajtmq+82/wPFPTBkLvSSjV5FKL5ErMwTDndcIn+NlOhQ==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2025-08-11T13:11:00Z"
|
||||||
|
mac: ENC[AES256_GCM,data:P34YsR/Rvc3q4Os5n9hxonJLCXwifMRnKOCM59h5MRMT/aqjl+QlBX+oUADsqDSrhUscQb3N/UlpFeOT6qg+FmJbT/mYMH6v1xK16VD0M7VWydXpmjDu5If+O89lgDHsiEOGDgeR04jkiaY0yzT9U8l9CND5fMvF3I9o5Z1SZQk=,iv:NgUD8gB2bQa5vh0nb0Ngqp5dn0yqskHudWo8xoVjM4Q=,tag:5oTcnailDCHeMvMLz63e1w==,type:str]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.9.4
|
||||||
|
|
@ -1,229 +1,14 @@
|
||||||
{...}: {
|
{ ... }:
|
||||||
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./disks.nix
|
./disks.nix
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
networking = {
|
|
||||||
interfaces.enp2s0 = {
|
|
||||||
ipv6.addresses = [
|
|
||||||
{
|
|
||||||
address = "2a0d:6e00:1dc9:0::dead:beef";
|
|
||||||
prefixLength = 64;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
useDHCP = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultGateway = {
|
|
||||||
address = "192.168.1.1";
|
|
||||||
interface = "enp2s0";
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultGateway6 = {
|
|
||||||
address = "fe80::1";
|
|
||||||
interface = "enp2s0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Expose amarht cloud stuff like this until I have a proper solution
|
|
||||||
services.caddy.virtualHosts = {
|
|
||||||
"auth.amarth.cloud".extraConfig = ''
|
|
||||||
reverse_proxy http://192.168.1.223:9092
|
|
||||||
'';
|
|
||||||
|
|
||||||
"amarth.cloud".extraConfig = ''
|
|
||||||
reverse_proxy http://192.168.1.223:8080
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sneeuwvlok = {
|
sneeuwvlok = {
|
||||||
services = {
|
services = {
|
||||||
backup.borg.enable = true;
|
|
||||||
|
|
||||||
authentication.zitadel = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
organization = {
|
|
||||||
nix = {
|
|
||||||
user = {
|
|
||||||
chris = {
|
|
||||||
email = "chris@kruining.eu";
|
|
||||||
firstName = "Chris";
|
|
||||||
lastName = "Kruining";
|
|
||||||
|
|
||||||
roles = ["ORG_OWNER"];
|
|
||||||
instanceRoles = ["IAM_OWNER"];
|
|
||||||
};
|
|
||||||
|
|
||||||
kaas = {
|
|
||||||
email = "chris+kaas@kruining.eu";
|
|
||||||
firstName = "Kaas";
|
|
||||||
lastName = "Kruining";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
project = {
|
|
||||||
ulmo = {
|
|
||||||
projectRoleCheck = true;
|
|
||||||
projectRoleAssertion = true;
|
|
||||||
hasProjectCheck = true;
|
|
||||||
|
|
||||||
role = {
|
|
||||||
jellyfin = {
|
|
||||||
group = "jellyfin";
|
|
||||||
};
|
|
||||||
jellyfin_admin = {
|
|
||||||
group = "jellyfin";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
assign = {
|
|
||||||
chris = ["jellyfin" "jellyfin_admin"];
|
|
||||||
kaas = ["jellyfin"];
|
|
||||||
};
|
|
||||||
|
|
||||||
application = {
|
|
||||||
jellyfin = {
|
|
||||||
redirectUris = ["https://jellyfin.kruining.eu/sso/OID/redirect/zitadel"];
|
|
||||||
grantTypes = ["authorizationCode"];
|
|
||||||
responseTypes = ["code"];
|
|
||||||
};
|
|
||||||
|
|
||||||
forgejo = {
|
|
||||||
redirectUris = ["https://git.amarth.cloud/user/oauth2/zitadel/callback"];
|
|
||||||
grantTypes = ["authorizationCode"];
|
|
||||||
responseTypes = ["code"];
|
|
||||||
};
|
|
||||||
|
|
||||||
vaultwarden = {
|
|
||||||
redirectUris = ["https://vault.kruining.eu/identity/connect/oidc-signin"];
|
|
||||||
grantTypes = ["authorizationCode"];
|
|
||||||
responseTypes = ["code"];
|
|
||||||
exportMap = {
|
|
||||||
client_id = "SSO_CLIENT_ID";
|
|
||||||
client_secret = "SSO_CLIENT_SECRET";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
matrix = {
|
|
||||||
redirectUris = ["https://matrix.kruining.eu/_synapse/client/oidc/callback"];
|
|
||||||
grantTypes = ["authorizationCode"];
|
|
||||||
responseTypes = ["code"];
|
|
||||||
};
|
|
||||||
|
|
||||||
mydia = {
|
|
||||||
redirectUris = ["http://localhost:2010/auth/oidc/callback"];
|
|
||||||
grantTypes = ["authorizationCode"];
|
|
||||||
responseTypes = ["code"];
|
|
||||||
};
|
|
||||||
|
|
||||||
grafana = {
|
|
||||||
redirectUris = ["http://localhost:9001/login/generic_oauth"];
|
|
||||||
grantTypes = ["authorizationCode"];
|
|
||||||
responseTypes = ["code"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
action = {
|
|
||||||
flattenRoles = {
|
|
||||||
script = ''
|
|
||||||
(ctx, api) => {
|
|
||||||
if (ctx.v1.user.grants == undefined || ctx.v1.user.grants.count == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roles = ctx.v1.user.grants.grants.flatMap(({ roles, projectId }) => roles.map(role => projectId + ':' + role));
|
|
||||||
|
|
||||||
api.v1.claims.setClaim('nix:zitadel:custom', JSON.stringify({ roles }));
|
|
||||||
};
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
triggers = [
|
|
||||||
{
|
|
||||||
flowType = "customiseToken";
|
|
||||||
triggerType = "preUserinfoCreation";
|
|
||||||
actions = ["flattenRoles"];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
flowType = "customiseToken";
|
|
||||||
triggerType = "preAccessTokenCreation";
|
|
||||||
actions = ["flattenRoles"];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
communication.matrix.enable = true;
|
|
||||||
|
|
||||||
development.forgejo.enable = true;
|
|
||||||
|
|
||||||
networking.ssh.enable = true;
|
networking.ssh.enable = true;
|
||||||
|
|
||||||
media.enable = true;
|
media.enable = true;
|
||||||
media.glance.enable = true;
|
|
||||||
media.mydia.enable = true;
|
|
||||||
media.nfs.enable = true;
|
|
||||||
media.servarr = {
|
|
||||||
radarr = {
|
|
||||||
enable = true;
|
|
||||||
port = 2001;
|
|
||||||
rootFolders = [
|
|
||||||
"/var/media/movies"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
sonarr = {
|
|
||||||
enable = true;
|
|
||||||
# debug = true;
|
|
||||||
port = 2002;
|
|
||||||
rootFolders = [
|
|
||||||
"/var/media/series"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
lidarr = {
|
|
||||||
enable = true;
|
|
||||||
debug = true;
|
|
||||||
port = 2003;
|
|
||||||
rootFolders = [
|
|
||||||
"/var/media/music"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
prowlarr = {
|
|
||||||
enable = true;
|
|
||||||
debug = true;
|
|
||||||
port = 2004;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
observability = {
|
|
||||||
grafana.enable = true;
|
|
||||||
prometheus.enable = true;
|
|
||||||
loki.enable = true;
|
|
||||||
promtail.enable = true;
|
|
||||||
# uptime-kuma.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
security.vaultwarden = {
|
|
||||||
enable = true;
|
|
||||||
database = {
|
|
||||||
# type = "sqlite";
|
|
||||||
# file = "/var/lib/vaultwarden/state.db";
|
|
||||||
|
|
||||||
type = "postgresql";
|
|
||||||
host = "localhost";
|
|
||||||
port = 5432;
|
|
||||||
sslMode = "disabled";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
editor = {
|
editor = {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ in
|
||||||
{
|
{
|
||||||
# TODO :: Implement disko at some point
|
# TODO :: Implement disko at some point
|
||||||
|
|
||||||
swapDevices = [];
|
swapDevices = [
|
||||||
|
{ device = "/dev/disk/by-uuid/0ddf001a-5679-482e-b254-04a1b9094794"; }
|
||||||
|
];
|
||||||
|
|
||||||
boot.supportedFilesystems = [ "nfs" ];
|
boot.supportedFilesystems = [ "nfs" ];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
email:
|
|
||||||
chris_kruining_eu: ENC[AES256_GCM,data:/JS+dQ6ABlkdjRZP+sGeUY3js30swS4=,iv:d5CcoY6DD3DJ/e3t0OU/KUULccJpTN0uBQPQzl/3R0s=,tag:aTN7RdzXkIpci9tEBjevSA==,type:str]
|
|
||||||
info_amarth_cloud: ENC[AES256_GCM,data:/x7aAFAxXYYf79tB08VQmmuTIy2TvdSTFfAzIWdIr+I=,iv:plNxS6oOin+oEql+1xsePOsUfLJkf+ZPBviPRTbIghE=,tag:hjtK3rysd2NNBA2mWdv8cw==,type:str]
|
|
||||||
zitadel:
|
|
||||||
masterKey: ENC[AES256_GCM,data:4MPvBo407qrS7NF4oUTf84tZoPkSRmiHdD7qpkYeHME=,iv:H2NIAN0xBUDqnyco9gA3zYAsKtSeA/JpqYrPhc1eqc0=,tag:6OFGDfsucG5gDerImgpuXA==,type:str]
|
|
||||||
nix: {}
|
|
||||||
users: ENC[AES256_GCM,data:pMSK3Re/DZeMnFNCEgjTGWWMYYX5eLOoZwGg3oO7WQ0Sx7z7sLRPpqlGVw384G6uYjR19MpnVud6hHPkGY/FoTO0vsJ+a2anFpmLjLsPNehiQ57rnvnWJCeVJyTz0kqKt7vS1kGpdtjH5d98PerNzxR0FvTrjJhQCfHyP/S8/G6vD6cLmeBXaStpKJ6TM0UIPcWSTzrpV3O292xAFooWYv19hkM4C6IJtbej8zTmY8pEsHk5OY3w,iv:r3603xOtSE1CEdMR9epaWclbO3PXjMWpnJT7HEbF57o=,tag:HAPUlIuumY0IjL0P4Q1aFA==,type:str]
|
|
||||||
forgejo:
|
|
||||||
action_runner_token: ENC[AES256_GCM,data:yJ6OnRq5kinbuhvH06K5o3l86EafuBoojMwg/qhP+cgeH+BwPeE+Ng==,iv:IeXJahPxgLNIUFmkgp495tLVh8UyQBmJ2SnVEUhlhHs=,tag:XYQi613CxSp8AQeilJMrsg==,type:str]
|
|
||||||
synapse:
|
|
||||||
oidc_id: ENC[AES256_GCM,data:XbCpyGq0LeRJWq8dv/5Dipvp,iv:YDhgl26z1NBbIQLoLdGVz0+ze6o1ZcmgVHPfwoRj57I=,tag:y2vUuqnDmtTvVQmZCAlnLg==,type:str]
|
|
||||||
oidc_secret: ENC[AES256_GCM,data:nVFi5EFbNMZ0mvrDHVYC0NiwJlo2eEw44D+Fcv9SKSb2oO00lGEDkP/oXDj5YgDq6RLQSe3f/SUOn77ntwnZYg==,iv:awe7VNUYOn9ofl1QlQTrEN5d0i5WkVM35qndruL4VXo=,tag:8Yoc9lFF9aWbtAa5fzQGEA==,type:str]
|
|
||||||
radarr:
|
|
||||||
apikey: ENC[AES256_GCM,data:G141GW4PyS5pbAV39HcVscMw3s30txOgTZzWaL7o+ccZfnfDLv796O6xKXdqGZ8saLsveghLw9Z6a5luusHyQ3Q5ESL6W7SVeZVTuSqSC3i/4jl75FJxhnsgVsfrnYxzLGpKiw==,iv:sZl/XLh6y3WgSAn6nH3sFB6atBifZdghm+QsCNDbcjY=,tag:Tw+R80nrF0T0yDti0Uf+ig==,type:str]
|
|
||||||
sonarr:
|
|
||||||
apikey: ENC[AES256_GCM,data:s8bgDJ+LpIH1Mt3KSiIKB8LnxztOkHdc8J6+50o+HoDUAfIIsZkA2oX/m7UecrTSRi6ay8D9yjhe6ZwSNXhJh6wQqTS7gZWn8f6QfrfI+8DKdc9enh91suQxjkz8Q+wnKK0zBg==,iv:LmAe6v+6ItVnHB6gko6mhiGOuVBksBYP4dXfbxpAIPE=,tag:DZ8kwOwaWwWTGWEGu5S0Kg==,type:str]
|
|
||||||
lidarr:
|
|
||||||
apikey: ENC[AES256_GCM,data:I2eKaxidmxem7C7ukmyIfwASNqrkS4vEOiCcU5kSNY6DR0pXsYg0PBdgu8vzK6llbXODLdG5t55BordIWvVRJGAauo0FMvtp59NSNpza7cK68tdKGvNefD6bqhUIR06BY11niQ==,iv:48AD7cd17TlWY5yAagepLOIVwgxhD/d13Pnup6GsWDA=,tag:teOVtW8opE99hqAXQwvlrA==,type:str]
|
|
||||||
prowlarr:
|
|
||||||
apikey: ENC[AES256_GCM,data:pyZ2WGEs/PlIdhDsQq2TPGJbplkd5fLF0ZkBjITqIJlnAzYHb+rl+KOM4rHqQcI6yAJM8X1Y3ymGrD7vG7GiRxB7yoEG13SKhZIWOddTnxIhbkz81RfrL2fUJIydOaP6sS//9Q==,iv:Tr6MWoC6nC7rdVTOjT1T2itT+lVL4GnUiAr5/+IHAs0=,tag:keIJNuGeVht8+xSN3FnBGA==,type:str]
|
|
||||||
mydia:
|
|
||||||
oidc_id: ENC[AES256_GCM,data:LfYWh9EC0aio3w1Xsj/jtU6z,iv:+dX9KkNtfQMYSX4yr83KyXalWMD/aWby7fC8aL4ZT3I=,tag:CvdbMoMTuC9FohTMIE5pmg==,type:str]
|
|
||||||
oidc_secret: ENC[AES256_GCM,data:PgI4hmP/3wt9uj+1QvCYcT8Wav0hgCRADouzWM3V695SSfXfbwDgez8tA/tm1/1jymAU2F2sZH8G2hZ1cdHyHQ==,iv:h3o3jsTmnoNE3+mGX12J3ZU0/6PlQNjdndEvaj/czj0=,tag:p3+p4E8fBtR7a8UpM8cUsg==,type:str]
|
|
||||||
secret_key_base: ENC[AES256_GCM,data:yG7HJ5r74Qtxbeyf8F6dA0uHv2pQ8YAJKlKiKjS+m24JRvJWQaTThJ+c5HbuUa6R3e9XtVHchhlVPkF0Is/b+g==,iv:v65xdRr4JdKZmBtjZ08/J3LLqnphSGt9QfVPNQ2x/xg=,tag:n7tD2dhr4IJn1LWM9WW8UA==,type:str]
|
|
||||||
guardian_secret: ENC[AES256_GCM,data:OjnNFSHlecL+qXwlhTm++itRM6ga5E5KrSJxbgIUpbMEkIWgu3xhRtnPdipXbedgall0XdO/s+jnWCagZX94BA==,iv:DukdKvm9vey8BWUiml20tgA/Vji1XVX4+sUPge9nTk0=,tag:q3HdvgUYqR0APiaFz0ul5Q==,type:str]
|
|
||||||
qbittorrent:
|
|
||||||
password_hash: ENC[AES256_GCM,data:yCfCslj01wtfwzzPOGlwA6wLLf+EUuEweYa3ZxvDtd/VGMxuV38quV+ob1Of+W0UH3+U4Qmgh4BK3I3IJZuKOvNdkZ0i81YBwW6cgvZUmnxwh8wokpNzxCKbYk5nF7y7SaGEdzQLvV7ad3fNMJsQ+s2zCsKWbm+j8Bwgq0E=,iv:IIktPS9pYXaYPzH0r4wrkp31CpunKnr70Ainu6hOeWY=,tag:bYCfhDfIwiQZ1tKAvITewQ==,type:str]
|
|
||||||
password: ENC[AES256_GCM,data:UepYY6UjJV/jo2aXTOEnKRtsjSqOSYPQlKlrAa7rf9rdnt2UXGjCkvN+A72pICuIBCAmhXZBAUMvmWTV9trk6NREHe0cY1xTC7pNv3x9TM/ZQmH498pbT/95pYAKwouHp9heJQ==,iv:FzjF+xPoaOp+gplxpz940V2dkWSTWe8dWUxexCoxxHc=,tag:TDZsboq9fEmmBrwJN/HTpQ==,type:str]
|
|
||||||
grafana:
|
|
||||||
oidc_id: ENC[AES256_GCM,data:NVdIgCQ6nz4BSUDJYCKyILtK,iv:tcljy9PzC/yyd7TSdngyJt+uh60uXi2PKu47czErbaQ=,tag:zE4q3dD4UQaHIpGeZ1L48Q==,type:str]
|
|
||||||
oidc_secret: ENC[AES256_GCM,data:b7qILK9ZHW2khtM1Hl/KdjCv3Wq6eOo2Ym/cbjcMB8/3Hn2UelpP4K4lFyiV3bn1/GF6Jl5Z7A0EwMybOx0InA==,iv:3HL/7BiyObwT8DmFxzNPI9CdmCH/4j/4oc9x7qBE1k0=,tag:dBhcq1zLKy6N+jp/v42R4A==,type:str]
|
|
||||||
sabnzbd:
|
|
||||||
sunnyweb:
|
|
||||||
password: ENC[AES256_GCM,data:flw8AahqO1Mx,iv:Qhu8iVWMzzqy18y8dj3aHoBnSZatm74/tYvZ456l2sA=,tag:sCYBdw7kD0zJZFFr5EyPIQ==,type:str]
|
|
||||||
username: ENC[AES256_GCM,data:IboJ8WDWuVNgvrk7c3V8I5S6Xg==,iv:BRohMuQFQz2S+HFasIaok6npT3C5v/SlhAhbLQXfB0s=,tag:M3/u0WBQ3AufHqe4DCtsrA==,type:str]
|
|
||||||
apikey: ENC[AES256_GCM,data:j5sPXKbBhMdNHOuoTfZ+c8nGu5JameOgK2z428iLdP01Hi6MvHVaN8Zs8YxMoSBtOjdtIEC8MS+3m1S1rU/P4pCRfZpK5ua1DBHq4l0xROUqokFWjDcAmJJv3pYXl0cQxQcGKQ==,iv:v5hu3gmO1Zn1FfXkHLPGN9f7JOcQjzoQahdqJwfM+xY=,tag:uI1LFcTgcyRgAaTJ1kzKow==,type:str]
|
|
||||||
sops:
|
|
||||||
age:
|
|
||||||
- recipient: age19qfpf980tadguqq44zf6xwvjvl428dyrj46ha3n6aeqddwhtnuqqml7etq
|
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwdDZyZkxvNU4zM3NHb2gx
|
|
||||||
ZlhLZk5JWUFGMWZGeUVHNkFFU1NtZlBQVVhjCmZGai9NdmdUeU5VcW9ROVZKTW5q
|
|
||||||
cmZaQ2JlaldaTWduQklocUZLT2FUcGcKLS0tIHlqVU0wdXJ0dTE4dlZSVEczd2Yv
|
|
||||||
RVFxVHFxbkVNbEZsaVcwYXZCdUc5R1kKQdAN6LEKmGLCSkKhNuEr0YK2zl9Aw1kK
|
|
||||||
6C25lN532mG55zIRectZda1Fmi1GMZ/2v3b5qz7x+TDMA9m/47OjmA==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
- recipient: age1ewes0f5snqx3sh5ul6fa6qtxzhd25829v6mf5rx2wnheat6fefps5rme2x
|
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoK3lqRDhEMXEvaUp3OWdV
|
|
||||||
eFlZSGpJcGs0RTdRbllWdmdZTzl3RTlDNlIwCm92R290NjNyK2NNbWpINTBhazNS
|
|
||||||
NTJYWEw0SGc1TUtrd0NZSmowakMvSlEKLS0tIG5uUEIrZGVORkRNVnBVOHgyMXZG
|
|
||||||
TTRWaHhpNWlkVDFmMFN4ZTNHMUxyNVkKV693pzTKRkZboQCMPr9IyMGSgxfuHXcb
|
|
||||||
Y6BNcp6Qg6PWtX5QI7wRkPNINAK1TEbRBba+b8h6gMmVU4DliQyFiQ==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
lastmodified: "2025-12-11T22:19:26Z"
|
|
||||||
mac: ENC[AES256_GCM,data:J1RVA3s9qemyLGo4svCofqIA4XNYgDWDc3JRbfynGLtAocOQPtXOLKoEauplDWMQ8hFIGRznIzv5XkCH6hfxQhjNI0UCuR0WhFZtnQU59hS+Qg4AQKVukRdjY136RpNiBMCMNhiXs8NAbuVxrFramgFClFQgVO+b6+Q3w2JspNE=,iv:hPUnwDUg+Wbx/YDugY8TjFIJqUzJE75tv4vzc2NHdrQ=,tag:xwqb7I315SbAlK7MlT9uBA==,type:str]
|
|
||||||
unencrypted_suffix: _unencrypted
|
|
||||||
version: 3.11.0
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue