pepr 0.42.1 → 0.42.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/cli/deploy.d.ts +15 -0
  2. package/dist/cli/deploy.d.ts.map +1 -1
  3. package/dist/cli/dev.d.ts.map +1 -1
  4. package/dist/cli/format.d.ts.map +1 -1
  5. package/dist/cli/format.helpers.d.ts +3 -0
  6. package/dist/cli/format.helpers.d.ts.map +1 -0
  7. package/dist/cli/init/enums.d.ts +10 -0
  8. package/dist/cli/init/enums.d.ts.map +1 -0
  9. package/dist/cli/init/index.d.ts.map +1 -1
  10. package/dist/cli/init/templates.d.ts +15 -11
  11. package/dist/cli/init/templates.d.ts.map +1 -1
  12. package/dist/cli/init/utils.d.ts.map +1 -1
  13. package/dist/cli/init/walkthrough.d.ts +3 -2
  14. package/dist/cli/init/walkthrough.d.ts.map +1 -1
  15. package/dist/cli/kfc.d.ts.map +1 -1
  16. package/dist/cli/root.d.ts.map +1 -1
  17. package/dist/cli/update.d.ts.map +1 -1
  18. package/dist/cli/uuid.d.ts.map +1 -1
  19. package/dist/cli.js +145 -306
  20. package/dist/controller.js +1 -195
  21. package/dist/fixtures/loader.d.ts.map +1 -1
  22. package/dist/lib/assets/deploy.d.ts.map +1 -1
  23. package/dist/lib/assets/index.d.ts +1 -1
  24. package/dist/lib/assets/index.d.ts.map +1 -1
  25. package/dist/lib/assets/pods.d.ts +1 -3
  26. package/dist/lib/assets/pods.d.ts.map +1 -1
  27. package/dist/lib/assets/rbac.d.ts.map +1 -1
  28. package/dist/lib/assets/webhooks.d.ts.map +1 -1
  29. package/dist/lib/controller/index.d.ts +2 -2
  30. package/dist/lib/controller/index.d.ts.map +1 -1
  31. package/dist/lib/controller/store.d.ts +1 -1
  32. package/dist/lib/controller/store.d.ts.map +1 -1
  33. package/dist/lib/controller/storeCache.d.ts +1 -1
  34. package/dist/lib/controller/storeCache.d.ts.map +1 -1
  35. package/dist/lib/{capability.d.ts → core/capability.d.ts} +1 -1
  36. package/dist/lib/core/capability.d.ts.map +1 -0
  37. package/dist/lib/{module.d.ts → core/module.d.ts} +2 -2
  38. package/dist/lib/core/module.d.ts.map +1 -0
  39. package/dist/lib/core/queue.d.ts.map +1 -0
  40. package/dist/lib/{schedule.d.ts → core/schedule.d.ts} +0 -1
  41. package/dist/lib/core/schedule.d.ts.map +1 -0
  42. package/dist/lib/core/storage.d.ts.map +1 -0
  43. package/dist/lib/deploymentChecks.d.ts.map +1 -1
  44. package/dist/lib/errors.d.ts +0 -5
  45. package/dist/lib/errors.d.ts.map +1 -1
  46. package/dist/lib/filesystemService.d.ts.map +1 -1
  47. package/dist/lib/filter/adjudicators/adjudicators.d.ts +5 -4
  48. package/dist/lib/filter/adjudicators/adjudicators.d.ts.map +1 -1
  49. package/dist/lib/filter/filter.d.ts +33 -1
  50. package/dist/lib/filter/filter.d.ts.map +1 -1
  51. package/dist/lib/finalizer.d.ts.map +1 -1
  52. package/dist/lib/helpers.d.ts +4 -9
  53. package/dist/lib/helpers.d.ts.map +1 -1
  54. package/dist/lib/included-files.d.ts.map +1 -1
  55. package/dist/lib/mutate-request.d.ts.map +1 -1
  56. package/dist/lib/processors/mutate-processor.d.ts +28 -0
  57. package/dist/lib/processors/mutate-processor.d.ts.map +1 -0
  58. package/dist/lib/{validate-processor.d.ts → processors/validate-processor.d.ts} +5 -5
  59. package/dist/lib/processors/validate-processor.d.ts.map +1 -0
  60. package/dist/lib/{watch-processor.d.ts → processors/watch-processor.d.ts} +2 -2
  61. package/dist/lib/processors/watch-processor.d.ts.map +1 -0
  62. package/dist/lib/telemetry/logger.d.ts.map +1 -1
  63. package/dist/lib/telemetry/metrics.d.ts.map +1 -1
  64. package/dist/lib/validate-request.d.ts +2 -2
  65. package/dist/lib/validate-request.d.ts.map +1 -1
  66. package/dist/lib.d.ts +2 -2
  67. package/dist/lib.d.ts.map +1 -1
  68. package/dist/lib.js +383 -243
  69. package/dist/lib.js.map +4 -4
  70. package/dist/sdk/heredoc.d.ts.map +1 -1
  71. package/package.json +9 -9
  72. package/src/cli/deploy.ts +113 -74
  73. package/src/cli/dev.ts +2 -2
  74. package/src/cli/format.helpers.ts +27 -0
  75. package/src/cli/format.ts +4 -18
  76. package/src/cli/init/enums.ts +9 -0
  77. package/src/cli/init/index.ts +4 -3
  78. package/src/cli/init/templates.ts +30 -2
  79. package/src/cli/init/utils.ts +3 -3
  80. package/src/cli/init/walkthrough.ts +7 -8
  81. package/src/cli/kfc.ts +1 -1
  82. package/src/cli/root.ts +1 -1
  83. package/src/cli/update.ts +1 -1
  84. package/src/cli/uuid.ts +1 -1
  85. package/src/fixtures/loader.ts +2 -2
  86. package/src/lib/assets/deploy.ts +5 -5
  87. package/src/lib/assets/index.ts +1 -1
  88. package/src/lib/assets/pods.ts +1 -1
  89. package/src/lib/assets/webhooks.ts +30 -45
  90. package/src/lib/controller/index.ts +4 -4
  91. package/src/lib/controller/store.ts +2 -2
  92. package/src/lib/controller/storeCache.ts +6 -2
  93. package/src/lib/{capability.ts → core/capability.ts} +4 -4
  94. package/src/lib/{module.ts → core/module.ts} +10 -10
  95. package/src/lib/{queue.ts → core/queue.ts} +1 -1
  96. package/src/lib/deploymentChecks.ts +2 -2
  97. package/src/lib/errors.ts +3 -8
  98. package/src/lib/filesystemService.ts +1 -1
  99. package/src/lib/filter/adjudicators/adjudicators.ts +40 -9
  100. package/src/lib/filter/filter.ts +204 -111
  101. package/src/lib/finalizer.ts +2 -2
  102. package/src/lib/helpers.ts +20 -133
  103. package/src/lib/included-files.ts +1 -1
  104. package/src/lib/processors/mutate-processor.ts +225 -0
  105. package/src/lib/{validate-processor.ts → processors/validate-processor.ts} +8 -8
  106. package/src/lib/{watch-processor.ts → processors/watch-processor.ts} +8 -8
  107. package/src/lib/telemetry/logger.ts +3 -1
  108. package/src/lib/tls.ts +5 -1
  109. package/src/lib/validate-request.ts +4 -4
  110. package/src/lib.ts +2 -2
  111. package/src/runtime/controller.ts +2 -2
  112. package/src/sdk/heredoc.ts +1 -1
  113. package/dist/lib/capability.d.ts.map +0 -1
  114. package/dist/lib/module.d.ts.map +0 -1
  115. package/dist/lib/mutate-processor.d.ts +0 -6
  116. package/dist/lib/mutate-processor.d.ts.map +0 -1
  117. package/dist/lib/queue.d.ts.map +0 -1
  118. package/dist/lib/schedule.d.ts.map +0 -1
  119. package/dist/lib/storage.d.ts.map +0 -1
  120. package/dist/lib/validate-processor.d.ts.map +0 -1
  121. package/dist/lib/watch-processor.d.ts.map +0 -1
  122. package/src/lib/mutate-processor.ts +0 -165
  123. /package/dist/lib/{queue.d.ts → core/queue.d.ts} +0 -0
  124. /package/dist/lib/{storage.d.ts → core/storage.d.ts} +0 -0
  125. /package/src/lib/{schedule.ts → core/schedule.ts} +0 -0
  126. /package/src/lib/{storage.ts → core/storage.ts} +0 -0
