Skip to content

Commit 3497678

Browse files
committed
make restish service interface more generic
1 parent 8f5e213 commit 3497678

4 files changed

Lines changed: 68 additions & 23 deletions

File tree

modules/arr-common/mkArrServiceModule.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ in {
196196
else "";
197197
in {
198198
baseUrl = "http://${host}:${toString cfg.config.hostConfig.port}${urlBase}/api/${cfg.config.apiVersion}";
199-
inherit (cfg.config) apiKeyPath;
199+
headers."X-Api-Key" = cfg.config.apiKeyPath;
200200
};
201201
};
202202
};

modules/arr-common/mkWaitForApiScript.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ in ''
1212
1313
echo "Waiting for ${capitalizedName} API to be available..."
1414
for i in {1..90}; do
15-
if restish -o json ${serviceName}/system/status >/dev/null 2>&1; then
15+
if restish -o json ${serviceName}/system/status >/dev/null; then
1616
echo "${capitalizedName} API is available"
1717
exit 0
1818
fi

modules/restish-wrapper/default.nix

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
enabledServices = lib.attrValues cfg.services;
1111

12+
# Helper to convert header/query names to valid bash variable names
13+
# Converts to uppercase and replaces hyphens with underscores
14+
sanitizeVarName = name: lib.replaceStrings ["-"] ["_"] (lib.toUpper name);
15+
1216
restishWrapper = pkgs.writeShellScriptBin "restish" ''
1317
set -euo pipefail
1418
@@ -20,33 +24,51 @@
2024
mkdir -p "$RESTISH_CONFIG_DIR"
2125
2226
${lib.optionalString ((lib.length enabledServices) > 0) ''
27+
# Helper function to read value from file if it exists, otherwise use as-is
28+
read_value() {
29+
local value="$1"
30+
if [ -f "$value" ]; then
31+
cat "$value"
32+
else
33+
echo "$value"
34+
fi
35+
}
36+
37+
# Build JSON config using jq
38+
CONFIG_FILE="$RESTISH_CONFIG_DIR/apis.json"
2339
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: svc: ''
24-
if [ -f "${svc.apiKeyPath}" ]; then
25-
export ${lib.toUpper name}_API_KEY=$(cat "${svc.apiKeyPath}")
26-
else
27-
echo "Warning: API key file not found: ${svc.apiKeyPath}" >&2
28-
fi
40+
${lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: ''
41+
export HEADER_${sanitizeVarName name}_${sanitizeVarName k}=$(read_value "${v}")
42+
'')
43+
svc.headers)}
44+
${lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: ''
45+
export QUERY_${sanitizeVarName name}_${sanitizeVarName k}=$(read_value "${v}")
46+
'')
47+
svc.query)}
2948
'')
3049
cfg.services)}
3150
32-
CONFIG_FILE="$RESTISH_CONFIG_DIR/apis.json"
3351
cat > "$CONFIG_FILE" <<'EOF'
3452
{
35-
${lib.concatStringsSep ",\n " (lib.mapAttrsToList (name: svc: ''
36-
"${name}": {
37-
"base": "${svc.baseUrl}",
38-
"profiles": {
39-
"default": {
40-
"headers": {
41-
"X-Api-Key": "''${${lib.toUpper name}_API_KEY}"
53+
${lib.concatStringsSep ",\n" (lib.mapAttrsToList (name: svc: let
54+
headerPairs = lib.mapAttrsToList (k: v: ''"${k}": "$HEADER_${sanitizeVarName name}_${sanitizeVarName k}"'') svc.headers;
55+
queryPairs = lib.mapAttrsToList (k: v: ''"${k}": "$QUERY_${sanitizeVarName name}_${sanitizeVarName k}"'') svc.query;
56+
profileParts =
57+
(lib.optionals (svc.headers != {}) [''"headers": { ${lib.concatStringsSep ", " headerPairs} }''])
58+
++ (lib.optionals (svc.query != {}) [''"query": { ${lib.concatStringsSep ", " queryPairs} }'']);
59+
in ''
60+
"${name}": {
61+
"base": "${svc.baseUrl}",
62+
"profiles": {
63+
"default": {
64+
${lib.concatStringsSep ",\n" profileParts}
4265
}
4366
}
44-
}
45-
}'')
46-
cfg.services)}
67+
}'') cfg.services)}
4768
}
4869
EOF
4970
71+
# Substitute environment variables
5072
TEMP_CONFIG=$(mktemp)
5173
${pkgs.envsubst}/bin/envsubst < "$CONFIG_FILE" > "$TEMP_CONFIG"
5274
mv "$TEMP_CONFIG" "$CONFIG_FILE"
@@ -65,9 +87,32 @@ in {
6587
example = "http://127.0.0.1:8989/api/v3";
6688
};
6789

68-
apiKeyPath = mkOption {
69-
type = types.path;
70-
description = "Path to the API key file";
90+
headers = mkOption {
91+
type = types.attrsOf types.str;
92+
default = {};
93+
description = ''
94+
HTTP headers to send with requests.
95+
Values can be either plain strings or file paths.
96+
If a value is a valid file path, it will be read at runtime.
97+
'';
98+
example = {
99+
"X-Api-Key" = "/run/secrets/sonarr/api_key";
100+
"User-Agent" = "nixflix";
101+
};
102+
};
103+
104+
query = mkOption {
105+
type = types.attrsOf types.str;
106+
default = {};
107+
description = ''
108+
Query parameters to include in requests.
109+
Values can be either plain strings or file paths.
110+
If a value is a valid file path, it will be read at runtime.
111+
'';
112+
example = {
113+
"apikey" = "/run/secrets/sabnzbd/api_key";
114+
"output" = "json";
115+
};
71116
};
72117
};
73118
});

tests/vm-tests/sabnzbd-basic.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ in
2525
sabnzbd = {
2626
enable = true;
2727
downloadsDir = "/downloads/usenet";
28-
apiKeyPath = pkgs.writeText "sabnzbd-apikey" "testapikey123456789abcdef";
29-
nzbKeyPath = pkgs.writeText "sabnzbd-nzbkey" "testnzbkey123456789abcdef";
28+
apiKeyPath = "${pkgs.writeText "sabnzbd-apikey" "testapikey123456789abcdef"}";
29+
nzbKeyPath = "${pkgs.writeText "sabnzbd-nzbkey" "testnzbkey123456789abcdef"}";
3030
environmentSecrets = [
3131
{
3232
env = "EWEKA_USERNAME";

0 commit comments

Comments
 (0)