pepr 0.13.4 → 0.14.0

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 (105) hide show
  1. package/README.md +23 -4
  2. package/dist/cli.js +375 -204
  3. package/dist/controller.js +1 -1
  4. package/dist/lib/assets/deploy.d.ts.map +1 -1
  5. package/dist/lib/assets/destroy.d.ts +2 -0
  6. package/dist/lib/assets/destroy.d.ts.map +1 -0
  7. package/dist/lib/assets/index.d.ts +6 -5
  8. package/dist/lib/assets/index.d.ts.map +1 -1
  9. package/dist/lib/assets/networking.d.ts +6 -5
  10. package/dist/lib/assets/networking.d.ts.map +1 -1
  11. package/dist/lib/assets/pods.d.ts +84 -4
  12. package/dist/lib/assets/pods.d.ts.map +1 -1
  13. package/dist/lib/assets/rbac.d.ts +6 -4
  14. package/dist/lib/assets/rbac.d.ts.map +1 -1
  15. package/dist/lib/assets/store.d.ts +7 -0
  16. package/dist/lib/assets/store.d.ts.map +1 -0
  17. package/dist/lib/assets/webhooks.d.ts +2 -2
  18. package/dist/lib/assets/webhooks.d.ts.map +1 -1
  19. package/dist/lib/assets/yaml.d.ts.map +1 -1
  20. package/dist/lib/capability.d.ts +21 -4
  21. package/dist/lib/capability.d.ts.map +1 -1
  22. package/dist/lib/controller/index.d.ts +10 -0
  23. package/dist/lib/controller/index.d.ts.map +1 -0
  24. package/dist/lib/controller/store.d.ts +7 -0
  25. package/dist/lib/controller/store.d.ts.map +1 -0
  26. package/dist/lib/filter.d.ts +2 -2
  27. package/dist/lib/filter.d.ts.map +1 -1
  28. package/dist/lib/{k8s/types.d.ts → k8s.d.ts} +14 -25
  29. package/dist/lib/k8s.d.ts.map +1 -0
  30. package/dist/lib/metrics.d.ts +12 -12
  31. package/dist/lib/metrics.d.ts.map +1 -1
  32. package/dist/lib/module.d.ts +25 -4
  33. package/dist/lib/module.d.ts.map +1 -1
  34. package/dist/lib/mutate-processor.d.ts +3 -3
  35. package/dist/lib/mutate-processor.d.ts.map +1 -1
  36. package/dist/lib/mutate-request.d.ts +11 -10
  37. package/dist/lib/mutate-request.d.ts.map +1 -1
  38. package/dist/lib/storage.d.ts +56 -0
  39. package/dist/lib/storage.d.ts.map +1 -0
  40. package/dist/lib/tls.d.ts.map +1 -0
  41. package/dist/lib/types.d.ts +28 -48
  42. package/dist/lib/types.d.ts.map +1 -1
  43. package/dist/lib/validate-processor.d.ts +2 -2
  44. package/dist/lib/validate-processor.d.ts.map +1 -1
  45. package/dist/lib/validate-request.d.ts +9 -8
  46. package/dist/lib/validate-request.d.ts.map +1 -1
  47. package/dist/lib/watch-processor.d.ts +3 -0
  48. package/dist/lib/watch-processor.d.ts.map +1 -0
  49. package/dist/lib.d.ts +3 -7
  50. package/dist/lib.d.ts.map +1 -1
  51. package/dist/lib.js +484 -807
  52. package/dist/lib.js.map +4 -4
  53. package/package.json +13 -17
  54. package/src/lib/assets/deploy.ts +69 -127
  55. package/src/lib/assets/destroy.ts +33 -0
  56. package/src/lib/assets/index.ts +8 -14
  57. package/src/lib/assets/networking.ts +28 -5
  58. package/src/lib/assets/pods.ts +130 -11
  59. package/src/lib/assets/rbac.ts +42 -4
  60. package/src/lib/assets/store.ts +49 -0
  61. package/src/lib/assets/webhooks.ts +2 -2
  62. package/src/lib/assets/yaml.ts +13 -3
  63. package/src/lib/capability.ts +69 -14
  64. package/src/lib/{controller.ts → controller/index.ts} +25 -23
  65. package/src/lib/controller/store.ts +197 -0
  66. package/src/lib/filter.ts +2 -2
  67. package/src/lib/{k8s/types.ts → k8s.ts} +15 -26
  68. package/src/lib/metrics.ts +22 -38
  69. package/src/lib/module.ts +47 -10
  70. package/src/lib/mutate-processor.ts +6 -6
  71. package/src/lib/mutate-request.ts +18 -26
  72. package/src/lib/storage.ts +128 -0
  73. package/src/lib/types.ts +30 -53
  74. package/src/lib/validate-processor.ts +5 -4
  75. package/src/lib/validate-request.ts +15 -19
  76. package/src/lib/watch-processor.ts +55 -0
  77. package/src/lib.ts +4 -8
  78. package/src/templates/capabilities/hello-pepr.ts +54 -5
  79. package/src/templates/package.json +1 -0
  80. package/dist/lib/controller.d.ts +0 -10
  81. package/dist/lib/controller.d.ts.map +0 -1
  82. package/dist/lib/fetch.d.ts +0 -23
  83. package/dist/lib/fetch.d.ts.map +0 -1
  84. package/dist/lib/k8s/index.d.ts +0 -7
  85. package/dist/lib/k8s/index.d.ts.map +0 -1
  86. package/dist/lib/k8s/kinds.d.ts +0 -12
  87. package/dist/lib/k8s/kinds.d.ts.map +0 -1
  88. package/dist/lib/k8s/tls.d.ts.map +0 -1
  89. package/dist/lib/k8s/types.d.ts.map +0 -1
  90. package/dist/lib/k8s/upstream.d.ts +0 -4
  91. package/dist/lib/k8s/upstream.d.ts.map +0 -1
  92. package/jest.config.json +0 -4
  93. package/journey/before.ts +0 -21
  94. package/journey/k8s.ts +0 -100
  95. package/journey/pepr-build.ts +0 -69
  96. package/journey/pepr-deploy.ts +0 -174
  97. package/journey/pepr-dev.ts +0 -155
  98. package/journey/pepr-format.ts +0 -13
  99. package/journey/pepr-init.ts +0 -12
  100. package/src/lib/fetch.ts +0 -76
  101. package/src/lib/k8s/index.ts +0 -14
  102. package/src/lib/k8s/kinds.ts +0 -531
  103. package/src/lib/k8s/upstream.ts +0 -53
  104. /package/dist/lib/{k8s/tls.d.ts → tls.d.ts} +0 -0
  105. /package/src/lib/{k8s/tls.ts → tls.ts} +0 -0