@@ -3,48 +3,55 @@
3
3
 
4
4
  import { AdmissionRequest, Binding } from "../types";
5
5
  import { Operation } from "../enums";
6
+ import { KubernetesObject } from "kubernetes-fluent-client";
6
7
  import {
7
- carriesIgnoredNamespace,
8
+ carriedAnnotations,
9
+ carriedLabels,
8
10
  carriedName,
9
- definedEvent,
10
- declaredOperation,
11
- definedName,
12
- definedGroup,
11
+ carriedNamespace,
12
+ carriesIgnoredNamespace,
13
13
  declaredGroup,
14
- definedVersion,
14
+ declaredKind,
15
+ declaredOperation,
15
16
  declaredVersion,
17
+ definedAnnotations,
18
+ definedEvent,
19
+ definedGroup,
16
20
  definedKind,
17
- declaredKind,
18
- definedNamespaces,
19
- carriedNamespace,
20
21
  definedLabels,
21
- carriedLabels,
22
- definedAnnotations,
23
- carriedAnnotations,
24
- definedNamespaceRegexes,
22
+ definedName,
25
23
  definedNameRegex,
24
+ definedNamespaceRegexes,
25
+ definedNamespaces,
26
+ definedVersion,
26
27
  misboundDeleteWithDeletionTimestamp,
27
- mismatchedDeletionTimestamp,
28
+ misboundNamespace,
28
29
  mismatchedAnnotations,
30
+ mismatchedDeletionTimestamp,
31
+ mismatchedEvent,
32
+ mismatchedGroup,
33
+ mismatchedKind,
29
34
  mismatchedLabels,
30
35
  mismatchedName,
31
36
  mismatchedNameRegex,
32
37
  mismatchedNamespace,
33
38
  mismatchedNamespaceRegex,
34
- mismatchedEvent,
35
- mismatchedGroup,
36
39
  mismatchedVersion,
37
- mismatchedKind,
38
40
  missingCarriableNamespace,
39
41
  unbindableNamespaces,
40
42
  uncarryableNamespace,
41
43
  } from "./adjudicators/adjudicators";
