pepr 0.1.27 → 0.1.29

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 (62) hide show
  1. package/cli.ts +3 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +4 -0
  4. package/dist/index.d.ts +5 -0
  5. package/dist/index.js +14 -0
  6. package/dist/package.json +76 -0
  7. package/dist/src/cli/banner.d.ts +1 -0
  8. package/dist/{pepr-cli.js → src/cli/banner.js} +4 -1251
  9. package/dist/src/cli/build.d.ts +7 -0
  10. package/dist/src/cli/build.js +102 -0
  11. package/dist/src/cli/capability.d.ts +2 -0
  12. package/dist/src/cli/capability.js +15 -0
  13. package/dist/src/cli/deploy.d.ts +2 -0
  14. package/dist/src/cli/deploy.js +55 -0
  15. package/dist/src/cli/dev.d.ts +2 -0
  16. package/dist/src/cli/dev.js +96 -0
  17. package/dist/src/cli/index.d.ts +1 -0
  18. package/dist/src/cli/index.js +33 -0
  19. package/dist/src/cli/init/index.d.ts +2 -0
  20. package/dist/src/cli/init/index.js +54 -0
  21. package/dist/src/cli/init/templates.d.ts +82 -0
  22. package/dist/src/cli/init/templates.js +229 -0
  23. package/dist/src/cli/init/utils.d.ts +20 -0
  24. package/dist/src/cli/init/utils.js +56 -0
  25. package/dist/src/cli/init/walkthrough.d.ts +7 -0
  26. package/dist/src/cli/init/walkthrough.js +84 -0
  27. package/dist/src/cli/root.d.ts +4 -0
  28. package/dist/src/cli/root.js +21 -0
  29. package/dist/src/cli/test.d.ts +2 -0
  30. package/dist/src/cli/test.js +51 -0
  31. package/dist/src/lib/capability.d.ts +26 -0
  32. package/dist/src/lib/capability.js +119 -0
  33. package/dist/src/lib/controller.d.ts +13 -0
  34. package/dist/src/lib/controller.js +84 -0
  35. package/dist/src/lib/filter.d.ts +10 -0
  36. package/dist/src/lib/filter.js +48 -0
  37. package/dist/src/lib/k8s/index.d.ts +4 -0
  38. package/dist/src/lib/k8s/index.js +38 -0
  39. package/dist/src/lib/k8s/kinds.d.ts +3 -0
  40. package/dist/src/lib/k8s/kinds.js +431 -0
  41. package/dist/src/lib/k8s/tls.d.ts +17 -0
  42. package/dist/src/lib/k8s/tls.js +74 -0
  43. package/dist/src/lib/k8s/types.d.ts +136 -0
  44. package/dist/src/lib/k8s/types.js +12 -0
  45. package/dist/src/lib/k8s/upstream.d.ts +1 -0
  46. package/dist/src/lib/k8s/upstream.js +47 -0
  47. package/dist/src/lib/k8s/webhook.d.ts +33 -0
  48. package/dist/src/lib/k8s/webhook.js +497 -0
  49. package/dist/src/lib/logger.d.ts +54 -0
  50. package/dist/{types-1709b44f.js → src/lib/logger.js} +6 -39
  51. package/dist/src/lib/module.d.ts +22 -0
  52. package/dist/src/lib/module.js +39 -0
  53. package/dist/src/lib/processor.d.ts +4 -0
  54. package/dist/src/lib/processor.js +73 -0
  55. package/dist/src/lib/request.d.ts +77 -0
  56. package/dist/src/lib/request.js +144 -0
  57. package/dist/src/lib/types.d.ts +187 -0
  58. package/dist/src/lib/types.js +34 -0
  59. package/package.json +8 -11
  60. package/tsconfig.build.json +4 -0
  61. package/dist/pepr-core.js +0 -949
  62. package/tsconfig.json +0 -17
