Skip to content

Commit 35bfd44

Browse files
committed
feat(modules/lib): add oneOfRefs enforcement to the renderer
1 parent 30739ff commit 35bfd44

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

modules/lib/default.nix

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,22 @@ rec {
351351
else
352352
null
353353
) (spec.requiredAttrs or [ ]);
354+
# exactly-one-of ref groups: each entry is a list of ref names of
355+
# which exactly one must be set (provider rejects zero or two).
356+
oneOfChecks = map (
357+
group:
358+
let
359+
setRefs = builtins.filter (refName: (item.${refName} or null) != null) group;
360+
n = builtins.length setRefs;
361+
joined = lib.concatStringsSep ", " group;
362+
in
363+
if n == 0 then
364+
throw "${runtimePrefix}.${c}.${key}: exactly one of [${joined}] must be set"
365+
else if n > 1 then
366+
throw "${runtimePrefix}.${c}.${key}: [${joined}] are mutually exclusive; set exactly one"
367+
else
368+
null
369+
) (spec.oneOfRefs or [ ]);
354370
# wrap nested MaxItems:1 blocks in `[ obj ]` so terraform reads
355371
# them as blocks. spec.blockAttrs lists dotted paths; recurses
356372
# through attrsets and list elements.
@@ -379,7 +395,7 @@ rec {
379395
# deepSeq forces the checks to run.
380396
# (they're not nixos assertions because we generate the .tf.json
381397
# outside a full system build too.)
382-
builtins.deepSeq [ reqSecretChecks reqAttrChecks ] {
398+
builtins.deepSeq [ reqSecretChecks reqAttrChecks oneOfChecks ] {
383399
label = tfLabel spec.prefix key;
384400
value = wrapped;
385401
inherit (substituted) secrets;

0 commit comments

Comments
 (0)