6868 local nsLabels = std.get(ns.metadata, 'labels', {});
6969 !inDelete(ns) && std.get(nsLabels, 'example.com/sync-secret', 'false') == 'true';
7070
71+ assert std.length(esp.context().source_secret) == 1 : "Expected to have exactly one source secret"; <6>
7172 local secret = esp.context().source_secret[0];
73+
7274 local copy_to(nsname) = {
7375 apiVersion: 'v1',
7476 kind: 'Secret',
@@ -83,21 +85,21 @@ spec:
8385 type: secret.type,
8486 };
8587
86- if esp.triggerName() == 'namespace' then ( <6 >
87- local ns = esp.triggerData().resource; <7 >
88+ if esp.triggerName() == 'namespace' then ( <7 >
89+ local ns = esp.triggerData().resource; <8 >
8890 if ns != null && wants_secret(ns) then copy_to(ns.metadata.name)
89- ) else if esp.triggerName() == 'managed_secret' then ( <8 >
91+ ) else if esp.triggerName() == 'managed_secret' then ( <9 >
9092 local tdata = esp.triggerData();
9193 // by using the resource event when a managed secret is reconciled we
9294 // don't have to care about whether we got triggered due to a
9395 // modification or deletion of the secret.
9496 local secretNs = std.filter(
95- function(ns) ns.metadata.name == tdata.resourceEvent.namespace, <9 >
97+ function(ns) ns.metadata.name == tdata.resourceEvent.namespace, <10 >
9698 esp.context().target_namespaces
9799 );
98100 if std.length(secretNs) == 1 && wants_secret(secretNs[0]) then
99101 copy_to(tdata.resourceEvent.namespace)
100- ) else [ <10 >
102+ ) else [ <11 >
101103 copy_to(ns.metadata.name)
102104 for ns in esp.context().target_namespaces
103105 if wants_secret(ns)
@@ -111,13 +113,25 @@ Only namespaces with the label `example.com/sync-secret=true` will receive the s
111113Uses the same cache as the `target_namespaces` context resource.
112114<5> Trigger that reconciles the `ManagedResource` when a managed secret is created, modified or deleted.
113115Filtered by the label `espejote.io/managed-by=secret-sync-namespace.sync-secret` injected by the template itself.
114- <6> When triggered by a namespace event, reconcile only that namespace.
115- <7> The full triggering resource is available in `esp.triggerData().resource` .
116+ <6> Assertion to ensure the source secret exists in the context.
117+ Context resources always return an array of resources, even if only a single resource is expected.
118+ If no referenced resource exists, the array is empty.
119+ The assertion causes the reconciliation to fail in that case, which adds an event to the `ManagedResource` and to the triggering resource.
120+ Jsonnet does not allow early exits but the check could guard the final `if` expression instead as jsonnet is lazy-evaluated.
121+ +
122+ [source]
123+ ----
124+ if std.length(esp.context().source_secret) == 1 then
125+ if esp.triggerName() == 'namespace' then
126+ ...
127+ ----
128+ <7> When triggered by a namespace event, reconcile only that namespace.
129+ <8> The full triggering resource is available in `esp.triggerData().resource` .
116130Can be `null` if the resource was deleted.
117- <8 > When triggered by a managed secret event, reconcile only the namespace of that secret.
118- <9 > `resourceEvent` contains the raw event data, including the namespace of the secret.
131+ <9 > When triggered by a managed secret event, reconcile only the namespace of that secret.
132+ <10 > `resourceEvent` contains the raw event data, including the namespace of the secret.
119133This data always exists, even if the resource was deleted.
120- <10 > Default reconciliation: create/update the secret in all target namespaces.
134+ <11 > Default reconciliation: create/update the secret in all target namespaces.
121135Also triggers on source secret change through the `source_secret` trigger.
122136
123137### RBAC [[rbac]]
0 commit comments