package/dist/pepr-core.js DELETED
@@ -1,949 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- var dist = require('@kubernetes/client-node/dist');
5
- var types = require('./types-1709b44f.js');
6
- var R = require('ramda');
7
- var express = require('express');
8
- var fs = require('fs');
9
- var https = require('https');
10
- var fastJsonPatch = require('fast-json-patch');
11
-
12
- function _interopNamespaceDefault(e) {
13
- var n = Object.create(null);
14
- if (e) {
15
- Object.keys(e).forEach(function (k) {
16
- if (k !== 'default') {
17
- var d = Object.getOwnPropertyDescriptor(e, k);
18
- Object.defineProperty(n, k, d.get ? d : {
19
- enumerable: true,
20
- get: function () { return e[k]; }
21
- });
22
- }
23
- });
24
- }
25
- n.default = e;
26
- return Object.freeze(n);
27
- }
28
-
29
- var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
30
-
31
- // SPDX-License-Identifier: Apache-2.0
32
-
33
- var upstream = /*#__PURE__*/Object.freeze({
34
- __proto__: null,
35
- APIService: dist.V1APIService,
36
- CSIDriver: dist.V1CSIDriver,
37
- CSIStorageCapacity: dist.V1CSIStorageCapacity,
38
- CertificateSigningRequest: dist.V1CertificateSigningRequest,
39
- ConfigMap: dist.V1ConfigMap,
40
- ControllerRevision: dist.V1ControllerRevision,
41
- CronJob: dist.V1CronJob,
42
- CustomResourceDefinition: dist.V1CustomResourceDefinition,
43
- DaemonSet: dist.V1DaemonSet,
44
- Deployment: dist.V1Deployment,
45
- EndpointSlice: dist.V1EndpointSlice,
46
- HorizontalPodAutoscaler: dist.V1HorizontalPodAutoscaler,
47
- Ingress: dist.V1Ingress,
48
- IngressClass: dist.V1IngressClass,
49
- Job: dist.V1Job,
50
- LimitRange: dist.V1LimitRange,
51
- LocalSubjectAccessReview: dist.V1LocalSubjectAccessReview,
52
- MutatingWebhookConfiguration: dist.V1MutatingWebhookConfiguration,
53
- Namespace: dist.V1Namespace,
54
- NetworkPolicy: dist.V1NetworkPolicy,
55
- Node: dist.V1Node,
56
- PersistentVolume: dist.V1PersistentVolume,
57
- PersistentVolumeClaim: dist.V1PersistentVolumeClaim,
58
- Pod: dist.V1Pod,
59
- PodDisruptionBudget: dist.V1PodDisruptionBudget,
60
- PodTemplate: dist.V1PodTemplate,
61
- ReplicaSet: dist.V1ReplicaSet,
62
- ReplicationController: dist.V1ReplicationController,
63
- ResourceQuota: dist.V1ResourceQuota,
64
- RuntimeClass: dist.V1RuntimeClass,
65
- Secret: dist.V1Secret,
66
- SelfSubjectAccessReview: dist.V1SelfSubjectAccessReview,
67
- SelfSubjectRulesReview: dist.V1SelfSubjectRulesReview,
68
- Service: dist.V1Service,
69
- ServiceAccount: dist.V1ServiceAccount,
70
- StatefulSet: dist.V1StatefulSet,
71
- StorageClass: dist.V1StorageClass,
72
- SubjectAccessReview: dist.V1SubjectAccessReview,
73
- TokenReview: dist.V1TokenReview,
74
- ValidatingWebhookConfiguration: dist.V1ValidatingWebhookConfiguration,
75
- VolumeAttachment: dist.V1VolumeAttachment
76
- });
77
-
78
- // SPDX-License-Identifier: Apache-2.0
79
- // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
80
- const gvkMap = {
81
- /**
82
- * Represents a K8s ConfigMap resource.
83
- * ConfigMap holds configuration data for pods to consume.
84
- * @see {@link https://kubernetes.io/docs/concepts/configuration/configmap/}
85
- */
86
- V1ConfigMap: {
87
- kind: "ConfigMap",
88
- version: "v1",
89
- group: "",
90
- },
91
- /**
92
- * Represents a K8s Endpoints resource.
93
- * Endpoints expose a service's IP addresses and ports to other resources.
94
- * @see {@link https://kubernetes.io/docs/concepts/services-networking/service/#endpoints}
95
- */
96
- V1Endpoint: {
97
- kind: "Endpoints",
98
- version: "v1",
99
- group: "",
100
- },
101
- /**
102
- * Represents a K8s LimitRange resource.
103
- * LimitRange enforces constraints on the resource consumption of objects in a namespace.
104
- * @see {@link https://kubernetes.io/docs/concepts/policy/limit-range/}
105
- */
106
- V1LimitRange: {
107
- kind: "LimitRange",
108
- version: "v1",
109
- group: "",
110
- },
111
- /**
112
- * Represents a K8s Namespace resource.
113
- * Namespace is a way to divide cluster resources between multiple users.
114
- * @see {@link https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/}
115
- */
116
- V1Namespace: {
117
- kind: "Namespace",
118
- version: "v1",
119
- group: "",
120
- },
121
- /**
122
- * Represents a K8s Node resource.
123
- * Node is a worker machine in Kubernetes.
124
- * @see {@link https://kubernetes.io/docs/concepts/architecture/nodes/}
125
- */
126
- V1Node: {
127
- kind: "Node",
128
- version: "v1",
129
- group: "",
130
- },
131
- /**
132
- * Represents a K8s PersistentVolumeClaim resource.
133
- * PersistentVolumeClaim is a user's request for and claim to a persistent volume.
134
- * @see {@link https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims}
135
- */
136
- V1PersistentVolumeClaim: {
137
- kind: "PersistentVolumeClaim",
138
- version: "v1",
139
- group: "",
140
- },
141
- /**
142
- * Represents a K8s PersistentVolume resource.
143
- * PersistentVolume is a piece of storage in the cluster that has been provisioned by an administrator.
144
- * @see {@link https://kubernetes.io/docs/concepts/storage/persistent-volumes/}
145
- */
146
- V1PersistentVolume: {
147
- kind: "PersistentVolume",
148
- version: "v1",
149
- group: "",
150
- },
151
- /**
152
- * Represents a K8s Pod resource.
153
- * Pod is the smallest and simplest unit in the Kubernetes object model.
154
- * @see {@link https://kubernetes.io/docs/concepts/workloads/pods/}
155
- */
156
- V1Pod: {
157
- kind: "Pod",
158
- version: "v1",
159
- group: "",
160
- },
161
- /**
162
- * Represents a K8s PodTemplate resource.
163
- * PodTemplate is an object that describes the pod that will be created from a higher level abstraction.
164
- * @see {@link https://kubernetes.io/docs/concepts/workloads/controllers/#pod-template}
165
- */
166
- V1PodTemplate: {
167
- kind: "PodTemplate",
168
- version: "v1",
169
- group: "",
170
- },
171
- /**
172
- * Represents a K8s ReplicationController resource.
173
- * ReplicationController ensures that a specified number of pod replicas are running at any given time.
174
- * @see {@link https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/}
175
- */
176
- V1ReplicationController: {
177
- kind: "ReplicationController",
178
- version: "v1",
179
- group: "",
180
- },
181
- /**
182
- * Represents a K8s ResourceQuota resource.
183
- * ResourceQuota provides constraints that limit resource consumption per namespace.
184
- * @see {@link https://kubernetes.io/docs/concepts/policy/resource-quotas/}
185
- */
186
- V1ResourceQuota: {
187
- kind: "ResourceQuota",
188
- version: "v1",
189
- group: "",
190
- },
191
- /**
192
- * Represents a K8s Secret resource.
193
- * Secret holds secret data of a certain type.
194
- * @see {@link https://kubernetes.io/docs/concepts/configuration/secret/}
195
- */
196
- V1Secret: {
197
- kind: "Secret",
198
- version: "v1",
199
- group: "",
200
- },
201
- /**
202
- * Represents a K8s ServiceAccount resource.
203
- * ServiceAccount is an identity that processes in a pod can use to access the Kubernetes API.
204
- * @see {@link https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/}
205
- */
206
- V1ServiceAccount: {
207
- kind: "ServiceAccount",
208
- version: "v1",
209
- group: "",
210
- },
211
- /**
212
- * Represents a K8s Service resource.
213
- * Service is an abstraction which defines a logical set of Pods and a policy by which to access them.
214
- * @see {@link https://kubernetes.io/docs/concepts/services-networking/service/}
215
- */
216
- V1Service: {
217
- kind: "Service",
218
- version: "v1",
219
- group: "",
220
- },
221
- /**
222
- * Represents a K8s MutatingWebhookConfiguration resource.
223
- * MutatingWebhookConfiguration configures a mutating admission webhook.
224
- * @see {@link https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#configure-admission-webhooks-on-the-fly}
225
- */
226
- V1MutatingWebhookConfiguration: {
227
- kind: "MutatingWebhookConfiguration",
228
- version: "v1",
229
- group: "admissionregistration.k8s.io",
230
- },
231
- /**
232
- * Represents a K8s ValidatingWebhookConfiguration resource.
233
- * ValidatingWebhookConfiguration configures a validating admission webhook.
234
- * @see {@link https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#configure-admission-webhooks-on-the-fly}
235
- */
236
- V1ValidatingWebhookConfiguration: {
237
- kind: "ValidatingWebhookConfiguration",
238
- version: "v1",
239
- group: "admissionregistration.k8s.io",
240
- },
241
- /**
242
- * Represents a K8s CustomResourceDefinition resource.
243
- * CustomResourceDefinition is a custom resource in a Kubernetes cluster.
244
- * @see {@link https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/}
245
- */
246
- V1CustomResourceDefinition: {
247
- kind: "CustomResourceDefinition",
248
- version: "v1",
249
- group: "apiextensions.k8s.io",
250
- },
251
- /**
252
- * Represents a K8s APIService resource.
253
- * APIService represents a server for a particular API version and group.
254
- * @see {@link https://kubernetes.io/docs/tasks/access-kubernetes-api/setup-extension-api-server/}
255
- */
256
- V1APIService: {
257
- kind: "APIService",
258
- version: "v1",
259
- group: "apiregistration.k8s.io",
260
- },
261
- /**
262
- * Represents a K8s ControllerRevision resource.
263
- * ControllerRevision is used to manage the history of a StatefulSet or DaemonSet.
264
- * @see {@link https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#revision-history}
265
- */
266
- V1ControllerRevision: {
267
- kind: "ControllerRevision",
268
- version: "v1",
269
- group: "apps",
270
- },
271
- /**
272
- * Represents a K8s DaemonSet resource.
273
- * DaemonSet ensures that all (or some) nodes run a copy of a Pod.
274
- * @see {@link https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/}
275
- */
276
- V1DaemonSet: {
277
- kind: "DaemonSet",
278
- version: "v1",
279
- group: "apps",
280
- },
281
- /**
282
- * Represents a K8s Deployment resource.
283
- * Deployment provides declarative updates for Pods and ReplicaSets.
284
- * @see {@link https://kubernetes.io/docs/concepts/workloads/controllers/deployment/}
285
- */
286
- V1Deployment: {
287
- kind: "Deployment",
288
- version: "v1",
289
- group: "apps",
290
- },
291
- /**
292
- * Represents a K8s ReplicaSet resource.
293
- * ReplicaSet ensures that a specified number of pod replicas are running at any given time.
294
- * @see {@link https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/}
295
- */
296
- V1ReplicaSet: {
297
- kind: "ReplicaSet",
298
- version: "v1",
299
- group: "apps",
300
- },
301
- /**
302
- * Represents a K8s StatefulSet resource.
303
- * StatefulSet is used to manage stateful applications.
304
- * @see {@link https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/}
305
- */
306
- V1StatefulSet: {
307
- kind: "StatefulSet",
308
- version: "v1",
309
- group: "apps",
310
- },
311
- /**
312
- * Represents a K8s TokenReview resource.
313
- * TokenReview attempts to authenticate a token to a known user.
314
- * @see {@link https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#tokenreview-v1-authentication-k8s-io}
315
- */
316
- V1TokenReview: {
317
- kind: "TokenReview",
318
- version: "v1",
319
- group: "authentication.k8s.io",
320
- },
321
- /**
322
- * Represents a K8s LocalSubjectAccessReview resource.
323
- * LocalSubjectAccessReview checks whether a specific user can perform a specific action in a specific namespace.
324
- * @see {@link https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#localsubjectaccessreview-v1-authorization-k8s-io}
325
- */
326
- V1LocalSubjectAccessReview: {
327
- kind: "LocalSubjectAccessReview",
328
- version: "v1",
329
- group: "authorization.k8s.io",
330
- },
331
- /**
332
- * Represents a K8s SelfSubjectAccessReview resource.
333
- * SelfSubjectAccessReview checks whether the current user can perform a specific action.
334
- * @see {@link https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#selfsubjectaccessreview-v1-authorization-k8s-io}
335
- */
336
- V1SelfSubjectAccessReview: {
337
- kind: "SelfSubjectAccessReview",
338
- version: "v1",
339
- group: "authorization.k8s.io",
340
- },
341
- /**
342
- * Represents a K8s SelfSubjectRulesReview resource.
343
- * SelfSubjectRulesReview lists the permissions a specific user has within a namespace.
344
- * @see {@link https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#selfsubjectrulesreview-v1-authorization-k8s-io}
345
- */
346
- V1SelfSubjectRulesReview: {
347
- kind: "SelfSubjectRulesReview",
348
- version: "v1",
349
- group: "authorization.k8s.io",
350
- },
351
- /**
352
- * Represents a K8s SubjectAccessReview resource.
353
- * SubjectAccessReview checks whether a specific user can perform a specific action.
354
- * @see {@link https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#subjectaccessreview-v1-authorization-k8s-io}
355
- */
356
- V1SubjectAccessReview: {
357
- kind: "SubjectAccessReview",
358
- version: "v1",
359
- group: "authorization.k8s.io",
360
- },
361
- /**
362
- * Represents a K8s HorizontalPodAutoscaler resource.
363
- * HorizontalPodAutoscaler automatically scales the number of Pods in a replication controller, deployment, or replica set.
364
- * @see {@link https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/}
365
- */
366
- V1HorizontalPodAutoscaler: {
367
- kind: "HorizontalPodAutoscaler",
368
- version: "v2",
369
- group: "autoscaling",
370
- },
371
- /**
372
- * Represents a K8s CronJob resource.
373
- * CronJob manages time-based jobs, specifically those that run periodically and complete after a successful execution.
374
- * @see {@link https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/}
375
- */
376
- V1CronJob: {
377
- kind: "CronJob",
378
- version: "v1",
379
- group: "batch",
380
- },
381
- /**
382
- * Represents a K8s Job resource.
383
- * Job represents the configuration of a single job.
384
- * @see {@link https://kubernetes.io/docs/concepts/workloads/controllers/job/}
385
- */
386
- V1Job: {
387
- kind: "Job",
388
- version: "v1",
389
- group: "batch",
390
- },
391
- /**
392
- * Represents a K8s CertificateSigningRequest resource.
393
- * CertificateSigningRequest represents a certificate signing request.
394
- * @see {@link https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/}
395
- */
396
- V1CertificateSigningRequest: {
397
- kind: "CertificateSigningRequest",
398
- version: "v1",
399
- group: "certificates.k8s.io",
400
- },
401
- /**
402
- * Represents a K8s EndpointSlice resource.
403
- * EndpointSlice represents a scalable set of network endpoints for a Kubernetes Service.
404
- * @see {@link https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/}
405
- */
406
- V1EndpointSlice: {
407
- kind: "EndpointSlice",
408
- version: "v1",
409
- group: "discovery.k8s.io",
410
- },
411
- /**
412
- * Represents a K8s IngressClass resource.
413
- * IngressClass represents the class of the Ingress, referenced by the Ingress spec.
414
- * @see {@link https://kubernetes.io/docs/concepts/services-networking/ingress/}
415
- */
416
- V1IngressClass: {
417
- kind: "IngressClass",
418
- version: "v1",
419
- group: "networking.k8s.io",
420
- },
421
- /**
422
- * Represents a K8s Ingress resource.
423
- * Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster.
424
- * @see {@link https://kubernetes.io/docs/concepts/services-networking/ingress/}
425
- */
426
- V1Ingress: {
427
- kind: "Ingress",
428
- version: "v1",
429
- group: "networking.k8s.io",
430
- },
431
- /**
432
- * Represents a K8s NetworkPolicy resource.
433
- * NetworkPolicy defines a set of rules for how pods communicate with each other.
434
- * @see {@link https://kubernetes.io/docs/concepts/services-networking/network-policies/}
435
- */
436
- V1NetworkPolicy: {
437
- kind: "NetworkPolicy",
438
- version: "v1",
439
- group: "networking.k8s.io",
440
- },
441
- /**
442
- * Represents a K8s RuntimeClass resource.
443
- * RuntimeClass is a cluster-scoped resource that surfaces container runtime properties to the control plane.
444
- * @see {@link https://kubernetes.io/docs/concepts/containers/runtime-class/}
445
- */
446
- V1RuntimeClass: {
447
- kind: "RuntimeClass",
448
- version: "v1",
449
- group: "node.k8s.io",
450
- },
451
- /**
452
- * Represents a K8s PodDisruptionBudget resource.
453
- * PodDisruptionBudget is an API object that limits the number of pods of a replicated application that are down simultaneously.
454
- * @see {@link https://kubernetes.io/docs/concepts/workloads/pods/disruptions/}
455
- */
456
- V1PodDisruptionBudget: {
457
- kind: "PodDisruptionBudget",
458
- version: "v1",
459
- group: "policy",
460
- },
461
- /**
462
- * Represents a K8s VolumeAttachment resource.
463
- * VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.
464
- * @see {@link https://kubernetes.io/docs/concepts/storage/storage-classes/}
465
- */
466
- V1VolumeAttachment: {
467
- kind: "VolumeAttachment",
468
- version: "v1",
469
- group: "storage.k8s.io",
470
- },
471
- /**
472
- * Represents a K8s CSIDriver resource.
473
- * CSIDriver captures information about a Container Storage Interface (CSI) volume driver.
474
- * @see {@link https://kubernetes.io/docs/concepts/storage/volumes/}
475
- */
476
- V1CSIDriver: {
477
- kind: "CSIDriver",
478
- version: "v1",
479
- group: "storage.k8s.io",
480
- },
481
- /**
482
- * Represents a K8s CSIStorageCapacity resource.
483
- * CSIStorageCapacity stores the reported storage capacity of a CSI node or storage class.
484
- * @see {@link https://kubernetes.io/docs/concepts/storage/csi/}
485
- */
486
- V1CSIStorageCapacity: {
487
- kind: "CSIStorageCapacity",
488
- version: "v1",
489
- group: "storage.k8s.io",
490
- },
491
- /**
492
- * Represents a K8s StorageClass resource.
493
- * StorageClass is a cluster-scoped resource that provides a way for administrators to describe the classes of storage they offer.
494
- * @see {@link https://kubernetes.io/docs/concepts/storage/storage-classes/}
495
- */
496
- V1StorageClass: {
497
- kind: "StorageClass",
498
- version: "v1",
499
- group: "storage.k8s.io",
500
- },
501
- };
502
- function modelToGroupVersionKind(key) {
503
- return gvkMap[key];
504
- }
505
-
506
- // SPDX-License-Identifier: Apache-2.0
507
- // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
508
- var Operation;
509
- (function (Operation) {
510
- Operation["CREATE"] = "CREATE";
511
- Operation["UPDATE"] = "UPDATE";
512
- Operation["DELETE"] = "DELETE";
513
- Operation["CONNECT"] = "CONNECT";
514
- })(Operation || (Operation = {}));
515
-
516
- // SPDX-License-Identifier: Apache-2.0
517
- /**
518
- * A capability is a unit of functionality that can be registered with the Pepr runtime.
519
- */
520
- class Capability {
521
- get bindings() {
522
- return this._bindings;
523
- }
524
- get name() {
525
- return this._name;
526
- }
527
- get description() {
528
- return this._description;
529
- }
530
- get namespaces() {
531
- return this._namespaces || [];
532
- }
533
- get mutateOrValidate() {
534
- return this._mutateOrValidate;
535
- }
536
- constructor(cfg) {
537
- // Currently everything is considered a mutation
538
- this._mutateOrValidate = types.HookPhase.mutate;
539
- this._bindings = [];
540
- /**
541
- * The When method is used to register a capability action to be executed when a Kubernetes resource is
542
- * processed by Pepr. The action will be executed if the resource matches the specified kind and any
543
- * filters that are applied.
544
- *
545
- * @param model if using a custom KubernetesObject not available in `a.*`, specify the GroupVersionKind
546
- * @returns
547
- */
548
- this.When = (model) => {
549
- const binding = {
550
- // If the kind is not specified, use the default KubernetesObject
551
- kind: modelToGroupVersionKind(model.name),
552
- filters: {
553
- name: "",
554
- namespaces: [],
555
- labels: {},
556
- annotations: {},
557
- },
558
- callback: () => null,
559
- };
560
- const prefix = `${this._name}: ${model.name}`;
561
- types.logger.info(`Binding created`, prefix);
562
- const Then = (cb) => {
563
- types.logger.info(`Binding action created`, prefix);
564
- types.logger.debug(cb.toString(), prefix);
565
- // Push the binding to the list of bindings for this capability as a new BindingAction
566
- // with the callback function to preserve
567
- this._bindings.push({
568
- ...binding,
569
- callback: cb,
570
- });
571
- // Now only allow adding actions to the same binding
572
- return { Then };
573
- };
574
- const ThenSet = (merge) => {
575
- // Add the new action to the binding
576
- Then(req => req.Merge(merge));
577
- return { Then };
578
- };
579
- function InNamespace(...namespaces) {
580
- types.logger.debug(`Add namespaces filter ${namespaces}`, prefix);
581
- binding.filters.namespaces.push(...namespaces);
582
- return { WithLabel, WithAnnotation, WithName, Then, ThenSet };
583
- }
584
- function WithName(name) {
585
- types.logger.debug(`Add name filter ${name}`, prefix);
586
- binding.filters.name = name;
587
- return { WithLabel, WithAnnotation, Then, ThenSet };
588
- }
589
- function WithLabel(key, value = "") {
590
- types.logger.debug(`Add label filter ${key}=${value}`, prefix);
591
- binding.filters.labels[key] = value;
592
- return { WithLabel, WithAnnotation, Then, ThenSet };
593
- }
594
- const WithAnnotation = (key, value = "") => {
595
- types.logger.debug(`Add annotation filter ${key}=${value}`, prefix);
596
- binding.filters.annotations[key] = value;
597
- return { WithLabel, WithAnnotation, Then, ThenSet };
598
- };
599
- const bindEvent = (event) => {
600
- binding.event = event;
601
- return {
602
- InNamespace,
603
- Then,
604
- ThenSet,
605
- WithAnnotation,
606
- WithLabel,
607
- WithName,
608
- };
609
- };
610
- return {
611
- IsCreatedOrUpdated: () => bindEvent(types.Event.CreateOrUpdate),
612
- IsCreated: () => bindEvent(types.Event.Create),
613
- IsUpdated: () => bindEvent(types.Event.Update),
614
- IsDeleted: () => bindEvent(types.Event.Delete),
615
- };
616
- };
617
- this._name = cfg.name;
618
- this._description = cfg.description;
619
- this._namespaces = cfg.namespaces;
620
- types.logger.info(`Capability ${this._name} registered`);
621
- types.logger.debug(cfg);
622
- }
623
- }
624
-
625
- // SPDX-License-Identifier: Apache-2.0
626
- /**
627
- * shouldSkipRequest determines if a request should be skipped based on the binding filters.
628
- *
629
- * @param binding the capability action binding
630
- * @param req the incoming request
631
- * @returns
632
- */
633
- function shouldSkipRequest(binding, req) {
634
- const { group, kind, version } = binding.kind;
635
- const { namespaces, labels, annotations } = binding.filters;
636
- const { metadata } = req.object;
637
- if (kind !== req.kind.kind) {
638
- return true;
639
- }
640
- if (group && group !== req.kind.group) {
641
- return true;
642
- }
643
- if (version && version !== req.kind.version) {
644
- return true;
645
- }
646
- if (namespaces.length && !namespaces.includes(req.namespace || "")) {
647
- types.logger.debug("Namespace does not match");
648
- return true;
649
- }
650
- for (const [key, value] of Object.entries(labels)) {
651
- if (metadata?.labels?.[key] !== value) {
652
- types.logger.debug(`${metadata?.labels?.[key]} does not match ${value}`);
653
- return true;
654
- }
655
- }
656
- for (const [key, value] of Object.entries(annotations)) {
657
- if (metadata?.annotations?.[key] !== value) {
658
- types.logger.debug(`${metadata?.annotations?.[key]} does not match ${value}`);
659
- return true;
660
- }
661
- }
662
- return false;
663
- }
664
-
665
- // SPDX-License-Identifier: Apache-2.0
666
- /**
667
- * The RequestWrapper class provides methods to modify Kubernetes objects in the context
668
- * of a mutating webhook request.
669
- */
670
- class RequestWrapper {
671
- get PermitSideEffects() {
672
- return !this._input.dryRun;
673
- }
674
- /**
675
- * Indicates whether the request is a dry run.
676
- * @returns true if the request is a dry run, false otherwise.
677
- */
678
- get IsDryRun() {
679
- return this._input.dryRun;
680
- }
681
- /**
682
- * Provides access to the old resource in the request if available.
683
- * @returns The old Kubernetes resource object or null if not available.
684
- */
685
- get OldResource() {
686
- return this._input.oldObject;
687
- }
688
- /**
689
- * Provides access to the request object.
690
- * @returns The request object containing the Kubernetes resource.
691
- */
692
- get Request() {
693
- return this._input;
694
- }
695
- /**
696
- * Creates a new instance of the Action class.
697
- * @param input - The request object containing the Kubernetes resource to modify.
698
- */
699
- constructor(input) {
700
- // Deep clone the object to prevent mutation of the original object
701
- this.Raw = R__namespace.clone(input.object);
702
- // Store the input
703
- this._input = input;
704
- }
705
- /**
706
- * Deep merges the provided object with the current resource.
707
- *
708
- * @param obj - The object to merge with the current resource.
709
- */
710
- Merge(obj) {
711
- this.Raw = R__namespace.mergeDeepRight(this.Raw, obj);
712
- }
713
- /**
714
- * Updates a label on the Kubernetes resource.
715
- * @param key - The key of the label to update.
716
- * @param value - The value of the label.
717
- * @returns The current Action instance for method chaining.
718
- */
719
- SetLabel(key, value) {
720
- const ref = this.Raw;
721
- ref.metadata = ref.metadata ?? {};
722
- ref.metadata.labels = ref.metadata.labels ?? {};
723
- ref.metadata.labels[key] = value;
724
- return this;
725
- }
726
- /**
727
- * Updates an annotation on the Kubernetes resource.
728
- * @param key - The key of the annotation to update.
729
- * @param value - The value of the annotation.
730
- * @returns The current Action instance for method chaining.
731
- */
732
- SetAnnotation(key, value) {
733
- const ref = this.Raw;
734
- ref.metadata = ref.metadata ?? {};
735
- ref.metadata.annotations = ref.metadata.annotations ?? {};
736
- ref.metadata.annotations[key] = value;
737
- return this;
738
- }
739
- /**
740
- * Removes a label from the Kubernetes resource.
741
- * @param key - The key of the label to remove.
742
- * @returns The current Action instance for method chaining.
743
- */
744
- RemoveLabel(key) {
745
- if (this.Raw.metadata?.labels?.[key]) {
746
- delete this.Raw.metadata.labels[key];
747
- }
748
- return this;
749
- }
750
- /**
751
- * Removes an annotation from the Kubernetes resource.
752
- * @param key - The key of the annotation to remove.
753
- * @returns The current Action instance for method chaining.
754
- */
755
- RemoveAnnotation(key) {
756
- if (this.Raw.metadata?.annotations?.[key]) {
757
- delete this.Raw.metadata.annotations[key];
758
- }
759
- return this;
760
- }
761
- /**
762
- * Check if a label exists on the Kubernetes resource.
763
- *
764
- * @param key the label key to check
765
- * @returns
766
- */
767
- HasLabel(key) {
768
- return this.Raw?.metadata?.labels?.[key] !== undefined;
769
- }
770
- /**
771
- * Check if an annotation exists on the Kubernetes resource.
772
- *
773
- * @param key the annotation key to check
774
- * @returns
775
- */
776
- HasAnnotation(key) {
777
- return this.Raw?.metadata?.annotations?.[key] !== undefined;
778
- }
779
- }
780
-
781
- // SPDX-License-Identifier: Apache-2.0
782
- function processor(config, capabilities, req) {
783
- const wrapped = new RequestWrapper(req);
784
- const response = {
785
- uid: req.uid,
786
- patchType: "JSONPatch",
787
- warnings: [],
788
- allowed: false,
789
- };
790
- types.logger.info(`Processing '${req.uid}' for '${req.kind.kind}' '${req.name}'`);
791
- for (const { name, bindings } of capabilities) {
792
- const prefix = `${req.uid} ${req.name}: ${name}`;
793
- types.logger.info(`Processing capability ${name}`, prefix);
794
- for (const action of bindings) {
795
- // Continue to the next action without doing anything if this one should be skipped
796
- if (shouldSkipRequest(action, req)) {
797
- continue;
798
- }
799
- types.logger.info(`Processing matched action ${action.kind.kind}`, prefix);
800
- // Add annotations to the request to indicate that the capability started processing
801
- // this will allow tracking of failed mutations that were permitted to continue
802
- const { metadata } = wrapped.Raw;
803
- const identifier = `pepr.dev/${config.uuid}/${name}`;
804
- metadata.annotations = metadata.annotations || {};
805
- metadata.annotations[identifier] = "started";
806
- try {
807
- // Run the action
808
- action.callback(wrapped);
809
- // Add annotations to the request to indicate that the capability succeeded
810
- metadata.annotations[identifier] = "succeeded";
811
- }
812
- catch (e) {
813
- response.warnings.push(`Action failed: ${e}`);
814
- // If errors are not allowed, note the failure in the Reponse
815
- if (config.onError) {
816
- types.logger.error(`Action failed: ${e}`, prefix);
817
- response.result = "Pepr module configured to reject on error";
818
- return response;
819
- }
820
- else {
821
- types.logger.warn(`Action failed: ${e}`, prefix);
822
- metadata.annotations[identifier] = "warning";
823
- }
824
- }
825
- }
826
- }
827
- // If we've made it this far, the request is allowed
828
- response.allowed = true;
829
- // Compare the original request to the modified request to get the patches
830
- const patches = fastJsonPatch.compare(req.object, wrapped.Raw);
831
- // Only add the patch if there are patches to apply
832
- if (patches.length > 0) {
833
- response.patch = JSON.stringify(patches);
834
- }
835
- // Remove the warnings array if it's empty
836
- if (response.warnings.length < 1) {
837
- delete response.warnings;
838
- }
839
- types.logger.debug(patches);
840
- return response;
841
- }
842
-
843
- // SPDX-License-Identifier: Apache-2.0
844
- // Load SSL certificate and key
845
- const options = {
846
- key: fs.readFileSync(process.env.SSL_KEY_PATH || "/etc/certs/tls.key"),
847
- cert: fs.readFileSync(process.env.SSL_CERT_PATH || "/etc/certs/tls.crt"),
848
- };
849
- class Controller {
850
- constructor(config, capabilities) {
851
- this.config = config;
852
- this.capabilities = capabilities;
853
- this.app = express();
854
- /** Start the webhook server */
855
- this.startServer = (port) => {
856
- // Create HTTPS server
857
- https.createServer(options, this.app).listen(port, () => {
858
- console.log(`Server listening on port ${port}`);
859
- });
860
- };
861
- this.logger = (req, res, next) => {
862
- const startTime = Date.now();
863
- res.on("finish", () => {
864
- const now = new Date().toISOString();
865
- const elapsedTime = Date.now() - startTime;
866
- const message = `[${now}] ${req.method} ${req.originalUrl} - ${res.statusCode} - ${elapsedTime} ms\n`;
867
- res.statusCode >= 400 ? console.error(message) : console.info(message);
868
- });
869
- next();
870
- };
871
- this.healthz = (req, res) => {
872
- try {
873
- res.send("OK");
874
- }
875
- catch (err) {
876
- console.error(err);
877
- res.status(500).send("Internal Server Error");
878
- }
879
- };
880
- this.mutate = (req, res) => {
881
- try {
882
- const name = req.body?.request?.name || "";
883
- const namespace = req.body?.request?.namespace || "";
884
- const gvk = req.body?.request?.kind || { group: "", version: "", kind: "" };
885
- console.log(`Mutate request: ${gvk.group}/${gvk.version}/${gvk.kind}`);
886
- name && console.log(` ${namespace}/${name}\n`);
887
- // @todo: make this actually do something
888
- const response = processor(this.config, this.capabilities, req.body.request);
889
- console.debug(response);
890
- // Send a no prob bob response
891
- res.send({
892
- apiVersion: "admission.k8s.io/v1",
893
- kind: "AdmissionReview",
894
- response: {
895
- uid: req.body.request.uid,
896
- allowed: true,
897
- },
898
- });
899
- }
900
- catch (err) {
901
- console.error(err);
902
- res.status(500).send("Internal Server Error");
903
- }
904
- };
905
- // Middleware for logging requests
906
- this.app.use(this.logger);
907
- // Middleware for parsing JSON
908
- this.app.use(express.json());
909
- // Health check endpoint
910
- this.app.get("/healthz", this.healthz);
911
- // Mutate endpoint
912
- this.app.post("/mutate", this.mutate);
913
- }
914
- }
915
-
916
- // SPDX-License-Identifier: Apache-2.0
917
- const alwaysIgnore = {
918
- namespaces: ["kube-system", "pepr-system"],
919
- labels: [{ "pepr.dev": "ignore" }],
920
- };
921
- class PeprModule {
922
- /**
923
- * Create a new Pepr runtime
924
- *
925
- * @param config The configuration for the Pepr runtime
926
- */
927
- constructor({ description, pepr }, capabilities = [], deferStart = false) {
928
- const config = R.mergeDeepWith(R.concat, pepr, alwaysIgnore);
929
- config.description = description;
930
- this._controller = new Controller(config, capabilities);
931
- if (!deferStart) {
932
- this.start();
933
- }
934
- }
935
- /**
936
- * Start the Pepr runtime manually.
937
- * Normally this is called automatically when the Pepr module is instantiated, but can be called manually if `deferStart` is set to `true` in the constructor.
938
- *
939
- * @param port
940
- */
941
- start(port = 3000) {
942
- this._controller.startServer(port);
943
- }
944
- }
945
-
946
- exports.Log = types.logger;
947
- exports.Capability = Capability;
948
- exports.PeprModule = PeprModule;
949
- exports.a = upstream;