42
44
 
45
+ type AdjudicationResult = string | null;
46
+ type Adjudicator = () => AdjudicationResult;
47
+
43
48
  /**
44
- * shouldSkipRequest determines if a request should be skipped based on the binding filters.
49
+ * shouldSkipRequest determines if an admission request should be skipped based on the binding filters.
45
50
  *
46
51
  * @param binding the action binding
47
52
  * @param req the incoming request
53
+ * @param capabilityNamespaces the namespaces allowed by capability
54
+ * @param ignoredNamespaces the namespaces ignored by module config
48
55
  * @returns
49
56
  */
50
57
  export function shouldSkipRequest(
@@ -53,99 +60,185 @@ export function shouldSkipRequest(
53
60
  capabilityNamespaces: string[],
54
61
  ignoredNamespaces?: string[],
55
62
  ): string {
56
- const prefix = "Ignoring Admission Callback:";
57
63
  const obj = (req.operation === Operation.DELETE ? req.oldObject : req.object)!;
64
+ const prefix = "Ignoring Admission Callback:";
58
65
 
59
- // prettier-ignore
60
- return (
61
- misboundDeleteWithDeletionTimestamp(binding) ?
62
- `${prefix} Cannot use deletionTimestamp filter on a DELETE operation.` :
63
-
64
- mismatchedDeletionTimestamp(binding, obj) ?
65
- `${prefix} Binding defines deletionTimestamp but Object does not carry it.` :
66
-
67
- mismatchedEvent(binding, req) ?
68
- (
69
- `${prefix} Binding defines event '${definedEvent(binding)}' but ` +
70
- `Request declares '${declaredOperation(req)}'.`
71
- ) :
72
-
73
- mismatchedName(binding, obj) ?
74
- `${prefix} Binding defines name '${definedName(binding)}' but Object carries '${carriedName(obj)}'.` :
75
-
76
- mismatchedGroup(binding, req) ?
77
- (
78
- `${prefix} Binding defines group '${definedGroup(binding)}' but ` +
79
- `Request declares '${declaredGroup(req)}'.`
80
- ) :
81
-
82
- mismatchedVersion(binding, req) ?
83
- (
84
- `${prefix} Binding defines version '${definedVersion(binding)}' but ` +
85
- `Request declares '${declaredVersion(req)}'.`
86
- ) :
87
-
88
- mismatchedKind(binding, req) ?
89
- (
90
- `${prefix} Binding defines kind '${definedKind(binding)}' but ` +
91
- `Request declares '${declaredKind(req)}'.`
92
- ) :
93
-
94
- unbindableNamespaces(capabilityNamespaces, binding) ?
95
- (
96
- `${prefix} Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} ` +
97
- `but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
98
- ) :
99
-
100
- uncarryableNamespace(capabilityNamespaces, obj) ?
101
- (
102
- `${prefix} Object carries namespace '${carriedNamespace(obj)}' ` +
103
- `but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
104
- ) :
105
-
106
- mismatchedNamespace(binding, obj) ?
107
- (
108
- `${prefix} Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' ` +
109
- `but Object carries '${carriedNamespace(obj)}'.`
110
- ) :
111
-
112
- mismatchedLabels(binding, obj) ?
113
- (
114
- `${prefix} Binding defines labels '${JSON.stringify(definedLabels(binding))}' ` +
115
- `but Object carries '${JSON.stringify(carriedLabels(obj))}'.`
116
- ) :
117
-
118
- mismatchedAnnotations(binding, obj) ?
119
- (
120
- `${prefix} Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' ` +
121
- `but Object carries '${JSON.stringify(carriedAnnotations(obj))}'.`
122
- ) :
123
-
124
- mismatchedNamespaceRegex(binding, obj) ?
125
- (
126
- `${prefix} Binding defines namespace regexes ` +
127
- `'${JSON.stringify(definedNamespaceRegexes(binding))}' ` +
128
- `but Object carries '${carriedNamespace(obj)}'.`
129
- ) :
130
-
131
- mismatchedNameRegex(binding, obj) ?
132
- (
133
- `${prefix} Binding defines name regex '${definedNameRegex(binding)}' ` +
134
- `but Object carries '${carriedName(obj)}'.`
135
- ) :
136
-
137
- carriesIgnoredNamespace(ignoredNamespaces, obj) ?
138
- (
139
- `${prefix} Object carries namespace '${carriedNamespace(obj)}' ` +
140
- `but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.`
141
- ) :
142
-
143
- missingCarriableNamespace(capabilityNamespaces, obj) ?
144
- (
145
- `${prefix} Object does not carry a namespace ` +
146
- `but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
147
- ) :
148
-
149
- ""
150
- );
66
+ const adjudicators: Adjudicator[] = [
67
+ (): AdjudicationResult => adjudicateMisboundDeleteWithDeletionTimestamp(binding),
68
+ (): AdjudicationResult => adjudicateMismatchedDeletionTimestamp(binding, obj),
69
+ (): AdjudicationResult => adjudicateMismatchedEvent(binding, req),
70
+ (): AdjudicationResult => adjudicateMismatchedName(binding, obj),
71
+ (): AdjudicationResult => adjudicateMismatchedGroup(binding, req),
72
+ (): AdjudicationResult => adjudicateMismatchedVersion(binding, req),
73
+ (): AdjudicationResult => adjudicateMismatchedKind(binding, req),
74
+ (): AdjudicationResult => adjudicateUnbindableNamespaces(capabilityNamespaces, binding),
75
+ (): AdjudicationResult => adjudicateUncarryableNamespace(capabilityNamespaces, obj),
76
+ (): AdjudicationResult => adjudicateMismatchedNamespace(binding, obj),
77
+ (): AdjudicationResult => adjudicateMismatchedLabels(binding, obj),
78
+ (): AdjudicationResult => adjudicateMismatchedAnnotations(binding, obj),
79
+ (): AdjudicationResult => adjudicateMismatchedNamespaceRegex(binding, obj),
80
+ (): AdjudicationResult => adjudicateMismatchedNameRegex(binding, obj),
81
+ (): AdjudicationResult => adjudicateCarriesIgnoredNamespace(ignoredNamespaces, obj),
82
+ (): AdjudicationResult => adjudicateMissingCarriableNamespace(capabilityNamespaces, obj),
83
+ ];
84
+
85
+ for (const adjudicator of adjudicators) {
86
+ const result = adjudicator();
87
+ if (result) {
88
+ return `${prefix} ${result}`;
89
+ }
90
+ }
91
+
92
+ return "";
93
+ }
94
+
95
+ /**
96
+ * filterNoMatchReason determines whether a callback should be skipped after
97
+ * receiving an update event from the API server, based on the binding filters.
98
+ *
99
+ * @param binding the action binding
100
+ * @param kubernetesObject the incoming kubernetes object
101
+ * @param capabilityNamespaces the namespaces allowed by capability
102
+ * @param ignoredNamespaces the namespaces ignored by module config
103
+ */
104
+ export function filterNoMatchReason(
105
+ binding: Binding,
106
+ obj: Partial<KubernetesObject>,
107
+ capabilityNamespaces: string[],
108
+ ignoredNamespaces?: string[],
109
+ ): string {
110
+ const prefix = "Ignoring Watch Callback:";
111
+
112
+ const adjudicators: Adjudicator[] = [
113
+ (): AdjudicationResult => adjudicateMismatchedDeletionTimestamp(binding, obj),
114
+ (): AdjudicationResult => adjudicateMismatchedName(binding, obj),
115
+ (): AdjudicationResult => adjudicateMisboundNamespace(binding),
116
+ (): AdjudicationResult => adjudicateMismatchedLabels(binding, obj),
117
+ (): AdjudicationResult => adjudicateMismatchedAnnotations(binding, obj),
118
+ (): AdjudicationResult => adjudicateUncarryableNamespace(capabilityNamespaces, obj),
119
+ (): AdjudicationResult => adjudicateUnbindableNamespaces(capabilityNamespaces, binding),
120
+ (): AdjudicationResult => adjudicateMismatchedNamespace(binding, obj),
121
+ (): AdjudicationResult => adjudicateMismatchedNamespaceRegex(binding, obj),
122
+ (): AdjudicationResult => adjudicateMismatchedNameRegex(binding, obj),
123
+ (): AdjudicationResult => adjudicateCarriesIgnoredNamespace(ignoredNamespaces, obj),
124
+ (): AdjudicationResult => adjudicateMissingCarriableNamespace(capabilityNamespaces, obj),
125
+ ];
126
+
127
+ for (const adjudicator of adjudicators) {
128
+ const result = adjudicator();
129
+ if (result) {
130
+ return `${prefix} ${result}`;
131
+ }
132
+ }
133
+
134
+ return "";
135
+ }
136
+
137
+ export function adjudicateMisboundNamespace(binding: Binding): AdjudicationResult {
138
+ return misboundNamespace(binding) ? "Cannot use namespace filter on a namespace object." : null;
139
+ }
140
+
141
+ export function adjudicateMisboundDeleteWithDeletionTimestamp(binding: Binding): AdjudicationResult {
142
+ return misboundDeleteWithDeletionTimestamp(binding)
143
+ ? "Cannot use deletionTimestamp filter on a DELETE operation."
144
+ : null;
145
+ }
146
+
147
+ export function adjudicateMismatchedDeletionTimestamp(binding: Binding, obj: KubernetesObject): AdjudicationResult {
148
+ return mismatchedDeletionTimestamp(binding, obj)
149
+ ? "Binding defines deletionTimestamp but Object does not carry it."
150
+ : null;
151
+ }
152
+
153
+ export function adjudicateMismatchedEvent(binding: Binding, req: AdmissionRequest): AdjudicationResult {
154
+ return mismatchedEvent(binding, req)
155
+ ? `Binding defines event '${definedEvent(binding)}' but Request declares '${declaredOperation(req)}'.`
156
+ : null;
157
+ }
158
+
159
+ export function adjudicateMismatchedName(binding: Binding, obj: KubernetesObject): AdjudicationResult {
160
+ return mismatchedName(binding, obj)
161
+ ? `Binding defines name '${definedName(binding)}' but Object carries '${carriedName(obj)}'.`
162
+ : null;
163
+ }
164
+
165
+ export function adjudicateMismatchedGroup(binding: Binding, req: AdmissionRequest): AdjudicationResult {
166
+ return mismatchedGroup(binding, req)
167
+ ? `Binding defines group '${definedGroup(binding)}' but Request declares '${declaredGroup(req)}'.`
168
+ : null;
169
+ }
170
+
171
+ export function adjudicateMismatchedVersion(binding: Binding, req: AdmissionRequest): AdjudicationResult {
172
+ return mismatchedVersion(binding, req)
173
+ ? `Binding defines version '${definedVersion(binding)}' but Request declares '${declaredVersion(req)}'.`
174
+ : null;
175
+ }
176
+
177
+ export function adjudicateMismatchedKind(binding: Binding, req: AdmissionRequest): AdjudicationResult {
178
+ return mismatchedKind(binding, req)
179
+ ? `Binding defines kind '${definedKind(binding)}' but Request declares '${declaredKind(req)}'.`
180
+ : null;
181
+ }
182
+
183
+ export function adjudicateUnbindableNamespaces(capabilityNamespaces: string[], binding: Binding): AdjudicationResult {
184
+ return unbindableNamespaces(capabilityNamespaces, binding)
185
+ ? `Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
186
+ : null;
187
+ }
188
+
189
+ export function adjudicateUncarryableNamespace(
190
+ capabilityNamespaces: string[],
191
+ obj: KubernetesObject,
192
+ ): AdjudicationResult {
193
+ return uncarryableNamespace(capabilityNamespaces, obj)
194
+ ? `Object carries namespace '${obj.kind && obj.kind === "Namespace" ? obj.metadata?.name : carriedNamespace(obj)}' but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
195
+ : null;
196
+ }
197
+
198
+ export function adjudicateMismatchedNamespace(binding: Binding, obj: KubernetesObject): AdjudicationResult {
199
+ return mismatchedNamespace(binding, obj)
200
+ ? `Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' but Object carries '${carriedNamespace(obj)}'.`
201
+ : null;
202
+ }
203
+
204
+ export function adjudicateMismatchedLabels(binding: Binding, obj: KubernetesObject): AdjudicationResult {
205
+ return mismatchedLabels(binding, obj)
206
+ ? `Binding defines labels '${JSON.stringify(definedLabels(binding))}' but Object carries '${JSON.stringify(carriedLabels(obj))}'.`
207
+ : null;
208
+ }
209
+
210
+ export function adjudicateMismatchedAnnotations(binding: Binding, obj: KubernetesObject): AdjudicationResult {
211
+ return mismatchedAnnotations(binding, obj)
212
+ ? `Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' but Object carries '${JSON.stringify(carriedAnnotations(obj))}'.`
213
+ : null;
214
+ }
215
+
216
+ export function adjudicateMismatchedNamespaceRegex(binding: Binding, obj: KubernetesObject): AdjudicationResult {
217
+ return mismatchedNamespaceRegex(binding, obj)
218
+ ? `Binding defines namespace regexes '${JSON.stringify(definedNamespaceRegexes(binding))}' but Object carries '${carriedNamespace(obj)}'.`
219
+ : null;
220
+ }
221
+
222
+ export function adjudicateMismatchedNameRegex(binding: Binding, obj: KubernetesObject): AdjudicationResult {
223
+ return mismatchedNameRegex(binding, obj)
224
+ ? `Binding defines name regex '${definedNameRegex(binding)}' but Object carries '${carriedName(obj)}'.`
225
+ : null;
226
+ }
227
+
228
+ export function adjudicateCarriesIgnoredNamespace(
229
+ ignoredNamespaces: string[] | undefined,
230
+ obj: KubernetesObject,
231
+ ): AdjudicationResult {
232
+ return carriesIgnoredNamespace(ignoredNamespaces, obj)
233
+ ? `Object carries namespace '${obj.kind && obj.kind === "Namespace" ? obj.metadata?.name : carriedNamespace(obj)}' but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.`
234
+ : null;
235
+ }
236
+
237
+ export function adjudicateMissingCarriableNamespace(
238
+ capabilityNamespaces: string[],
239
+ obj: KubernetesObject,
240
+ ): AdjudicationResult {
241
+ return missingCarriableNamespace(capabilityNamespaces, obj)
242
+ ? `Object does not carry a namespace but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
243
+ : null;
151
244
  }
@@ -7,7 +7,7 @@ import { Binding, DeepPartial } from "./types";
7
7
  import { Operation } from "./enums";
8
8
  import { PeprMutateRequest } from "./mutate-request";
9
9
 
10
- export function addFinalizer<K extends KubernetesObject>(request: PeprMutateRequest<K>) {
10
+ export function addFinalizer<K extends KubernetesObject>(request: PeprMutateRequest<K>): void {
11
11
  // if a DELETE is being processed, don't add a finalizer
12
12
  if (request.Request.operation === Operation.DELETE) {
13
13
  return;
@@ -28,7 +28,7 @@ export function addFinalizer<K extends KubernetesObject>(request: PeprMutateRequ
28
28
  request.Merge({ metadata: { finalizers } } as DeepPartial<K>);
29
29
  }
30
30
 
31
- export async function removeFinalizer(binding: Binding, obj: KubernetesObject) {
31
+ export async function removeFinalizer(binding: Binding, obj: KubernetesObject): Promise<void> {
32
32
  const peprFinal = "pepr.dev/finalizer";
33
33
  const meta = obj.metadata!;
34
34
  const resource = `${meta.namespace || "ClusterScoped"}/${meta.name}`;
@@ -1,34 +1,9 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
3
 
4
- import { KubernetesObject } from "kubernetes-fluent-client";
5
4
  import Log from "./telemetry/logger";
6
5
  import { Binding, CapabilityExport } from "./types";
7
6
  import { sanitizeResourceName } from "../sdk/sdk";
8
- import {
9
- carriedAnnotations,
10
- carriedLabels,
11
- carriedName,
12
- carriedNamespace,
13
- carriesIgnoredNamespace,
14
- definedAnnotations,
15
- definedLabels,
16
- definedName,
17
- definedNameRegex,
18
- definedNamespaces,
19
- definedNamespaceRegexes,
20
- misboundNamespace,
21
- mismatchedAnnotations,
22
- mismatchedDeletionTimestamp,
23
- mismatchedLabels,
24
- mismatchedName,
25
- mismatchedNameRegex,
26
- mismatchedNamespace,
27
- mismatchedNamespaceRegex,
28
- missingCarriableNamespace,
29
- unbindableNamespaces,
30
- uncarryableNamespace,
31
- } from "./filter/adjudicators/adjudicators";
32
7
 
33
8
  export function matchesRegex(pattern: string, testString: string): boolean {
34
9
  return new RegExp(pattern).test(testString);
@@ -55,100 +30,13 @@ export function validateHash(expectedHash: string): void {
55
30
  }
56
31
  }
57
32
 
58
- export type RBACMap = {
33
+ type RBACMap = {
59
34
  [key: string]: {
60
35
  verbs: string[];
61
36
  plural: string;
62
37
  };
63
38
  };
64
39
 
65
- /**
66
- * Decide to run callback after the event comes back from API Server
67
- **/
68
- export function filterNoMatchReason(
69
- binding: Binding,
70
- kubernetesObject: Partial<KubernetesObject>,
71
- capabilityNamespaces: string[],
72
- ignoredNamespaces?: string[],
73
- ): string {
74
- const prefix = "Ignoring Watch Callback:";
75
-
76
- // prettier-ignore
77
- return (
78
- mismatchedDeletionTimestamp(binding, kubernetesObject) ?
79
- `${prefix} Binding defines deletionTimestamp but Object does not carry it.` :
80
-
81
- mismatchedName(binding, kubernetesObject) ?
82
- `${prefix} Binding defines name '${definedName(binding)}' but Object carries '${carriedName(kubernetesObject)}'.` :
83
-
84
- misboundNamespace(binding) ?
85
- `${prefix} Cannot use namespace filter on a namespace object.` :
86
-
87
- mismatchedLabels(binding, kubernetesObject) ?
88
- (
89
- `${prefix} Binding defines labels '${JSON.stringify(definedLabels(binding))}' ` +
90
- `but Object carries '${JSON.stringify(carriedLabels(kubernetesObject))}'.`
91
- ) :
92
-
93
- mismatchedAnnotations(binding, kubernetesObject) ?
94
- (
95
- `${prefix} Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' ` +
96
- `but Object carries '${JSON.stringify(carriedAnnotations(kubernetesObject))}'.`
97
- ) :
98
-
99
- uncarryableNamespace(capabilityNamespaces, kubernetesObject) ?
100
- (
101
- `${prefix} Object carries namespace '${carriedNamespace(kubernetesObject)}' ` +
102
- `but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
103
- ) :
104
-
105
- unbindableNamespaces(capabilityNamespaces, binding) ?
106
- (
107
- `${prefix} Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} ` +
108
- `but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
109
- ) :
110
-
111
- mismatchedNamespace(binding, kubernetesObject) ?
112
- (
113
- `${prefix} Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' ` +
114
- `but Object carries '${carriedNamespace(kubernetesObject)}'.`
115
- ) :
116
-
117
- mismatchedNamespaceRegex(binding, kubernetesObject) ?
118
- (
119
- `${prefix} Binding defines namespace regexes ` +
120
- `'${JSON.stringify(definedNamespaceRegexes(binding))}' ` +
121
- `but Object carries '${carriedNamespace(kubernetesObject)}'.`
122
- ) :
123
-
124
- mismatchedNameRegex(binding, kubernetesObject) ?
125
- (
126
- `${prefix} Binding defines name regex '${definedNameRegex(binding)}' ` +
127
- `but Object carries '${carriedName(kubernetesObject)}'.`
128
- ) :
129
-
130
- carriesIgnoredNamespace(ignoredNamespaces, kubernetesObject) ?
131
- (
132
- `${prefix} Object carries namespace '${carriedNamespace(kubernetesObject)}' ` +
133
- `but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.`
134
- ) :
135
-
136
- missingCarriableNamespace(capabilityNamespaces, kubernetesObject) ?
137
- (
138
- `${prefix} Object does not carry a namespace ` +
139
- `but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
140
- ) :
141
-
142
- ""
143
- );
144
- }
145
-
146
- export function addVerbIfNotExists(verbs: string[], verb: string) {
147
- if (!verbs.includes(verb)) {
148
- verbs.push(verb);
149
- }
150
- }
151
-
152
40
  export function createRBACMap(capabilities: CapabilityExport[]): RBACMap {
153
41
  return capabilities.reduce((acc: RBACMap, capability: CapabilityExport) => {
154
42
  capability.bindings.forEach(binding => {
@@ -200,11 +88,11 @@ export function hasAnyOverlap<T>(array1: T[], array2: T[]): boolean {
200
88
  return array1.some(element => array2.includes(element));
201
89
  }
202
90
 
203
- export function ignoredNamespaceConflict(ignoreNamespaces: string[], bindingNamespaces: string[]) {
91
+ export function ignoredNamespaceConflict(ignoreNamespaces: string[], bindingNamespaces: string[]): boolean {
204
92
  return hasAnyOverlap(bindingNamespaces, ignoreNamespaces);
205
93
  }
206
94
 
207
- export function bindingAndCapabilityNSConflict(bindingNamespaces: string[], capabilityNamespaces: string[]) {
95
+ export function bindingAndCapabilityNSConflict(bindingNamespaces: string[], capabilityNamespaces: string[]): boolean {
208
96
  if (!capabilityNamespaces) {
209
97
  return false;
210
98
  }
@@ -215,7 +103,7 @@ export function generateWatchNamespaceError(
215
103
  ignoredNamespaces: string[],
216
104
  bindingNamespaces: string[],
217
105
  capabilityNamespaces: string[],
218
- ) {
106
+ ): string {
219
107
  let err = "";
220
108
 
221
109
  // check if binding uses an ignored namespace
@@ -237,7 +125,7 @@ export function generateWatchNamespaceError(
237
125
  }
238
126
 
239
127
  // namespaceComplianceValidator ensures that capability bindings respect ignored and capability namespaces
240
- export function namespaceComplianceValidator(capability: CapabilityExport, ignoredNamespaces?: string[]) {
128
+ export function namespaceComplianceValidator(capability: CapabilityExport, ignoredNamespaces?: string[]): void {
241
129
  const { namespaces: capabilityNamespaces, bindings, name } = capability;
242
130
  const bindingNamespaces: string[] = bindings.flatMap((binding: Binding) => binding.filters.namespaces);
243
131
  const bindingRegexNamespaces: string[] = bindings.flatMap(
@@ -256,13 +144,16 @@ export function namespaceComplianceValidator(capability: CapabilityExport, ignor
256
144
  }
257
145
 
258
146
  // Ensure that each regexNamespace matches a capabilityNamespace
147
+ matchRegexToCapababilityNamespace(bindingRegexNamespaces, capabilityNamespaces);
148
+ // ensure regexNamespaces do not match ignored ns
149
+ checkRegexNamespaces(bindingRegexNamespaces, ignoredNamespaces);
150
+ }
259
151
 
260
- if (
261
- bindingRegexNamespaces &&
262
- bindingRegexNamespaces.length > 0 &&
263
- capabilityNamespaces &&
264
- capabilityNamespaces.length > 0
265
- ) {
152
+ const matchRegexToCapababilityNamespace = (
153
+ bindingRegexNamespaces: string[],
154
+ capabilityNamespaces: string[] | undefined,
155
+ ): void => {
156
+ if (bindingRegexNamespaces.length > 0 && capabilityNamespaces && capabilityNamespaces.length > 0) {
266
157
  for (const regexNamespace of bindingRegexNamespaces) {
267
158
  let matches = false;
268
159
  matches =
@@ -275,13 +166,10 @@ export function namespaceComplianceValidator(capability: CapabilityExport, ignor
275
166
  }
276
167
  }
277
168
  }
278
- // ensure regexNamespaces do not match ignored ns
279
- if (
280
- bindingRegexNamespaces &&
281
- bindingRegexNamespaces.length > 0 &&
282
- ignoredNamespaces &&
283
- ignoredNamespaces.length > 0
284
- ) {
169
+ };
170
+
171
+ const checkRegexNamespaces = (bindingRegexNamespaces: string[], ignoredNamespaces: string[] | undefined): void => {
172
+ if (bindingRegexNamespaces.length > 0 && ignoredNamespaces && ignoredNamespaces.length > 0) {
285
173
  for (const regexNamespace of bindingRegexNamespaces) {
286
174
  const matchedNS = ignoredNamespaces.find(ignoredNS => matchesRegex(regexNamespace, ignoredNS));
287
175
  if (matchedNS) {
@@ -291,7 +179,7 @@ export function namespaceComplianceValidator(capability: CapabilityExport, ignor
291
179
  }
292
180
  }
293
181
  }
294
- }
182
+ };
295
183
 
296
184
  // check if secret is over the size limit
297
185
  export function secretOverLimit(str: string): boolean {
@@ -302,8 +190,7 @@ export function secretOverLimit(str: string): boolean {
302
190
  return sizeInBytes > oneMiBInBytes;
303
191
  }
304
192
 
305
- /* eslint-disable @typescript-eslint/no-unused-vars */
306
- export const parseTimeout = (value: string, previous: unknown): number => {
193
+ export const parseTimeout = (value: string): number => {
307
194
  const parsedValue = parseInt(value, 10);
308
195
  const floatValue = parseFloat(value);
309
196
  if (isNaN(parsedValue)) {
@@ -3,7 +3,7 @@
3
3
 
4
4
  import { promises as fs } from "fs";
5
5
 
6
- export async function createDockerfile(version: string, description: string, includedFiles: string[]) {
6
+ export async function createDockerfile(version: string, description: string, includedFiles: string[]): Promise<void> {
7
7
  const file = `
8
8
  # Use an official Node.js runtime as the base image
9
9
  FROM ghcr.io/defenseunicorns/pepr/controller:v${version}