pepr 0.3.0-rc0 → 0.3.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.
package/README.md CHANGED
@@ -9,7 +9,7 @@ Pepr is on a mission to save Kubernetes from the tyranny of YAML, intimidating g
9
9
  - Zero-config K8s webhook mutations and [validations soon](https://github.com/defenseunicorns/pepr/issues/73).
10
10
  - Human-readable fluent API for generating [Pepr Capabilities](#capability)
11
11
  - Generate new K8s resources based off of cluster resource changes
12
- - Perform other exec/API calls based off of cluster resources changes or any other abitrary schedule
12
+ - Perform other exec/API calls based off of cluster resources changes or any other arbitrary schedule
13
13
  - Out of the box airgap support with [Zarf](https://zarf.dev)
14
14
  - Entire NPM ecosystem available for advanced operations
15
15
  - Realtime K8s debugging system for testing/reacting to cluster changes
@@ -76,7 +76,7 @@ https://user-images.githubusercontent.com/882485/230895880-c5623077-f811-4870-bb
76
76
 
77
77
  ### Module
78
78
 
79
- A module is the top-level collection of capabilities. It is a single, complete TypeScript project that includes an entry point to load all the configuration and capabilities, along with their CapabilityActions. During the Pepr build process, each module produces a unique Kubernetes MutatingWebhookConfiguration and ValidatingWebhookConfiguration, along with a secret containing the transpiled and compressed TypeScript code. The webhooks and secret are deployed into the Kubernetes cluster for processing by a common Pepr controller.
79
+ A module is the top-level collection of capabilities. It is a single, complete TypeScript project that includes an entry point to load all the configuration and capabilities, along with their CapabilityActions. During the Pepr build process, each module produces a unique Kubernetes MutatingWebhookConfiguration and ValidatingWebhookConfiguration, along with a secret containing the transpiled and compressed TypeScript code. The webhooks and secret are deployed into the Kubernetes cluster with their own isolated controller.
80
80
 
81
81
  See [Module](./docs/module.md) for more details.
82
82
 
@@ -95,50 +95,7 @@ For example, a CapabilityAction could be responsible for adding a specific label
95
95
  See [CapabilityActions](./docs/actions.md) for more details.
96
96
 
97
97
  ## Logical Pepr Flow
98
-
99
- ```mermaid
100
- graph LR
101
-
102
- subgraph "Module 3 (Validate Only)"
103
- direction LR
104
- Q[entrypoint 3] --> R[Validate Webhook];
105
- R --> S[Capability a <br><i>- action 1<br>- action 2</i>];
106
- S --> T[Capability b <br><i>- action 1<br>- action 2</i>];
107
- end
108
-
109
- subgraph "Module 2 (Mutate Only)"
110
- direction LR
111
- K[entrypoint 2] --> L[Mutate Webhook];
112
- L --> M[Capability a <br><i>- action 1<br>- action 2</i>];
113
- M --> N[Capability b <br><i>- action 1<br>- action 2<br>- action 3</i>];
114
- N --> O[Capability c <br><i>- action 1</i>];
115
- end
116
-
117
- subgraph "Module 1 (Mutate & Validate)"
118
- direction LR
119
- A[entrypoint 1] --> B[Mutate Webhook];
120
- A --> C[Validate Webhook];
121
- B --> D[Capability a <br><i>- action 1</i>];
122
- D --> E[Capability b <br><i>- action 1<br>- action 2</i>];
123
- E --> F[Capability c <br><i>- action 1<br>- action 2</i>];
124
- C --> G[Capability d <br><i>- action 1<br>- action 2</i>];
125
- G --> H[Capability e <br><i>- action 1</i>];
126
- H --> I[Capability f <br><i>- action 1<br>- action 2<br>- action 3</i>];
127
- end
128
-
129
-
130
-
131
- %% Defining node styles
132
- classDef Validate fill:#66ff66,color:#000;
133
- classDef Mutate fill:#5786ea,color:#000;
134
-
135
-
136
- class L,M,N,O Mutate;
137
- class B,D,E,F Mutate;
138
-
139
- class R,S,T Validate;
140
- class C,G,H,I Validate;
141
- ```
98
+ ![Module Diagram](./.images/modules.svg)
142
99
 
143
100
  ## TypeScript
144
101
 
package/dist/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "engines": {
10
10
  "node": ">=18.0.0"
11
11
  },
12
- "version": "0.3.0-rc0",
12
+ "version": "0.3.0",
13
13
  "main": "dist/index.js",
14
14
  "scripts": {
15
15
  "prebuild": "rm -fr dist/* && node hack/build-template-data.js",
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "engines": {
10
10
  "node": ">=18.0.0"
11
11
  },
12
- "version": "0.3.0-rc0",
12
+ "version": "0.3.0",
13
13
  "main": "dist/index.js",
14
14
  "scripts": {
15
15
  "prebuild": "rm -fr dist/* && node hack/build-template-data.js",
@@ -1,75 +0,0 @@
1
- {
2
- "uid": "6295e2a5-ad33-43d0-a508-2c5893c7d535",
3
- "kind": {
4
- "group": "",
5
- "version": "v1",
6
- "kind": "ConfigMap"
7
- },
8
- "resource": {
9
- "group": "",
10
- "version": "v1",
11
- "resource": "configmaps"
12
- },
13
- "requestKind": {
14
- "group": "",
15
- "version": "v1",
16
- "kind": "ConfigMap"
17
- },
18
- "requestResource": {
19
- "group": "",
20
- "version": "v1",
21
- "resource": "configmaps"
22
- },
23
- "name": "game-demo",
24
- "namespace": "apps",
25
- "operation": "CREATE",
26
- "userInfo": {
27
- "username": "kubernetes-admin",
28
- "groups": ["system:masters", "system:authenticated"]
29
- },
30
- "object": {
31
- "kind": "ConfigMap",
32
- "apiVersion": "v1",
33
- "metadata": {
34
- "name": "game-demo",
35
- "namespace": "apps",
36
- "creationTimestamp": null,
37
- "annotations": {
38
- "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"data\":{\"game.properties\":\"enemy.types=aliens,monsters\\nplayer.maximum-lives=5 \\n\",\"player_initial_lives\":\"3\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"game-demo\",\"namespace\":\"apps\"}}\n"
39
- },
40
- "managedFields": [
41
- {
42
- "manager": "kubectl-client-side-apply",
43
- "operation": "Update",
44
- "apiVersion": "v1",
45
- "time": "2023-03-31T19:46:37Z",
46
- "fieldsType": "FieldsV1",
47
- "fieldsV1": {
48
- "f:data": {
49
- ".": {},
50
- "f:game.properties": {},
51
- "f:player_initial_lives": {}
52
- },
53
- "f:metadata": {
54
- "f:annotations": {
55
- ".": {},
56
- "f:kubectl.kubernetes.io/last-applied-configuration": {}
57
- }
58
- }
59
- }
60
- }
61
- ]
62
- },
63
- "data": {
64
- "game.properties": "enemy.types=aliens,monsters\nplayer.maximum-lives=5 \n",
65
- "player_initial_lives": "3"
66
- }
67
- },
68
- "oldObject": null,
69
- "dryRun": false,
70
- "options": {
71
- "kind": "CreateOptions",
72
- "apiVersion": "meta.k8s.io/v1",
73
- "fieldManager": "kubectl-client-side-apply"
74
- }
75
- }
@@ -1,170 +0,0 @@
1
- {
2
- "uid": "b6b9e558-5b95-488e-bad4-f1d0875569bb",
3
- "kind": {
4
- "group": "apps",
5
- "version": "v1",
6
- "kind": "Deployment"
7
- },
8
- "resource": {
9
- "group": "apps",
10
- "version": "v1",
11
- "resource": "deployments"
12
- },
13
- "requestKind": {
14
- "group": "apps",
15
- "version": "v1",
16
- "kind": "Deployment"
17
- },
18
- "requestResource": {
19
- "group": "apps",
20
- "version": "v1",
21
- "resource": "deployments"
22
- },
23
- "name": "nginx-deployment",
24
- "namespace": "apps",
25
- "operation": "CREATE",
26
- "userInfo": {
27
- "username": "kubernetes-admin",
28
- "groups": ["system:masters", "system:authenticated"]
29
- },
30
- "object": {
31
- "kind": "Deployment",
32
- "apiVersion": "apps/v1",
33
- "metadata": {
34
- "name": "nginx-deployment",
35
- "namespace": "apps",
36
- "creationTimestamp": null,
37
- "labels": {
38
- "app": "nginx"
39
- },
40
- "annotations": {
41
- "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"nginx\"},\"name\":\"nginx-deployment\",\"namespace\":\"apps\"},\"spec\":{\"replicas\":1,\"selector\":{\"matchLabels\":{\"app\":\"nginx\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"nginx\"}},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"nginx\",\"ports\":[{\"containerPort\":80}]}]}}}}\n"
42
- },
43
- "managedFields": [
44
- {
45
- "manager": "kubectl-client-side-apply",
46
- "operation": "Update",
47
- "apiVersion": "apps/v1",
48
- "time": "2023-03-31T19:36:29Z",
49
- "fieldsType": "FieldsV1",
50
- "fieldsV1": {
51
- "f:metadata": {
52
- "f:annotations": {
53
- ".": {},
54
- "f:kubectl.kubernetes.io/last-applied-configuration": {}
55
- },
56
- "f:labels": {
57
- ".": {},
58
- "f:app": {}
59
- }
60
- },
61
- "f:spec": {
62
- "f:progressDeadlineSeconds": {},
63
- "f:replicas": {},
64
- "f:revisionHistoryLimit": {},
65
- "f:selector": {},
66
- "f:strategy": {
67
- "f:rollingUpdate": {
68
- ".": {},
69
- "f:maxSurge": {},
70
- "f:maxUnavailable": {}
71
- },
72
- "f:type": {}
73
- },
74
- "f:template": {
75
- "f:metadata": {
76
- "f:labels": {
77
- ".": {},
78
- "f:app": {}
79
- }
80
- },
81
- "f:spec": {
82
- "f:containers": {
83
- "k:{\"name\":\"nginx\"}": {
84
- ".": {},
85
- "f:image": {},
86
- "f:imagePullPolicy": {},
87
- "f:name": {},
88
- "f:ports": {
89
- ".": {},
90
- "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": {
91
- ".": {},
92
- "f:containerPort": {},
93
- "f:protocol": {}
94
- }
95
- },
96
- "f:resources": {},
97
- "f:terminationMessagePath": {},
98
- "f:terminationMessagePolicy": {}
99
- }
100
- },
101
- "f:dnsPolicy": {},
102
- "f:restartPolicy": {},
103
- "f:schedulerName": {},
104
- "f:securityContext": {},
105
- "f:terminationGracePeriodSeconds": {}
106
- }
107
- }
108
- }
109
- }
110
- }
111
- ]
112
- },
113
- "spec": {
114
- "replicas": 1,
115
- "selector": {
116
- "matchLabels": {
117
- "app": "nginx"
118
- }
119
- },
120
- "template": {
121
- "metadata": {
122
- "creationTimestamp": null,
123
- "labels": {
124
- "app": "nginx"
125
- }
126
- },
127
- "spec": {
128
- "containers": [
129
- {
130
- "name": "nginx",
131
- "image": "nginx:1.14.2",
132
- "ports": [
133
- {
134
- "containerPort": 80,
135
- "protocol": "TCP"
136
- }
137
- ],
138
- "resources": {},
139
- "terminationMessagePath": "/dev/termination-log",
140
- "terminationMessagePolicy": "File",
141
- "imagePullPolicy": "IfNotPresent"
142
- }
143
- ],
144
- "restartPolicy": "Always",
145
- "terminationGracePeriodSeconds": 30,
146
- "dnsPolicy": "ClusterFirst",
147
- "securityContext": {},
148
- "schedulerName": "default-scheduler"
149
- }
150
- },
151
- "strategy": {
152
- "type": "RollingUpdate",
153
- "rollingUpdate": {
154
- "maxUnavailable": "25%",
155
- "maxSurge": "25%"
156
- }
157
- },
158
- "revisionHistoryLimit": 10,
159
- "progressDeadlineSeconds": 600
160
- },
161
- "status": {}
162
- },
163
- "oldObject": null,
164
- "dryRun": false,
165
- "options": {
166
- "kind": "CreateOptions",
167
- "apiVersion": "meta.k8s.io/v1",
168
- "fieldManager": "kubectl-client-side-apply"
169
- }
170
- }
@@ -1,72 +0,0 @@
1
- {
2
- "uid": "e309ad02-d69b-499d-adb4-0eae6dfa5a89",
3
- "kind": {
4
- "group": "",
5
- "version": "v1",
6
- "kind": "Namespace"
7
- },
8
- "resource": {
9
- "group": "",
10
- "version": "v1",
11
- "resource": "namespaces"
12
- },
13
- "requestKind": {
14
- "group": "",
15
- "version": "v1",
16
- "kind": "Namespace"
17
- },
18
- "requestResource": {
19
- "group": "",
20
- "version": "v1",
21
- "resource": "namespaces"
22
- },
23
- "name": "hijeff",
24
- "namespace": "hijeff",
25
- "operation": "CREATE",
26
- "userInfo": {
27
- "username": "kubernetes-admin",
28
- "groups": ["system:masters", "system:authenticated"]
29
- },
30
- "object": {
31
- "kind": "Namespace",
32
- "apiVersion": "v1",
33
- "metadata": {
34
- "name": "hijeff",
35
- "uid": "e8c1d87c-dff1-49c6-aa9d-ef83f2702d7f",
36
- "creationTimestamp": "2023-03-31T19:42:39Z",
37
- "labels": {
38
- "kubernetes.io/metadata.name": "hijeff"
39
- },
40
- "managedFields": [
41
- {
42
- "manager": "kubectl-create",
43
- "operation": "Update",
44
- "apiVersion": "v1",
45
- "time": "2023-03-31T19:42:39Z",
46
- "fieldsType": "FieldsV1",
47
- "fieldsV1": {
48
- "f:metadata": {
49
- "f:labels": {
50
- ".": {},
51
- "f:kubernetes.io/metadata.name": {}
52
- }
53
- }
54
- }
55
- }
56
- ]
57
- },
58
- "spec": {
59
- "finalizers": ["kubernetes"]
60
- },
61
- "status": {
62
- "phase": "Active"
63
- }
64
- },
65
- "oldObject": null,
66
- "dryRun": false,
67
- "options": {
68
- "kind": "CreateOptions",
69
- "apiVersion": "meta.k8s.io/v1",
70
- "fieldManager": "kubectl-create"
71
- }
72
- }
@@ -1,271 +0,0 @@
1
- {
2
- "uid": "af5c3d45-72b8-11eb-a3a3-0242ac130003",
3
- "kind": {
4
- "group": "",
5
- "version": "v1",
6
- "kind": "Pod"
7
- },
8
- "resource": {
9
- "group": "",
10
- "version": "v1",
11
- "resource": "pods"
12
- },
13
- "subResource": "",
14
- "name": "podinfo",
15
- "namespace": "default",
16
- "operation": "Create",
17
- "userInfo": {
18
- "username": "system:serviceaccount:kube-system:replicaset-controller",
19
- "uid": "95c8f0ca-d31a-4d3f-9f27-9a2a2661ab3c",
20
- "groups": [
21
- "system:serviceaccounts",
22
- "system:serviceaccounts:kube-system",
23
- "system:authenticated"
24
- ]
25
- },
26
- "oldObject": {},
27
- "dryRun": false,
28
- "options": null,
29
- "object": {
30
- "apiVersion": "v1",
31
- "kind": "Pod",
32
- "metadata": {
33
- "annotations": {
34
- "prometheus.io/port": "9898",
35
- "prometheus.io/scrape": "true"
36
- },
37
- "creationTimestamp": "2023-03-07T07:48:13Z",
38
- "generateName": "cool-name-podinfo-66bbff7cf4-",
39
- "labels": {
40
- "app.kubernetes.io/name": "cool-name-podinfo",
41
- "pod-template-hash": "66bbff7cf4",
42
- "zarf-agent": "patched"
43
- },
44
- "name": "cool-name-podinfo-66bbff7cf4-fwhl2",
45
- "namespace": "helm-releasename",
46
- "ownerReferences": [
47
- {
48
- "apiVersion": "apps/v1",
49
- "blockOwnerDeletion": true,
50
- "controller": true,
51
- "kind": "ReplicaSet",
52
- "name": "cool-name-podinfo-66bbff7cf4",
53
- "uid": "41d30484-6ccd-462b-b96a-e166095e3681"
54
- }
55
- ],
56
- "resourceVersion": "46512",
57
- "uid": "883303bc-e4b7-4fa8-a576-575cc4407201"
58
- },
59
- "spec": {
60
- "containers": [
61
- {
62
- "command": [
63
- "./podinfo",
64
- "--port=9898",
65
- "--cert-path=/data/cert",
66
- "--port-metrics=9797",
67
- "--grpc-port=9999",
68
- "--grpc-service-name=podinfo",
69
- "--level=info",
70
- "--random-delay=false",
71
- "--random-error=false"
72
- ],
73
- "env": [
74
- {
75
- "name": "PODINFO_UI_COLOR",
76
- "value": "#34577c"
77
- }
78
- ],
79
- "image": "127.0.0.1:31999/stefanprodan/podinfo-2985051089:6.1.6",
80
- "imagePullPolicy": "IfNotPresent",
81
- "livenessProbe": {
82
- "exec": {
83
- "command": ["podcli", "check", "http", "localhost:9898/healthz"]
84
- },
85
- "failureThreshold": 3,
86
- "initialDelaySeconds": 1,
87
- "periodSeconds": 10,
88
- "successThreshold": 1,
89
- "timeoutSeconds": 5
90
- },
91
- "name": "podinfo",
92
- "ports": [
93
- {
94
- "containerPort": 9898,
95
- "name": "http",
96
- "protocol": "TCP"
97
- },
98
- {
99
- "containerPort": 9797,
100
- "name": "http-metrics",
101
- "protocol": "TCP"
102
- },
103
- {
104
- "containerPort": 9999,
105
- "name": "grpc",
106
- "protocol": "TCP"
107
- }
108
- ],
109
- "readinessProbe": {
110
- "exec": {
111
- "command": ["podcli", "check", "http", "localhost:9898/readyz"]
112
- },
113
- "failureThreshold": 3,
114
- "initialDelaySeconds": 1,
115
- "periodSeconds": 10,
116
- "successThreshold": 1,
117
- "timeoutSeconds": 5
118
- },
119
- "resources": {
120
- "requests": {
121
- "cpu": "1m",
122
- "memory": "16Mi"
123
- }
124
- },
125
- "terminationMessagePath": "/dev/termination-log",
126
- "terminationMessagePolicy": "File",
127
- "volumeMounts": [
128
- {
129
- "mountPath": "/data",
130
- "name": "data"
131
- },
132
- {
133
- "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
134
- "name": "kube-api-access-vn9dc",
135
- "readOnly": true
136
- }
137
- ]
138
- }
139
- ],
140
- "dnsPolicy": "ClusterFirst",
141
- "enableServiceLinks": true,
142
- "imagePullSecrets": [
143
- {
144
- "name": "private-registry"
145
- }
146
- ],
147
- "nodeName": "k3d-k3s-default-server-0",
148
- "preemptionPolicy": "PreemptLowerPriority",
149
- "priority": 0,
150
- "restartPolicy": "Always",
151
- "schedulerName": "default-scheduler",
152
- "securityContext": {},
153
- "serviceAccount": "default",
154
- "serviceAccountName": "default",
155
- "terminationGracePeriodSeconds": 30,
156
- "tolerations": [
157
- {
158
- "effect": "NoExecute",
159
- "key": "node.kubernetes.io/not-ready",
160
- "operator": "Exists",
161
- "tolerationSeconds": 300
162
- },
163
- {
164
- "effect": "NoExecute",
165
- "key": "node.kubernetes.io/unreachable",
166
- "operator": "Exists",
167
- "tolerationSeconds": 300
168
- }
169
- ],
170
- "volumes": [
171
- {
172
- "emptyDir": {},
173
- "name": "data"
174
- },
175
- {
176
- "name": "kube-api-access-vn9dc",
177
- "projected": {
178
- "defaultMode": 420,
179
- "sources": [
180
- {
181
- "serviceAccountToken": {
182
- "expirationSeconds": 3607,
183
- "path": "token"
184
- }
185
- },
186
- {
187
- "configMap": {
188
- "items": [
189
- {
190
- "key": "ca.crt",
191
- "path": "ca.crt"
192
- }
193
- ],
194
- "name": "kube-root-ca.crt"
195
- }
196
- },
197
- {
198
- "downwardAPI": {
199
- "items": [
200
- {
201
- "fieldRef": {
202
- "apiVersion": "v1",
203
- "fieldPath": "metadata.namespace"
204
- },
205
- "path": "namespace"
206
- }
207
- ]
208
- }
209
- }
210
- ]
211
- }
212
- }
213
- ]
214
- },
215
- "status": {
216
- "conditions": [
217
- {
218
- "lastProbeTime": null,
219
- "lastTransitionTime": "2023-03-07T07:48:13Z",
220
- "status": "True",
221
- "type": "Initialized"
222
- },
223
- {
224
- "lastProbeTime": null,
225
- "lastTransitionTime": "2023-03-07T07:48:16Z",
226
- "status": "True",
227
- "type": "Ready"
228
- },
229
- {
230
- "lastProbeTime": null,
231
- "lastTransitionTime": "2023-03-07T07:48:16Z",
232
- "status": "True",
233
- "type": "ContainersReady"
234
- },
235
- {
236
- "lastProbeTime": null,
237
- "lastTransitionTime": "2023-03-07T07:48:13Z",
238
- "status": "True",
239
- "type": "PodScheduled"
240
- }
241
- ],
242
- "containerStatuses": [
243
- {
244
- "containerID": "containerd://81b20dafbf2498a52c8ab46fa1e95ce25c06271684e590a377ee4ac9fd2a85ee",
245
- "image": "127.0.0.1:31999/stefanprodan/podinfo-2985051089:6.1.6",
246
- "imageID": "127.0.0.1:31999/stefanprodan/podinfo-2985051089@sha256:1f1fb2d1bfadac8a487106ea62b2b582bedc83fe17b3332dffe9151dfc820742",
247
- "lastState": {},
248
- "name": "podinfo",
249
- "ready": true,
250
- "restartCount": 0,
251
- "started": true,
252
- "state": {
253
- "running": {
254
- "startedAt": "2023-03-07T07:48:14Z"
255
- }
256
- }
257
- }
258
- ],
259
- "hostIP": "172.19.0.3",
260
- "phase": "Running",
261
- "podIP": "10.42.0.26",
262
- "podIPs": [
263
- {
264
- "ip": "10.42.0.26"
265
- }
266
- ],
267
- "qosClass": "Burstable",
268
- "startTime": "2023-03-07T07:48:13Z"
269
- }
270
- }
271
- }