@@ -3,9 +3,11 @@
3
3
 
4
4
  /* eslint-disable class-methods-use-this */
5
5
 
6
+ import { KubernetesObject } from "kubernetes-fluent-client";
7
+
6
8
  import { clone } from "ramda";
7
- import { KubernetesObject, Operation, Request } from "./k8s/types";
8
- import { ValidateResponse } from "./types";
9
+ import { Operation, AdmissionRequest } from "./k8s";
10
+ import { ValidateActionResponse } from "./types";
9
11
 
10
12
  /**
11
13
  * The RequestWrapper class provides methods to modify Kubernetes objects in the context
@@ -14,7 +16,7 @@ import { ValidateResponse } from "./types";
14
16
  export class PeprValidateRequest<T extends KubernetesObject> {
15
17
  Raw: T;
16
18
 
17
- #input: Request<T>;
19
+ #input: AdmissionRequest<T>;
18
20
 
19
21
  /**
20
22
  * Provides access to the old resource in the request if available.
@@ -36,15 +38,9 @@ export class PeprValidateRequest<T extends KubernetesObject> {
36
38
  * Creates a new instance of the Action class.
37
39
  * @param input - The request object containing the Kubernetes resource to modify.
38
40
  */
39
- constructor(input: Request<T>) {
41
+ constructor(input: AdmissionRequest<T>) {
40
42
  this.#input = input;
41
43
 
42
- // Bind public methods to this instance
43
- this.HasLabel = this.HasLabel.bind(this);
44
- this.HasAnnotation = this.HasAnnotation.bind(this);
45
- this.Approve = this.Approve.bind(this);
46
- this.Deny = this.Deny.bind(this);
47
-
48
44
  // If this is a DELETE operation, use the oldObject instead
49
45
  if (input.operation.toUpperCase() === Operation.DELETE) {
50
46
  this.Raw = clone(input.oldObject as T);
@@ -54,7 +50,7 @@ export class PeprValidateRequest<T extends KubernetesObject> {
54
50
  }
55
51
 
56
52
  if (!this.Raw) {
57
- throw new Error("unable to load the request object into PeprRequest.RawP");
53
+ throw new Error("unable to load the request object into PeprRequest.Raw");
58
54
  }
59
55
  }
60
56
 
@@ -64,9 +60,9 @@ export class PeprValidateRequest<T extends KubernetesObject> {
64
60
  * @param key the label key to check
65
61
  * @returns
66
62
  */
67
- HasLabel(key: string) {
63
+ HasLabel = (key: string) => {
68
64
  return this.Raw.metadata?.labels?.[key] !== undefined;
69
- }
65
+ };
70
66
 
71
67
  /**
72
68
  * Check if an annotation exists on the Kubernetes resource.
@@ -74,20 +70,20 @@ export class PeprValidateRequest<T extends KubernetesObject> {
74
70
  * @param key the annotation key to check
75
71
  * @returns
76
72
  */
77
- HasAnnotation(key: string) {
73
+ HasAnnotation = (key: string) => {
78
74
  return this.Raw.metadata?.annotations?.[key] !== undefined;
79
- }
75
+ };
80
76
 
81
77
  /**
82
78
  * Create a validation response that allows the request.
83
79
  *
84
80
  * @returns The validation response.
85
81
  */
86
- Approve(): ValidateResponse {
82
+ Approve = (): ValidateActionResponse => {
87
83
  return {
88
84
  allowed: true,
89
85
  };
90
- }
86
+ };
91
87
 
92
88
  /**
93
89
  * Create a validation response that denies the request.
@@ -96,11 +92,11 @@ export class PeprValidateRequest<T extends KubernetesObject> {
96
92
  * @param statusCode Optional status code to return to the user.
97
93
  * @returns The validation response.
98
94
  */
99
- Deny(statusMessage?: string, statusCode?: number): ValidateResponse {
95
+ Deny = (statusMessage?: string, statusCode?: number): ValidateActionResponse => {
100
96
  return {
101
97
  allowed: false,
102
98
  statusCode,
103
99
  statusMessage,
104
100
  };
105
- }
101
+ };
106
102
  }
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+
4
+ import { K8s } from "kubernetes-fluent-client";
5
+ import { WatchPhase } from "kubernetes-fluent-client/dist/fluent/types";
6
+
7
+ import { WatchCfg } from "kubernetes-fluent-client/dist/fluent/watch";
8
+ import { Capability } from "./capability";
9
+ import Log from "./logger";
10
+ import { Binding, Event } from "./types";
11
+
12
+ export function setupWatch(capabilities: Capability[]) {
13
+ capabilities
14
+ .flatMap(c => c.bindings)
15
+ .filter(binding => binding.isWatch)
16
+ .forEach(runBinding);
17
+ }
18
+
19
+ async function runBinding(binding: Binding) {
20
+ // Map the event to the watch phase
21
+ const eventToPhaseMap = {
22
+ [Event.Create]: [WatchPhase.Added],
23
+ [Event.Update]: [WatchPhase.Modified],
24
+ [Event.CreateOrUpdate]: [WatchPhase.Added, WatchPhase.Modified],
25
+ [Event.Delete]: [WatchPhase.Deleted],
26
+ [Event.Any]: [WatchPhase.Added, WatchPhase.Modified, WatchPhase.Deleted],
27
+ };
28
+
29
+ // Get the phases to match, default to any
30
+ const phaseMatch: WatchPhase[] = eventToPhaseMap[binding.event] || eventToPhaseMap[Event.Any];
31
+
32
+ const watchCfg: WatchCfg = {
33
+ retryMax: 3,
34
+ retryDelaySec: 5,
35
+ retryFail(e) {
36
+ // If failure continues, log and exit
37
+ Log.error(e, "Watch failed after 3 attempts, giving up");
38
+ process.exit(1);
39
+ },
40
+ };
41
+
42
+ // Watch the resource
43
+ await K8s(binding.model, binding.filters).Watch((obj, type) => {
44
+ // If the type matches the phase, call the watch callback
45
+ if (phaseMatch.includes(type)) {
46
+ try {
47
+ // This may be a promise, but we don't need to wait for it
48
+ void binding.watchCallback?.(obj, type);
49
+ } catch (e) {
50
+ // Errors in the watch callback should not crash the controller
51
+ Log.error(e, "Error executing watch callback");
52
+ }
53
+ }
54
+ }, watchCfg);
55
+ }
package/src/lib.ts CHANGED
@@ -1,9 +1,7 @@
1
- import * as k8s from "@kubernetes/client-node";
2
- import { StatusCodes as fetchStatus } from "http-status-codes";
1
+ import { K8s, RegisterKind, fetch, kind, kind as a, fetchStatus } from "kubernetes-fluent-client";
3
2
  import * as R from "ramda";
3
+
4
4
  import { Capability } from "./lib/capability";
5
- import { fetch, fetchRaw } from "./lib/fetch";
6
- import { RegisterKind, a } from "./lib/k8s/index";
7
5
  import Log from "./lib/logger";
8
6
  import { PeprModule } from "./lib/module";
9
7
  import { PeprMutateRequest } from "./lib/mutate-request";
@@ -11,26 +9,24 @@ import { PeprValidateRequest } from "./lib/validate-request";
11
9
  import * as PeprUtils from "./lib/utils";
12
10
 
13
11
  // Import type information for external packages
14
- import type * as K8sTypes from "@kubernetes/client-node";
15
12
  import type * as RTypes from "ramda";
16
13
 
17
14
  export {
18
15
  a,
16
+ kind,
19
17
  /** PeprModule is used to setup a complete Pepr Module: `new PeprModule(cfg, {...capabilities})` */
20
18
  PeprModule,
21
19
  PeprMutateRequest,
22
20
  PeprValidateRequest,
23
21
  PeprUtils,
24
22
  RegisterKind,
23
+ K8s,
25
24
  Capability,
26
25
  Log,
27
26
  R,
28
27
  fetch,
29
- fetchRaw,
30
28
  fetchStatus,
31
- k8s,
32
29
 
33
30
  // Export the imported type information for external packages
34
31
  RTypes,
35
- K8sTypes,
36
32
  };
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  Capability,
3
+ K8s,
3
4
  Log,
4
5
  PeprMutateRequest,
5
6
  RegisterKind,
6
7
  a,
7
8
  fetch,
8
9
  fetchStatus,
10
+ kind,
9
11
  } from "pepr";
10
12
 
11
13
  /**
@@ -19,8 +21,8 @@ export const HelloPepr = new Capability({
19
21
  namespaces: ["pepr-demo", "pepr-demo-2"],
20
22
  });
21
23
 
22
- // Use the 'When' function to create a new Action
23
- const { When } = HelloPepr;
24
+ // Use the 'When' function to create a new action, use 'Store' to persist data
25
+ const { When, Store } = HelloPepr;
24
26
 
25
27
  /**
26
28
  * ---------------------------------------------------------------------------------------------------
@@ -35,6 +37,36 @@ When(a.Namespace)
35
37
  .IsCreated()
36
38
  .Mutate(ns => ns.RemoveLabel("remove-me"));
37
39
 
40
+ /**
41
+ * ---------------------------------------------------------------------------------------------------
42
+ * Watch Action with K8s SSA (Namespace) *
43
+ * ---------------------------------------------------------------------------------------------------
44
+ *
45
+ * This action watches for the `pepr-demo-2` namespace to be created, then creates a ConfigMap with
46
+ * the name `pepr-ssa-demo` and adds the namespace UID to the ConfigMap data. Because Pepr uses
47
+ * server-side apply for this operation, the ConfigMap will be created or updated if it already exists.
48
+ */
49
+ When(a.Namespace)
50
+ .IsCreated()
51
+ .WithName("pepr-demo-2")
52
+ .Watch(async ns => {
53
+ Log.info("Namespace pepr-demo-2 was created.");
54
+
55
+ // You can share data between actions using the Store, including between different types of actions
56
+ Store.setItem("watch-data", "This data was stored by a Watch Action.");
57
+
58
+ // Apply the ConfigMap using K8s server-side apply
59
+ await K8s(kind.ConfigMap).Apply({
60
+ metadata: {
61
+ name: "pepr-ssa-demo",
62
+ namespace: "pepr-demo-2",
63
+ },
64
+ data: {
65
+ "ns-uid": ns.metadata.uid,
66
+ },
67
+ });
68
+ });
69
+
38
70
  /**
39
71
  * ---------------------------------------------------------------------------------------------------
40
72
  * Mutate Action (CM Example 1) *
@@ -54,6 +86,12 @@ When(a.ConfigMap)
54
86
  request
55
87
  .SetLabel("pepr", "was-here")
56
88
  .SetAnnotation("pepr.dev", "annotations-work-too");
89
+
90
+ // Use the Store to persist data between requests and Pepr controller pods
91
+ Store.setItem("example-1", "was-here");
92
+
93
+ // This data is written asynchronously and can be read back via `Store.getItem()` or `Store.subscribe()`
94
+ Store.setItem("example-1-data", JSON.stringify(request.Raw.data));
57
95
  });
58
96
 
59
97
  /**
@@ -61,10 +99,10 @@ When(a.ConfigMap)
61
99
  * Mutate & Validate Actions (CM Example 2) *
62
100
  * ---------------------------------------------------------------------------------------------------
63
101
  *
64
- * This combines 2 different types of actions: 'Mutate', and 'Validate'. The order
102
+ * This combines 3 different types of actions: 'Mutate', 'Validate', and 'Watch'. The order
65
103
  * of the actions is required, but each action is optional. In this example, when a ConfigMap is created
66
- * with the name `example-2`, then add a label and annotation and finally validate that the ConfigMap has the label
67
- * `pepr`.
104
+ * with the name `example-2`, then add a label and annotation, validate that the ConfigMap has the label
105
+ * `pepr`, and log the request.
68
106
  */
69
107
  When(a.ConfigMap)
70
108
  .IsCreated()
@@ -94,6 +132,10 @@ When(a.ConfigMap)
94
132
 
95
133
  // Otherwise, deny the request with an error message (optional)
96
134
  return request.Deny("ConfigMap must have label 'pepr'");
135
+ })
136
+ .Watch((cm, phase) => {
137
+ // This Watch Action will watch the ConfigMap after it has been persisted to the cluster
138
+ Log.info(cm, `ConfigMap was ${phase} with the name example-2`);
97
139
  });
