pepr 0.39.1 → 0.40.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/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "!src/**/*.test.ts",
16
16
  "!dist/**/*.test.d.ts*"
17
17
  ],
18
- "version": "0.39.1",
18
+ "version": "0.40.0",
19
19
  "main": "dist/lib.js",
20
20
  "types": "dist/lib.d.ts",
21
21
  "scripts": {
@@ -46,7 +46,7 @@
46
46
  "follow-redirects": "1.15.9",
47
47
  "http-status-codes": "^2.3.0",
48
48
  "json-pointer": "^0.6.2",
49
- "kubernetes-fluent-client": "3.3.1",
49
+ "kubernetes-fluent-client": "3.3.3",
50
50
  "pino": "9.5.0",
51
51
  "pino-pretty": "13.0.0",
52
52
  "prom-client": "15.1.3",
@@ -54,8 +54,8 @@
54
54
  "sigstore": "3.0.0"
55
55
  },
56
56
  "devDependencies": {
57
- "@commitlint/cli": "19.5.0",
58
- "@commitlint/config-conventional": "19.5.0",
57
+ "@commitlint/cli": "19.6.0",
58
+ "@commitlint/config-conventional": "19.6.0",
59
59
  "@fast-check/jest": "^2.0.1",
60
60
  "@jest/globals": "29.7.0",
61
61
  "@types/eslint": "9.6.1",
@@ -0,0 +1,52 @@
1
+ {
2
+ "uid": "2ac28f03-c045-4af6-86f1-aa0007571863",
3
+ "kind": {
4
+ "group": "rbac.authorization.k8s.io",
5
+ "version": "v1",
6
+ "kind": "ClusterRole"
7
+ },
8
+ "resource": {
9
+ "group": "rbac.authorization.k8s.io",
10
+ "version": "v1",
11
+ "resource": "clusterroles"
12
+ },
13
+ "requestKind": {
14
+ "group": "rbac.authorization.k8s.io",
15
+ "version": "v1",
16
+ "kind": "ClusterRole"
17
+ },
18
+ "requestResource": {
19
+ "group": "rbac.authorization.k8s.io",
20
+ "version": "v1",
21
+ "resource": "clusterroles"
22
+ },
23
+ "name": "pod-creator",
24
+ "operation": "CREATE",
25
+ "userInfo": {
26
+ "username": "system:admin",
27
+ "groups": ["system:masters", "system:authenticated"]
28
+ },
29
+ "object": {
30
+ "kind": "ClusterRole",
31
+ "apiVersion": "rbac.authorization.k8s.io/v1",
32
+ "metadata": {
33
+ "name": "pod-creator",
34
+ "creationTimestamp": null
35
+ },
36
+ "rules": [
37
+ {
38
+ "verbs": ["create", "update", "patch"],
39
+ "apiGroups": [""],
40
+ "resources": ["pods"]
41
+ }
42
+ ]
43
+ },
44
+ "oldObject": null,
45
+ "dryRun": false,
46
+ "options": {
47
+ "kind": "CreateOptions",
48
+ "apiVersion": "meta.k8s.io/v1",
49
+ "fieldManager": "kubectl-create",
50
+ "fieldValidation": "Strict"
51
+ }
52
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "uid": "501f5447-a028-4a3f-b4ac-fc56f3f78ffc",
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": "lower",
24
+ "namespace": "pepr-demo",
25
+ "operation": "CREATE",
26
+ "userInfo": {
27
+ "username": "system:admin",
28
+ "groups": ["system:masters", "system:authenticated"]
29
+ },
30
+ "object": {
31
+ "kind": "Deployment",
32
+ "apiVersion": "apps/v1",
33
+ "metadata": {
34
+ "name": "lower",
35
+ "namespace": "pepr-demo",
36
+ "creationTimestamp": null,
37
+ "labels": {
38
+ "app": "lower"
39
+ }
40
+ },
41
+ "spec": {
42
+ "replicas": 3,
43
+ "selector": {
44
+ "matchLabels": {
45
+ "app": "lower"
46
+ }
47
+ },
48
+ "template": {
49
+ "metadata": {
50
+ "creationTimestamp": null,
51
+ "labels": {
52
+ "app": "lower"
53
+ }
54
+ },
55
+ "spec": {
56
+ "containers": [
57
+ {
58
+ "name": "nginx",
59
+ "image": "nginx",
60
+ "resources": {},
61
+ "terminationMessagePath": "/dev/termination-log",
62
+ "terminationMessagePolicy": "File",
63
+ "imagePullPolicy": "Always"
64
+ }
65
+ ],
66
+ "restartPolicy": "Always",
67
+ "terminationGracePeriodSeconds": 30,
68
+ "dnsPolicy": "ClusterFirst",
69
+ "securityContext": {},
70
+ "schedulerName": "default-scheduler"
71
+ }
72
+ },
73
+ "strategy": {
74
+ "type": "RollingUpdate",
75
+ "rollingUpdate": {
76
+ "maxUnavailable": "25%",
77
+ "maxSurge": "25%"
78
+ }
79
+ },
80
+ "revisionHistoryLimit": 10,
81
+ "progressDeadlineSeconds": 600
82
+ },
83
+ "status": {}
84
+ },
85
+ "oldObject": null,
86
+ "dryRun": false,
87
+ "options": {
88
+ "kind": "CreateOptions",
89
+ "apiVersion": "meta.k8s.io/v1",
90
+ "fieldManager": "kubectl-create",
91
+ "fieldValidation": "Strict"
92
+ }
93
+ }
@@ -1,15 +1,25 @@
1
1
  import { kind } from "kubernetes-fluent-client";
2
2
 
3
3
  import { AdmissionRequest } from "../lib/types";
4
- import createPod from "./data/create-pod.json";
5
- import deletePod from "./data/delete-pod.json";
4
+ import admissionRequestCreatePod from "./data/admission-create-pod.json";
5
+ import admissionRequestDeletePod from "./data/admission-delete-pod.json";
6
+ import admissionRequestCreateClusterRole from "./data/admission-create-clusterrole.json";
7
+ import admissionRequestCreateDeployment from "./data/admission-create-deployment.json";
6
8
 
7
- export function CreatePod() {
8
- return cloneObject<kind.Pod>(createPod);
9
+ export function AdmissionRequestCreateDeployment() {
10
+ return cloneObject<kind.Deployment>(admissionRequestCreateDeployment);
9
11
  }
10
12
 
11
- export function DeletePod() {
12
- return cloneObject<kind.Pod>(deletePod);
13
+ export function AdmissionRequestCreatePod() {
14
+ return cloneObject<kind.Pod>(admissionRequestCreatePod);
15
+ }
16
+
17
+ export function AdmissionRequestDeletePod() {
18
+ return cloneObject<kind.Pod>(admissionRequestDeletePod);
19
+ }
20
+
21
+ export function AdmissionRequestCreateClusterRole() {
22
+ return cloneObject<kind.ClusterRole>(admissionRequestCreateClusterRole);
13
23
  }
14
24
 
15
25
  function cloneObject<T>(obj: unknown): AdmissionRequest<T> {
@@ -22,7 +22,6 @@ export function clusterRole(
22
22
  ): kind.ClusterRole {
23
23
  // Create the RBAC map from capabilities
24
24
  const rbacMap = createRBACMap(capabilities);
25
-
26
25
  // Generate scoped rules from rbacMap
27
26
  const scopedRules = Object.keys(rbacMap).map(key => {
28
27
  let group: string;
@@ -216,6 +216,15 @@ export const uncarryableNamespace = allPass([
216
216
  pipe((namespaceSelector, kubernetesObject) => namespaceSelector.includes(carriedNamespace(kubernetesObject)), not),
217
217
  ]);
218
218
 
219
+ export const missingCarriableNamespace = allPass([
220
+ pipe(nthArg(0), length, gt(__, 0)),
221
+ pipe((namespaceSelector: string[], kubernetesObject: KubernetesObject): boolean =>
222
+ kubernetesObject.kind === "Namespace"
223
+ ? !namespaceSelector.includes(kubernetesObject.metadata!.name!)
224
+ : !carriesNamespace(kubernetesObject),
225
+ ),
226
+ ]);
227
+
219
228
  export const carriesIgnoredNamespace = allPass([
220
229
  pipe(nthArg(0), length, gt(__, 0)),
221
230
  pipe(nthArg(1), carriesNamespace),
@@ -35,6 +35,7 @@ import {
35
35
  mismatchedGroup,
36
36
  mismatchedVersion,
37
37
  mismatchedKind,
38
+ missingCarriableNamespace,
38
39
  unbindableNamespaces,
39
40
  uncarryableNamespace,
40
41
  } from "./adjudicators";
@@ -53,7 +54,7 @@ export function shouldSkipRequest(
53
54
  ignoredNamespaces?: string[],
54
55
  ): string {
55
56
  const prefix = "Ignoring Admission Callback:";
56
- const obj = req.operation === Operation.DELETE ? req.oldObject : req.object;
57
+ const obj = (req.operation === Operation.DELETE ? req.oldObject : req.object)!;
57
58
 
58
59
  // prettier-ignore
59
60
  return (
@@ -139,6 +140,12 @@ export function shouldSkipRequest(
139
140
  `but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.`
140
141
  ) :
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
+
142
149
  ""
143
150
  );
144
151
  }
@@ -26,6 +26,7 @@ import {
26
26
  mismatchedNameRegex,
27
27
  mismatchedNamespace,
28
28
  mismatchedNamespaceRegex,
29
+ missingCarriableNamespace,
29
30
  unbindableNamespaces,
30
31
  uncarryableNamespace,
31
32
  } from "./filter/adjudicators";
@@ -139,6 +140,12 @@ export function filterNoMatchReason(
139
140
  `but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.`
140
141
  ) :
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
+
142
149
  ""
143
150
  );
144
151
  }
@@ -50,7 +50,6 @@ export function getOrCreateQueue(obj: KubernetesObject) {
50
50
 
51
51
  // Watch configuration
52
52
  const watchCfg: WatchCfg = {
53
- useLegacyWatch: process.env.PEPR_USE_LEGACY_WATCH === "true",
54
53
  resyncFailureMax: process.env.PEPR_RESYNC_FAILURE_MAX ? parseInt(process.env.PEPR_RESYNC_FAILURE_MAX, 10) : 5,
55
54
  resyncDelaySec: process.env.PEPR_RESYNC_DELAY_SECONDS ? parseInt(process.env.PEPR_RESYNC_DELAY_SECONDS, 10) : 5,
56
55
  lastSeenLimitSeconds: process.env.PEPR_LAST_SEEN_LIMIT_SECONDS