98
140
 
99
141
  /**
@@ -370,3 +412,10 @@ When(UnicornKind)
370
412
  },
371
413
  });
372
414
  });
415
+
416
+ /**
417
+ * A callback function that is called once the Pepr Store is fully loaded.
418
+ */
419
+ Store.onReady(data => {
420
+ Log.info(data, "Pepr Store Ready");
421
+ });
@@ -6,6 +6,7 @@
6
6
  "uuid": "20e17cf6-a2e4-46b2-b626-75d88d96c88b",
7
7
  "description": "Development module for pepr",
8
8
  "onError": "ignore",
9
+ "logLevel": "debug",
9
10
  "alwaysIgnore": {
10
11
  "namespaces": [],
11
12
  "labels": []
@@ -1,10 +0,0 @@
1
- import { Capability } from "./capability";
2
- import { MutateResponse, Request } from "./k8s/types";
3
- import { ModuleConfig } from "./types";
4
- export declare class Controller {
5
- #private;
6
- constructor(config: ModuleConfig, capabilities: Capability[], beforeHook?: (req: Request) => void, afterHook?: (res: MutateResponse) => void);
7
- /** Start the webhook server */
8
- startServer(port: number): void;
9
- }
10
- //# sourceMappingURL=controller.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/lib/controller.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,OAAO,EAAoB,MAAM,aAAa,CAAC;AAIxE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,qBAAa,UAAU;;gBAoBnB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,UAAU,EAAE,EAC1B,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,EACnC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI;IA4B3C,+BAA+B;IAC/B,WAAW,CAAC,IAAI,EAAE,MAAM;CAyNzB"}
@@ -1,23 +0,0 @@
1
- import f, { RequestInfo, RequestInit } from "node-fetch";
2
- export declare const fetchRaw: typeof f;
3
- export type FetchResponse<T> = {
4
- data: T;
5
- ok: boolean;
6
- status: number;
7
- statusText: string;
8
- };
9
- /**
10
- * Perform an async HTTP call and return the parsed JSON response, optionally
11
- * as a specific type.
12
- *
13
- * @example
14
- * ```ts
15
- * fetch<string[]>("https://example.com/api/foo");
16
- * ```
17
- *
18
- * @param url The URL or Request object to fetch
19
- * @param init Additional options for the request
20
- * @returns
21
- */
22
- export declare function fetch<T>(url: URL | RequestInfo, init?: RequestInit): Promise<FetchResponse<T>>;
23
- //# sourceMappingURL=fetch.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/lib/fetch.ts"],"names":[],"mappings":"AAIA,OAAO,CAAC,EAAE,EAAc,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGrE,eAAO,MAAM,QAAQ,UAAI,CAAC;AAE1B,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B,IAAI,EAAE,CAAC,CAAC;IACR,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAsB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,WAAW,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CA8CpG"}
@@ -1,7 +0,0 @@
1
- import * as kind from "./upstream";
2
- /** a is a collection of K8s types to be used within a action: `When(a.Configmap)` */
3
- export { kind as a };
4
- export { modelToGroupVersionKind, gvkMap, RegisterKind } from "./kinds";
5
- export declare const isWatchMode: boolean;
6
- export * from "./types";
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/k8s/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,qFAAqF;AACrF,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;AAErB,OAAO,EAAE,uBAAuB,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGxE,eAAO,MAAM,WAAW,SAAyC,CAAC;AAElE,cAAc,SAAS,CAAC"}
@@ -1,12 +0,0 @@
1
- import { GenericClass } from "../types";
2
- import { GroupVersionKind } from "./types";
3
- export declare const gvkMap: Record<string, GroupVersionKind>;
4
- export declare function modelToGroupVersionKind(key: string): GroupVersionKind;
5
- /**
6
- * Registers a new model and GroupVersionKind with Pepr for use with `When(a.<Kind>)`
7
- *
8
- * @param model Used to match the GroupVersionKind and define the type-data for the request
9
- * @param groupVersionKind Contains the match parameters to determine the request should be handled
10
- */
11
- export declare const RegisterKind: (model: GenericClass, groupVersionKind: GroupVersionKind) => void;
12
- //# sourceMappingURL=kinds.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../../../src/lib/k8s/kinds.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAsfnD,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAErE;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,UAAW,YAAY,oBAAoB,gBAAgB,SAUnF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tls.d.ts","sourceRoot":"","sources":["../../../src/lib/k8s/tls.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE;QACH,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyC3C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/k8s/types.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- /** a is a collection of K8s types to be used within an action: `When(a.Configmap)` */
2
- export { V1APIService as APIService, V1CertificateSigningRequest as CertificateSigningRequest, V1ClusterRole as ClusterRole, V1ClusterRoleBinding as ClusterRoleBinding, V1ConfigMap as ConfigMap, V1ControllerRevision as ControllerRevision, V1CronJob as CronJob, V1CSIDriver as CSIDriver, V1CSIStorageCapacity as CSIStorageCapacity, V1CustomResourceDefinition as CustomResourceDefinition, V1DaemonSet as DaemonSet, V1Deployment as Deployment, V1EndpointSlice as EndpointSlice, V1HorizontalPodAutoscaler as HorizontalPodAutoscaler, V1Ingress as Ingress, V1IngressClass as IngressClass, V1Job as Job, V1LimitRange as LimitRange, V1LocalSubjectAccessReview as LocalSubjectAccessReview, V1MutatingWebhookConfiguration as MutatingWebhookConfiguration, V1Namespace as Namespace, V1NetworkPolicy as NetworkPolicy, V1Node as Node, V1PersistentVolume as PersistentVolume, V1PersistentVolumeClaim as PersistentVolumeClaim, V1Pod as Pod, V1PodDisruptionBudget as PodDisruptionBudget, V1PodTemplate as PodTemplate, V1ReplicaSet as ReplicaSet, V1ReplicationController as ReplicationController, V1ResourceQuota as ResourceQuota, V1Role as Role, V1RoleBinding as RoleBinding, V1RuntimeClass as RuntimeClass, V1Secret as Secret, V1SelfSubjectAccessReview as SelfSubjectAccessReview, V1SelfSubjectRulesReview as SelfSubjectRulesReview, V1Service as Service, V1ServiceAccount as ServiceAccount, V1StatefulSet as StatefulSet, V1StorageClass as StorageClass, V1SubjectAccessReview as SubjectAccessReview, V1TokenReview as TokenReview, V1ValidatingWebhookConfiguration as ValidatingWebhookConfiguration, V1VolumeAttachment as VolumeAttachment, } from "@kubernetes/client-node";
3
- export { GenericKind } from "./types";
4
- //# sourceMappingURL=upstream.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"upstream.d.ts","sourceRoot":"","sources":["../../../src/lib/k8s/upstream.ts"],"names":[],"mappings":"AAGA,sFAAsF;AACtF,OAAO,EACL,YAAY,IAAI,UAAU,EAC1B,2BAA2B,IAAI,yBAAyB,EACxD,aAAa,IAAI,WAAW,EAC5B,oBAAoB,IAAI,kBAAkB,EAC1C,WAAW,IAAI,SAAS,EACxB,oBAAoB,IAAI,kBAAkB,EAC1C,SAAS,IAAI,OAAO,EACpB,WAAW,IAAI,SAAS,EACxB,oBAAoB,IAAI,kBAAkB,EAC1C,0BAA0B,IAAI,wBAAwB,EACtD,WAAW,IAAI,SAAS,EACxB,YAAY,IAAI,UAAU,EAC1B,eAAe,IAAI,aAAa,EAChC,yBAAyB,IAAI,uBAAuB,EACpD,SAAS,IAAI,OAAO,EACpB,cAAc,IAAI,YAAY,EAC9B,KAAK,IAAI,GAAG,EACZ,YAAY,IAAI,UAAU,EAC1B,0BAA0B,IAAI,wBAAwB,EACtD,8BAA8B,IAAI,4BAA4B,EAC9D,WAAW,IAAI,SAAS,EACxB,eAAe,IAAI,aAAa,EAChC,MAAM,IAAI,IAAI,EACd,kBAAkB,IAAI,gBAAgB,EACtC,uBAAuB,IAAI,qBAAqB,EAChD,KAAK,IAAI,GAAG,EACZ,qBAAqB,IAAI,mBAAmB,EAC5C,aAAa,IAAI,WAAW,EAC5B,YAAY,IAAI,UAAU,EAC1B,uBAAuB,IAAI,qBAAqB,EAChD,eAAe,IAAI,aAAa,EAChC,MAAM,IAAI,IAAI,EACd,aAAa,IAAI,WAAW,EAC5B,cAAc,IAAI,YAAY,EAC9B,QAAQ,IAAI,MAAM,EAClB,yBAAyB,IAAI,uBAAuB,EACpD,wBAAwB,IAAI,sBAAsB,EAClD,SAAS,IAAI,OAAO,EACpB,gBAAgB,IAAI,cAAc,EAClC,aAAa,IAAI,WAAW,EAC5B,cAAc,IAAI,YAAY,EAC9B,qBAAqB,IAAI,mBAAmB,EAC5C,aAAa,IAAI,WAAW,EAC5B,gCAAgC,IAAI,8BAA8B,EAClE,kBAAkB,IAAI,gBAAgB,GACvC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
package/jest.config.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "preset": "ts-jest",
3
- "testEnvironment": "node"
4
- }
package/journey/before.ts DELETED
@@ -1,21 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
-
4
- import { promises as fs } from "fs";
5
- import { resolve } from "path";
6
-
7
- import { cwd } from "./entrypoint.test";
8
-
9
- export async function before() {
10
- const dir = resolve(cwd);
11
-
12
- try {
13
- await fs.access(dir);
14
- await fs.rm(dir, { recursive: true, force: true });
15
- } catch (err) {
16
- if (err.code !== "ENOENT") {
17
- throw err;
18
- // The directory does not exist, do nothing
19
- }
20
- }
21
- }
package/journey/k8s.ts DELETED
@@ -1,100 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
-
4
- import { AppsV1Api, CoreV1Api, KubeConfig, V1ConfigMap } from "@kubernetes/client-node";
5
-
6
- const kc = new KubeConfig();
7
- kc.loadFromDefault();
8
-
9
- const k8sApi = kc.makeApiClient(AppsV1Api);
10
- const k8sCoreApi = kc.makeApiClient(CoreV1Api);
11
-
12
- function delay2Secs() {
13
- return new Promise(resolve => setTimeout(resolve, 2000));
14
- }
15
-
16
- export async function createOrReplaceConfigMap(cm: V1ConfigMap) {
17
- const ns = cm.metadata?.namespace || "default";
18
- try {
19
- const resp = await k8sCoreApi.createNamespacedConfigMap(ns, cm);
20
- return resp.body;
21
- } catch (error) {
22
- const resp = await k8sCoreApi.replaceNamespacedConfigMap(cm.metadata?.name || "", ns, cm);
23
- return resp.body;
24
- }
25
- }
26
-
27
- export async function deleteConfigMap(namespace: string, name: string) {
28
- try {
29
- await k8sCoreApi.deleteNamespacedConfigMap(name, namespace);
30
- } catch (error) {
31
- // Do nothing
32
- }
33
- }
34
-
35
- export async function waitForDeploymentReady(namespace: string, name: string) {
36
- const deployment = await k8sApi.readNamespacedDeployment(name, namespace);
37
- const replicas = deployment.body.spec?.replicas || 1;
38
- const readyReplicas = deployment.body.status?.readyReplicas || 0;
39
-
40
- if (replicas !== readyReplicas) {
41
- await delay2Secs();
42
- return waitForDeploymentReady(namespace, name);
43
- }
44
- }
45
-
46
- export async function waitForNamespace(namespace: string) {
47
- try {
48
- const resp = await k8sCoreApi.readNamespace(namespace);
49
- return resp.body;
50
- } catch (error) {
51
- await delay2Secs();
52
- return waitForNamespace(namespace);
53
- }
54
- }
55
-
56
- export async function waitForConfigMap(namespace: string, name: string) {
57
- try {
58
- const resp = await k8sCoreApi.readNamespacedConfigMap(name, namespace);
59
- return resp.body;
60
- } catch (error) {
61
- await delay2Secs();
62
- return waitForConfigMap(namespace, name);
63
- }
64
- }
65
-
66
- export async function waitForSecret(namespace: string, name: string) {
67
- try {
68
- const resp = await k8sCoreApi.readNamespacedSecret(name, namespace);
69
- return resp.body;
70
- } catch (error) {
71
- await delay2Secs();
72
- return waitForSecret(namespace, name);
73
- }
74
- }
75
-
76
- export async function getPodLogs(namespace: string, labelSelector: string) {
77
- let allLogs = "";
78
-
79
- try {
80
- const res = await k8sCoreApi.listNamespacedPod(
81
- namespace,
82
- undefined,
83
- undefined,
84
- undefined,
85
- undefined,
86
- labelSelector,
87
- );
88
- const pods = res.body.items;
89
-
90
- for (const pod of pods) {
91
- const podName = pod.metadata?.name || "unknown";
92
- const log = await k8sCoreApi.readNamespacedPodLog(podName, namespace);
93
- allLogs += log.body;
94
- }
95
- } catch (err) {
96
- console.error("Error: ", err);
97
- }
98
-
99
- return allLogs;
100
- }
@@ -1,69 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
-
4
- import { expect, it } from "@jest/globals";
5
- import { loadYaml } from "@kubernetes/client-node";
6
- import { execSync } from "child_process";
7
- import { promises as fs } from "fs";
8
- import { resolve } from "path";
9
-
10
- import { cwd } from "./entrypoint.test";
11
-
12
- export function peprBuild() {
13
- it("should successfully build the Pepr project", async () => {
14
- execSync("npx pepr build", { cwd: cwd, stdio: "inherit" });
15
- });
16
-
17
- it("should generate produce the K8s yaml file", async () => {
18
- await fs.access(resolve(cwd, "dist", "pepr-module-static-test.yaml"));
19
- });
20
-
21
- it("should generate the zarf.yaml f", async () => {
22
- await fs.access(resolve(cwd, "dist", "zarf.yaml"));
23
- await validateZarfYaml();
24
- });
25
- }
26
-
27
- async function validateZarfYaml() {
28
- // Get the version of the pepr binary
29
- const peprVer = execSync("npx pepr --version", { cwd }).toString().trim();
30
-
31
- // Read the generated yaml files
32
- const k8sYaml = await fs.readFile(resolve(cwd, "dist", "pepr-module-static-test.yaml"), "utf8");
33
- const zarfYAML = await fs.readFile(resolve(cwd, "dist", "zarf.yaml"), "utf8");
34
-
35
- // The expected image name
36
- const expectedImage = `ghcr.io/defenseunicorns/pepr/controller:v${peprVer}`;
37
-
38
- // The expected zarf yaml contents
39
- const expectedZarfYaml = {
40
- kind: "ZarfPackageConfig",
41
- metadata: {
42
- name: "pepr-static-test",
43
- description: "Pepr Module: A test module for Pepr",
44
- url: "https://github.com/defenseunicorns/pepr",
45
- version: "0.0.1",
46
- },
47
- components: [
48
- {
49
- name: "module",
50
- required: true,
51
- manifests: [
52
- {
53
- name: "module",
54
- namespace: "pepr-system",
55
- files: ["pepr-module-static-test.yaml"],
56
- },
57
- ],
58
- images: [expectedImage],
59
- },
60
- ],
61
- };
62
-
63
- // Check the generated zarf yaml
64
- const actualZarfYaml = loadYaml(zarfYAML);
65
- expect(actualZarfYaml).toEqual(expectedZarfYaml);
66
-
67
- // Check the generated k8s yaml
68
- expect(k8sYaml).toMatch(`image: ${expectedImage}`);
69
- }