From 1f0e828bcc9e0c6b058a3d19594106949d9bc6c8 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 15 Dec 2023 02:40:59 -0600 Subject: [PATCH 01/98] wip: UDS Operator --- README.md | 9 +- bundles/tls-certs.ts | 31 --- package-lock.json | 195 ++++++------------ package.json | 5 +- pepr.ts | 6 +- src/istio/pepr/index.ts | 1 - src/istio/pepr/istio-injection.ts | 15 -- .../chart/templates/istio/pepr-config.yaml | 1 + src/operator/config.ts | 3 + .../crd/generated/package-v1alpha1.ts | 164 +++++++++++++++ src/operator/crd/index.ts | 1 + src/operator/crd/register.ts | 35 ++++ src/operator/crd/sources/v1alpha1.ts | 146 +++++++++++++ src/operator/index.ts | 36 ++++ src/operator/namespace.ts | 34 +++ src/operator/network/README.md | 1 + src/operator/network/allow-egress-dns.ts | 31 +++ src/operator/network/allow-egress-istiod.ts | 39 ++++ .../network/allow-egress-within-ns.ts | 25 +++ .../allow-ingress-sidecar-monitoring.ts | 40 ++++ .../network/allow-ingress-within-ns.ts | 25 +++ src/operator/network/builder.ts | 54 +++++ src/operator/network/default-deny-all.ts | 18 ++ src/operator/network/index.ts | 47 +++++ src/operator/network/transforms.ts | 59 ++++++ src/operator/tasks.yaml | 15 ++ src/operator/test.ts | 39 ++++ tasks/deploy.yaml | 8 - 28 files changed, 895 insertions(+), 188 deletions(-) delete mode 100644 bundles/tls-certs.ts delete mode 100644 src/istio/pepr/istio-injection.ts create mode 100644 src/operator/config.ts create mode 100644 src/operator/crd/generated/package-v1alpha1.ts create mode 100644 src/operator/crd/index.ts create mode 100644 src/operator/crd/register.ts create mode 100644 src/operator/crd/sources/v1alpha1.ts create mode 100644 src/operator/index.ts create mode 100644 src/operator/namespace.ts create mode 100644 src/operator/network/README.md create mode 100644 src/operator/network/allow-egress-dns.ts create mode 100644 src/operator/network/allow-egress-istiod.ts create mode 100644 src/operator/network/allow-egress-within-ns.ts create mode 100644 src/operator/network/allow-ingress-sidecar-monitoring.ts create mode 100644 src/operator/network/allow-ingress-within-ns.ts create mode 100644 src/operator/network/builder.ts create mode 100644 src/operator/network/default-deny-all.ts create mode 100644 src/operator/network/index.ts create mode 100644 src/operator/network/transforms.ts create mode 100644 src/operator/tasks.yaml create mode 100644 src/operator/test.ts diff --git a/README.md b/README.md index f67805665..42c460b1b 100644 --- a/README.md +++ b/README.md @@ -47,17 +47,18 @@ uds deploy oci://ghcr.io/defenseunicorns/packages/uds/bundles/k3d-core:arm64 uds deploy oci://ghcr.io/defenseunicorns/packages/uds/bundles/k3d-core:amd64 ``` -The bundle includes the uds.dev certs by default. You can use the UDS environment variables to override the default values. E.g. +The bundle includes the uds.dev certs by default. You can use the UDS environment variables to override the default values. E.g. ```bash -# Set environment variables with the contents of your certificate and key files +# Set environment variables with the contents of your certificate and key files (must be base64 encoded) UDS_ADMIN_TLS_CERT=$(cat admin.crt) UDS_ADMIN_TLS_KEY=$(cat admin.key) UDS_TENANT_TLS_CERT=$(cat tenant.crt) UDS_TENANT_TLS_KEY=$(cat tenant.key) -# AMD version -uds deploy ocs://ghcr.io/defenseunicorns/package/uds/bundles/k3d-core:amd64 +UDS_DOMAIN=example.com + +uds deploy oci://ghcr.io/defenseunicorns/package/uds/bundles/k3d-core:amd64 ``` ### UDS Core Packages diff --git a/bundles/tls-certs.ts b/bundles/tls-certs.ts deleted file mode 100644 index 09250f7c5..000000000 --- a/bundles/tls-certs.ts +++ /dev/null @@ -1,31 +0,0 @@ -// Apply using `npx ts-node tls-certs.ts` - -import { K8s, fromEnv, kind } from "kubernetes-fluent-client"; - -const applySecret = (gw: string) => - K8s(kind.Secret).Apply({ - metadata: { - name: "gw-cert", - namespace: `istio-${gw}-gateway`.toLocaleLowerCase(), - }, - type: "kubernetes.io/tls", - data: { - "tls.crt": fromEnv(`${gw}_GATEWAY_TLS_CERT`), - "tls.key": fromEnv(`${gw}_GATEWAY_TLS_KEY`), - }, - }); - -Promise.all([ - // Admin Gateway Secret, "*.admin.burning.boats" - applySecret("ADMIN"), - // Tenant Gateway Secret, "*.burning.boats" - applySecret("TENANT"), -]) - .then(() => { - console.info("✅ Secrets applied"); - }) - // If there's an error, log it and exit with an error code to fail the job. - .catch(e => { - console.error(e); - process.exit(1); - }); diff --git a/package-lock.json b/package-lock.json index ffb5b7294..8fce49592 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "uds-core", "version": "0.2.0", "dependencies": { - "pepr": "0.18.1" + "pepr": "0.20.1" }, "devDependencies": { "@jest/globals": "29.7.0", @@ -136,21 +136,21 @@ } }, "node_modules/@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -175,12 +175,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.23.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -190,14 +190,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -340,14 +340,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" @@ -439,9 +439,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -642,20 +642,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -672,9 +672,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -1753,9 +1753,9 @@ "peer": true }, "node_modules/@types/node": { - "version": "20.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", - "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", + "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", "dependencies": { "undici-types": "~5.26.4" } @@ -2517,9 +2517,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001566", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", - "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", "dev": true, "funding": [ { @@ -2888,9 +2888,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.603", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.603.tgz", - "integrity": "sha512-Dvo5OGjnl7AZTU632dFJtWj0uJK835eeOVQIuRcmBmsFsTNn3cL05FqOyHAfGQDIoHfLhyJ1Tya3PJ0ceMz54g==", + "version": "1.4.613", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.613.tgz", + "integrity": "sha512-r4x5+FowKG6q+/Wj0W9nidx7QO31BJwmR2uEo+Qh3YLGQ8SbBAFuDFpTxzly/I2gsbrFwBuIjrMp423L3O5U3w==", "dev": true }, "node_modules/emittery": { @@ -3619,9 +3619,9 @@ } }, "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "peer": true, "dependencies": { "type-fest": "^0.20.2" @@ -3729,63 +3729,9 @@ } }, "node_modules/help-me": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-4.2.0.tgz", - "integrity": "sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==", - "dependencies": { - "glob": "^8.0.0", - "readable-stream": "^3.6.0" - } - }, - "node_modules/help-me/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/help-me/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/help-me/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/help-me/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" }, "node_modules/html-escaper": { "version": "2.0.2", @@ -5363,16 +5309,16 @@ } }, "node_modules/pepr": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.18.1.tgz", - "integrity": "sha512-2TUOCMHF7ZSUE9UNNgjypWhuZkBpr6Ox1y3Z4C4isFU67YVTT67XTUHchIN5MFniaeGmCofnGoEWmqX/XiVeqQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.20.1.tgz", + "integrity": "sha512-Im0Qi7a96dFmvKL792XlbfFXq7QmFrfDHi/JL/vYIlrU4+H6iCfe7j3jT2TPCKe4wGItTPV2aR+h6+Zrri5WMQ==", "dependencies": { "@types/ramda": "0.29.9", "express": "4.18.2", "fast-json-patch": "3.1.1", "kubernetes-fluent-client": "1.9.0", - "pino": "8.16.2", - "pino-pretty": "10.2.3", + "pino": "8.17.1", + "pino-pretty": "10.3.0", "prom-client": "15.0.0", "ramda": "0.29.1" }, @@ -5413,9 +5359,9 @@ } }, "node_modules/pino": { - "version": "8.16.2", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.16.2.tgz", - "integrity": "sha512-2advCDGVEvkKu9TTVSa/kWW7Z3htI/sBKEZpqiHk6ive0i/7f5b1rsU8jn0aimxqfnSz5bj/nOYkwhBUn5xxvg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.17.1.tgz", + "integrity": "sha512-YoN7/NJgnsJ+fkADZqjhRt96iepWBndQHeClmSBH0sQWCb8zGD74t00SK4eOtKFi/f8TUmQnfmgglEhd2kI1RQ==", "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", @@ -5443,15 +5389,15 @@ } }, "node_modules/pino-pretty": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.2.3.tgz", - "integrity": "sha512-4jfIUc8TC1GPUfDyMSlW1STeORqkoxec71yhxIpLDQapUu8WOuoz2TTCoidrIssyz78LZC69whBMPIKCMbi3cw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.0.tgz", + "integrity": "sha512-JthvQW289q3454mhM3/38wFYGWPiBMR28T3CpDNABzoTQOje9UKS7XCJQSnjWF9LQGQkGd8D7h0oq+qwiM3jFA==", "dependencies": { "colorette": "^2.0.7", "dateformat": "^4.6.3", "fast-copy": "^3.0.0", "fast-safe-stringify": "^2.1.1", - "help-me": "^4.0.1", + "help-me": "^5.0.0", "joycon": "^3.1.1", "minimist": "^1.2.6", "on-exit-leak-free": "^2.1.0", @@ -6651,11 +6597,6 @@ "requires-port": "^1.0.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -6776,9 +6717,9 @@ } }, "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", + "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index c14a9cbc1..c166fdd71 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,16 @@ "zarf" ], "labels": [] + }, + "env": { + "UDS_DOMAIN": "###ZARF_VAR_DOMAIN###" } }, "scripts": { "k3d-setup": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'" }, "dependencies": { - "pepr": "0.18.1" + "pepr": "0.20.1" }, "devDependencies": { "@jest/globals": "29.7.0", diff --git a/pepr.ts b/pepr.ts index 32d384e5d..fcee1fc0e 100644 --- a/pepr.ts +++ b/pepr.ts @@ -2,8 +2,9 @@ import { Capability, PeprModule } from "pepr"; import cfg from "./package.json"; -import { policies } from "./src/policies"; import { istio } from "./src/istio/pepr"; +import { operator } from "./src/operator"; +import { policies } from "./src/policies"; /** * This the root of the UDS Core Pepr Module. To operate on a specific source package, you can @@ -13,6 +14,9 @@ import { istio } from "./src/istio/pepr"; * UDS_PKG=istio npx pepr build */ const sortedCapabilities: Record[] = [ + // UDS Core Operator + { operator }, + // UDS Core Policies { policies }, diff --git a/src/istio/pepr/index.ts b/src/istio/pepr/index.ts index 46c08384f..8c1ff8d42 100644 --- a/src/istio/pepr/index.ts +++ b/src/istio/pepr/index.ts @@ -1,4 +1,3 @@ -import "./istio-injection"; import "./istio-job-termination"; import "./istio-virtual-service"; diff --git a/src/istio/pepr/istio-injection.ts b/src/istio/pepr/istio-injection.ts deleted file mode 100644 index 592076a6e..000000000 --- a/src/istio/pepr/istio-injection.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { a } from "pepr"; - -import { When } from "./common"; - -/** - * Watch Namespaces for creation or updates and ensure the istio-injection label is set - */ -When(a.Namespace) - .IsCreatedOrUpdated() - .Mutate(ns => { - // If the istio-injection label is not present, add it and set it to "enabled" - if (!ns.HasLabel("istio-injection")) { - ns.SetLabel("istio-injection", "enabled"); - } - }); diff --git a/src/neuvector/chart/templates/istio/pepr-config.yaml b/src/neuvector/chart/templates/istio/pepr-config.yaml index 9e60d4b39..e25288af8 100644 --- a/src/neuvector/chart/templates/istio/pepr-config.yaml +++ b/src/neuvector/chart/templates/istio/pepr-config.yaml @@ -6,3 +6,4 @@ metadata: labels: "uds/istio-gateway": "admin" "uds/istio-host": "neuvector" + diff --git a/src/operator/config.ts b/src/operator/config.ts new file mode 100644 index 000000000..d67dea199 --- /dev/null +++ b/src/operator/config.ts @@ -0,0 +1,3 @@ +export const UDSConfig = { + domain: process.env.UDS_DOMAIN || "uds.dev", +}; diff --git a/src/operator/crd/generated/package-v1alpha1.ts b/src/operator/crd/generated/package-v1alpha1.ts new file mode 100644 index 000000000..cf83a10ea --- /dev/null +++ b/src/operator/crd/generated/package-v1alpha1.ts @@ -0,0 +1,164 @@ +// This file is auto-generated by kubernetes-fluent-client, do not edit manually + +import { GenericKind, RegisterKind } from "kubernetes-fluent-client"; + +export class Package extends GenericKind { + spec?: Spec; + status?: { [key: string]: never }; +} + +export interface Spec { + /** + * Network configuration for the package + */ + network?: Network; +} + +/** + * Network configuration for the package + */ +export interface Network { + /** + * Expose a service on an Istio Gateway + */ + expose?: Expose[]; + /** + * NetworkPolicy configuration for the package + */ + policies?: Policies; +} + +export interface Expose { + /** + * The name of the gateway to expose the service on + */ + gateway?: Gateway; + /** + * The hostname to expose the service on + */ + host?: string; + /** + * The name of the port to expose + */ + port?: string; + /** + * The name of the service to expose + */ + service?: string; +} + +/** + * The name of the gateway to expose the service on + */ +export enum Gateway { + Admin = "admin", + Passthrough = "passthrough", + Tenant = "tenant", +} + +/** + * NetworkPolicy configuration for the package + */ +export interface Policies { + /** + * Allow specific traffic + */ + allow?: Allow[]; + /** + * Disable default UDS NetworkPolicy configurations + */ + disableDefaults?: DisableDefault[]; +} + +export interface Allow { + /** + * The direction of the traffic + */ + direction: Direction; + /** + * The labels to apply to the policy + */ + labels?: { [key: string]: string }; + /** + * The name of the policy + */ + name: string; + /** + * The local pod selector to apply the policy to + */ + podSelector: PodSelector; + /** + * The port to allow + */ + port?: number; + /** + * The protocol (TCP, UDP, or SCTP) to allow. Defaults to TCP. + */ + protocol?: Protocol; + /** + * The remote namespace selector + */ + remoteNamespaceSelector?: RemoteNamespaceSelector; + /** + * The remote pod selector + */ + remotePodSelector?: RemotePodSelector; +} + +/** + * The direction of the traffic + */ +export enum Direction { + Egress = "Egress", + Ingress = "Ingress", +} + +/** + * The local pod selector to apply the policy to + */ +export interface PodSelector { + /** + * The labels to match + */ + matchLabels?: { [key: string]: string }; +} + +/** + * The protocol (TCP, UDP, or SCTP) to allow. Defaults to TCP. + */ +export enum Protocol { + SCTP = "SCTP", + TCP = "TCP", + UDP = "UDP", +} + +/** + * The remote namespace selector + */ +export interface RemoteNamespaceSelector { + /** + * The labels to match + */ + matchLabels?: { [key: string]: string }; +} + +/** + * The remote pod selector + */ +export interface RemotePodSelector { + /** + * The labels to match + */ + matchLabels?: { [key: string]: string }; +} + +export enum DisableDefault { + DNSLookup = "dnsLookup", + PermissiveNamespace = "permissiveNamespace", +} + +RegisterKind(Package, { + group: "uds.dev", + version: "v1alpha1", + kind: "Package", +}); diff --git a/src/operator/crd/index.ts b/src/operator/crd/index.ts new file mode 100644 index 000000000..e0c4b3df2 --- /dev/null +++ b/src/operator/crd/index.ts @@ -0,0 +1 @@ +export { Package as UDSPackage, DisableDefault, Allow } from "./generated/package-v1alpha1"; diff --git a/src/operator/crd/register.ts b/src/operator/crd/register.ts new file mode 100644 index 000000000..a0e450b40 --- /dev/null +++ b/src/operator/crd/register.ts @@ -0,0 +1,35 @@ +import { K8s, Log, kind } from "pepr"; + +import { v1alpha1 } from "./sources/v1alpha1"; + +// Register the CRD if we're in watch mode +if (process.env.PEPR_WATCH_MODE === "true") { + K8s(kind.CustomResourceDefinition) + .Apply({ + apiVersion: "apiextensions.k8s.io/v1", + kind: "CustomResourceDefinition", + metadata: { + name: "packages.uds.dev", + }, + spec: { + group: "uds.dev", + versions: [v1alpha1], + scope: "Namespaced", + names: { + plural: "packages", + singular: "package", + kind: "Package", + shortNames: ["pkg"], + }, + }, + }) + .then(() => { + Log.info("CRD registered"); + }) + .catch(err => { + Log.error(err); + + // Sad times, let's exit + process.exit(1); + }); +} diff --git a/src/operator/crd/sources/v1alpha1.ts b/src/operator/crd/sources/v1alpha1.ts new file mode 100644 index 000000000..89fd6c03c --- /dev/null +++ b/src/operator/crd/sources/v1alpha1.ts @@ -0,0 +1,146 @@ +import { V1CustomResourceDefinitionVersion, V1JSONSchemaProps } from "@kubernetes/client-node"; + +export const v1alpha1: V1CustomResourceDefinitionVersion = { + name: "v1alpha1", + served: true, + storage: true, + schema: { + openAPIV3Schema: { + type: "object", + properties: { + status: { + type: "object", + // JS Lib uses _ instead of - which makes the API Server very sad + "x-kubernetes-preserve-unknown-fields": true, + } as V1JSONSchemaProps, + spec: { + type: "object", + "x-kubernetes-preserve-unknown-fields": true, + properties: { + network: { + type: "object", + description: "Network configuration for the package", + properties: { + expose: { + type: "array", + description: "Expose a service on an Istio Gateway", + items: { + type: "object", + properties: { + service: { + description: "The name of the service to expose", + type: "string", + }, + port: { + description: "The name of the port to expose", + type: "string", + }, + gateway: { + description: "The name of the gateway to expose the service on", + enum: ["admin", "tenant", "passthrough"], + type: "string", + }, + host: { + description: "The hostname to expose the service on", + type: "string", + }, + }, + }, + }, + policies: { + type: "object", + description: "NetworkPolicy configuration for the package", + properties: { + disableDefaults: { + description: "Disable default UDS NetworkPolicy configurations", + type: "array", + items: { + type: "string", + enum: ["dnsLookup", "permissiveNamespace"], + }, + }, + allow: { + description: "Allow specific traffic", + type: "array", + items: { + type: "object", + required: ["name", "direction", "podSelector"], + properties: { + name: { + description: "The name of the policy", + type: "string", + }, + labels: { + description: "The labels to apply to the policy", + type: "object", + additionalProperties: { + type: "string", + }, + }, + direction: { + description: "The direction of the traffic", + enum: ["Ingress", "Egress"], + type: "string", + }, + podSelector: { + description: "The local pod selector to apply the policy to", + type: "object", + properties: { + matchLabels: { + description: "The labels to match", + type: "object", + additionalProperties: { + type: "string", + }, + }, + }, + }, + remoteNamespaceSelector: { + description: "The remote namespace selector", + type: "object", + properties: { + matchLabels: { + description: "The labels to match", + type: "object", + additionalProperties: { + type: "string", + }, + }, + }, + }, + remotePodSelector: { + description: "The remote pod selector", + type: "object", + properties: { + matchLabels: { + description: "The labels to match", + type: "object", + additionalProperties: { + type: "string", + }, + }, + }, + }, + port: { + description: "The port to allow", + type: "number", + }, + protocol: { + description: + "The protocol (TCP, UDP, or SCTP) to allow. Defaults to TCP.", + type: "string", + enum: ["TCP", "UDP", "SCTP"], + }, + }, + }, + }, + }, + }, + }, + }, + }, + } as V1JSONSchemaProps, + }, + }, + }, +}; diff --git a/src/operator/index.ts b/src/operator/index.ts new file mode 100644 index 000000000..bc6a8d09f --- /dev/null +++ b/src/operator/index.ts @@ -0,0 +1,36 @@ +import { Capability, Log } from "pepr"; + +import { UDSPackage } from "./crd"; +import "./crd/register"; +import { syncNamespace } from "./namespace"; +import { networkPolicies } from "./network"; + +export const operator = new Capability({ + name: "uds-core-operator", + description: "The UDS Operator is responsible for managing the lifecycle of UDS resources", +}); + +export const { Store, When } = operator; + +When(UDSPackage) + .IsCreatedOrUpdated() + .Watch(async pkg => { + if (!pkg.metadata?.namespace) { + Log.error(pkg, `Invalid Package definition`); + return; + } + + Log.debug(pkg, `Processing Package ${pkg.metadata.namespace}/${pkg.metadata.name}`); + + // Configure the namespace and namespace-wide network policies + try { + const namespace = await syncNamespace(pkg); + + await networkPolicies(pkg, namespace); + } catch (e) { + Log.error( + e, + `Error configuring namespace or network policies for ${pkg.metadata.namespace}/${pkg.metadata.name}`, + ); + } + }); diff --git a/src/operator/namespace.ts b/src/operator/namespace.ts new file mode 100644 index 000000000..c10f0502e --- /dev/null +++ b/src/operator/namespace.ts @@ -0,0 +1,34 @@ +import { K8s, kind } from "pepr"; +import { UDSPackage } from "./crd"; + +/** + * Syncs the package namespace istio-injection label and adds a label for the package name + * + * @param pkg + * @returns the namespace if successful, otherwise an empty string + */ +export async function syncNamespace(pkg: UDSPackage) { + if (!pkg.metadata?.namespace || !pkg.metadata.name) { + throw new Error(`Invalid Package definition, missing namespace or name`); + } + + const pkgLabel = `uds/${pkg.metadata.name}`; + const sourceNS = await K8s(kind.Namespace).Get(pkg.metadata.namespace); + const labels = sourceNS.metadata?.labels || {}; + + // Ensure Istio injection is enabled and the package label is present + if (labels["istio-injection"] !== "enabled" || !labels[pkgLabel]) { + labels["istio-injection"] = "enabled"; + labels[pkgLabel] = pkg.metadata.name; + + // Apply the updated Namespace + await K8s(kind.Namespace).Apply({ + metadata: { + name: pkg.metadata.namespace, + labels, + }, + }); + } + + return pkg.metadata.namespace; +} diff --git a/src/operator/network/README.md b/src/operator/network/README.md new file mode 100644 index 000000000..3b11be709 --- /dev/null +++ b/src/operator/network/README.md @@ -0,0 +1 @@ +This folder contains UDS Core common network policies for the cluster. They establish a baseline security posture that should be used in conjunction with individual allow policies for each workload. diff --git a/src/operator/network/allow-egress-dns.ts b/src/operator/network/allow-egress-dns.ts new file mode 100644 index 000000000..37cd882d2 --- /dev/null +++ b/src/operator/network/allow-egress-dns.ts @@ -0,0 +1,31 @@ +import { kind } from "pepr"; + +export function allowEgressDNS(ns: string): kind.NetworkPolicy { + return { + apiVersion: "networking.k8s.io/v1", + kind: "NetworkPolicy", + metadata: { + name: "allow-egress-dns", + namespace: ns, + }, + spec: { + podSelector: {}, + policyTypes: ["Egress"], + egress: [ + { + to: [ + { + namespaceSelector: {}, + }, + ], + ports: [ + { + port: 53, + protocol: "UDP", + }, + ], + }, + ], + }, + }; +} diff --git a/src/operator/network/allow-egress-istiod.ts b/src/operator/network/allow-egress-istiod.ts new file mode 100644 index 000000000..23d3bac1e --- /dev/null +++ b/src/operator/network/allow-egress-istiod.ts @@ -0,0 +1,39 @@ +import { kind } from "pepr"; + +export function allowEgressIstiod(ns: string): kind.NetworkPolicy { + return { + apiVersion: "networking.k8s.io/v1", + kind: "NetworkPolicy", + metadata: { + name: "allow-egress-istiod", + namespace: ns, + }, + spec: { + podSelector: {}, + policyTypes: ["Egress"], + egress: [ + { + to: [ + { + namespaceSelector: { + matchLabels: { + "kubernetes.io/metadata.name": "istio-system", + }, + }, + podSelector: { + matchLabels: { + istio: "pilot", + }, + }, + }, + ], + ports: [ + { + port: 15012, + }, + ], + }, + ], + }, + }; +} diff --git a/src/operator/network/allow-egress-within-ns.ts b/src/operator/network/allow-egress-within-ns.ts new file mode 100644 index 000000000..5c1f73699 --- /dev/null +++ b/src/operator/network/allow-egress-within-ns.ts @@ -0,0 +1,25 @@ +import { kind } from "pepr"; + +export function allowEgressWithinNS(ns: string): kind.NetworkPolicy { + return { + apiVersion: "networking.k8s.io/v1", + kind: "NetworkPolicy", + metadata: { + name: "allow-egress-within-ns", + namespace: ns, + }, + spec: { + podSelector: {}, + policyTypes: ["Egress"], + egress: [ + { + to: [ + { + namespaceSelector: {}, + }, + ], + }, + ], + }, + }; +} diff --git a/src/operator/network/allow-ingress-sidecar-monitoring.ts b/src/operator/network/allow-ingress-sidecar-monitoring.ts new file mode 100644 index 000000000..35a698f60 --- /dev/null +++ b/src/operator/network/allow-ingress-sidecar-monitoring.ts @@ -0,0 +1,40 @@ +import { kind } from "pepr"; + +export function allowIngressSidecarMonitoring(ns: string): kind.NetworkPolicy { + return { + apiVersion: "networking.k8s.io/v1", + kind: "NetworkPolicy", + metadata: { + name: "allow-ingress-sidecar-monitoring", + namespace: ns, + }, + spec: { + podSelector: {}, + policyTypes: ["Ingress"], + ingress: [ + { + from: [ + { + namespaceSelector: { + matchLabels: { + "kubernetes.io/metadata.name": "monitoring", + }, + }, + podSelector: { + matchLabels: { + app: "prometheus", + }, + }, + }, + ], + ports: [ + { + protocol: "TCP", + port: 15020, + }, + ], + }, + ], + }, + }; +} diff --git a/src/operator/network/allow-ingress-within-ns.ts b/src/operator/network/allow-ingress-within-ns.ts new file mode 100644 index 000000000..a433ed6c9 --- /dev/null +++ b/src/operator/network/allow-ingress-within-ns.ts @@ -0,0 +1,25 @@ +import { kind } from "pepr"; + +export function allowIngressWithinNS(ns: string): kind.NetworkPolicy { + return { + apiVersion: "networking.k8s.io/v1", + kind: "NetworkPolicy", + metadata: { + name: "allow-ingress-within-ns", + namespace: ns, + }, + spec: { + podSelector: {}, + policyTypes: ["Ingress"], + ingress: [ + { + from: [ + { + namespaceSelector: {}, + }, + ], + }, + ], + }, + }; +} diff --git a/src/operator/network/builder.ts b/src/operator/network/builder.ts new file mode 100644 index 000000000..03017d36a --- /dev/null +++ b/src/operator/network/builder.ts @@ -0,0 +1,54 @@ +import { kind } from "pepr"; +import { V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; + +import { Allow, UDSPackage } from "../crd"; + +export function builder(namespace: string, pkg: UDSPackage, policy: Allow): kind.NetworkPolicy { + const pkgName = pkg.metadata!.name!; + const name = `${pkgName}-${policy.name}`; + + // Create the NetworkPolicy + const generated: kind.NetworkPolicy = { + apiVersion: "networking.k8s.io/v1", + kind: "NetworkPolicy", + metadata: { + name, + namespace, + labels: { + "uds/package": pkgName, + ...policy.labels, + }, + }, + spec: { + policyTypes: [policy.direction], + podSelector: policy.podSelector, + }, + }; + + // Create the remote (peer) to match against + const peer: V1NetworkPolicyPeer = { + namespaceSelector: policy.remoteNamespaceSelector, + podSelector: policy.remotePodSelector, + }; + + // Create the port to match against + const ports: V1NetworkPolicyPort[] = [ + { + port: policy.port, + protocol: policy.protocol, + }, + ]; + + // Add the ingress or egress rule + switch (policy.direction) { + case "Ingress": + generated.spec!.ingress = [{ from: [peer], ports }]; + break; + + case "Egress": + generated.spec!.egress = [{ to: [peer], ports }]; + break; + } + + return generated; +} diff --git a/src/operator/network/default-deny-all.ts b/src/operator/network/default-deny-all.ts new file mode 100644 index 000000000..cd91b72e3 --- /dev/null +++ b/src/operator/network/default-deny-all.ts @@ -0,0 +1,18 @@ +import { kind } from "pepr"; + +export function defaultDenyAll(ns: string): kind.NetworkPolicy { + return { + apiVersion: "networking.k8s.io/v1", + kind: "NetworkPolicy", + metadata: { + name: "default-deny-all", + namespace: ns, + }, + spec: { + podSelector: {}, + policyTypes: ["Ingress", "Egress"], + ingress: [], + egress: [], + }, + }; +} diff --git a/src/operator/network/index.ts b/src/operator/network/index.ts new file mode 100644 index 000000000..4ece60a0a --- /dev/null +++ b/src/operator/network/index.ts @@ -0,0 +1,47 @@ +import { K8s, kind } from "pepr"; + +import { DisableDefault, UDSPackage } from "../crd"; +import { allowEgressDNS } from "./allow-egress-dns"; +import { allowEgressIstiod } from "./allow-egress-istiod"; +import { allowEgressWithinNS } from "./allow-egress-within-ns"; +import { allowIngressSidecarMonitoring } from "./allow-ingress-sidecar-monitoring"; +import { allowIngressWithinNS } from "./allow-ingress-within-ns"; +import { defaultDenyAll } from "./default-deny-all"; + +// Import the NetworkPolicy transforms webhook +import "./transforms"; +import { builder } from "./builder"; + +export async function networkPolicies(pkg: UDSPackage, namespace: string) { + const disabled = pkg.spec?.network?.policies?.disableDefaults ?? []; + const customPolicies = pkg.spec?.network?.policies?.allow ?? []; + + const policies = [ + // All traffic must be explicitly allowed + defaultDenyAll(namespace), + // Istio rules + allowEgressIstiod(namespace), + allowIngressSidecarMonitoring(namespace), + ]; + + // Allow DNS lookups + if (!disabled.includes(DisableDefault.DNSLookup)) { + policies.push(allowEgressDNS(namespace)); + } + + // Allow all traffic within the namespace + if (!disabled.includes(DisableDefault.PermissiveNamespace)) { + policies.push(allowEgressWithinNS(namespace)); + policies.push(allowIngressWithinNS(namespace)); + } + + // Process custom policies + for (const policy of customPolicies) { + policies.push(builder(namespace, pkg, policy)); + } + + for (const policy of policies) { + // Apply the policy, overwriting any existing policy + await K8s(kind.NetworkPolicy).Apply(policy); + } +} diff --git a/src/operator/network/transforms.ts b/src/operator/network/transforms.ts new file mode 100644 index 000000000..3da244010 --- /dev/null +++ b/src/operator/network/transforms.ts @@ -0,0 +1,59 @@ +import { K8s, Log, PeprMutateRequest, a, kind } from "pepr"; + +import { Store, When } from "../../policies/common"; + +export enum TransformLabels { + KEY = "uds/transform", + API_SERVER = "api-server", +} + +When(a.NetworkPolicy) + .IsCreatedOrUpdated() + .WithLabel(TransformLabels.KEY) + .Mutate(async request => { + const target = request.Raw.metadata?.labels?.[TransformLabels.KEY]; + + switch (target) { + case TransformLabels.API_SERVER: + await apiServer(request); + break; + + default: + throw new Error("Invalid or missing transform label"); + } + }); + +async function apiServer(request: PeprMutateRequest) { + const types = request.Raw.spec?.policyTypes; + + if (!types || !request.Raw.spec) { + throw new Error("You must specify at least one policyTypes"); + } + + // If the serverIP is not cached, get it from the kubernetes service + const ipBlock = { + cidr: Store.getItem("api-server-cidr") || "", + }; + + if (!ipBlock.cidr) { + const svc = await K8s(kind.Service).InNamespace("default").Get("kubernetes"); + + // If the IP is found, cache it + if (svc.spec?.clusterIP) { + ipBlock.cidr = `${svc.spec.clusterIP}/32`; + Store.setItem("api-server-cidr", ipBlock.cidr); + } else { + // Otherwise, log a warning and default to 0.0.0.0/0 + Log.warn("Unable to get api-server-cidr, defaulting to 0.0.0.0/0"); + ipBlock.cidr = "0.0.0.0/0"; + } + } + + if (types.includes("Ingress")) { + request.Raw.spec.ingress = [{ from: [{ ipBlock }] }]; + } + + if (types.includes("Egress")) { + request.Raw.spec.egress = [{ to: [{ ipBlock }] }]; + } +} diff --git a/src/operator/tasks.yaml b/src/operator/tasks.yaml new file mode 100644 index 000000000..785be58c9 --- /dev/null +++ b/src/operator/tasks.yaml @@ -0,0 +1,15 @@ +tasks: + - name: validate + actions: + - cmd: "npx jest src/operator/**/*.spec.ts" + + - name: gen-crds + description: "Generate CRDS, requires a running kubernetes cluster" + actions: + - cmd: "npx ts-node src/operator/crd/register.ts" + env: + - "PEPR_WATCH_MODE=true" + + - cmd: "npx kubernetes-fluent-client crd packages.uds.dev src/operator/crd/generated" + + - cmd: "npx pepr format" diff --git a/src/operator/test.ts b/src/operator/test.ts new file mode 100644 index 000000000..6d87a9ed0 --- /dev/null +++ b/src/operator/test.ts @@ -0,0 +1,39 @@ +import { K8s } from "pepr"; +import { UDSPackage } from "./crd"; +import { Direction } from "./crd/generated/package-v1alpha1"; + +K8s(UDSPackage) + .Apply({ + metadata: { + name: "testing-123", + namespace: "demo", + }, + spec: { + network: { + policies: { + allow: [ + { + name: "some-cool-test", + direction: Direction.Ingress, + labels: { + demo: "test", + }, + podSelector: { + matchLabels: { + app: "some-cool-test", + }, + }, + port: 80, + remoteNamespaceSelector: {}, + }, + ], + }, + }, + }, + }) + .then(pkg => { + console.log(pkg); + }) + .catch(err => { + console.error(err); + }); diff --git a/tasks/deploy.yaml b/tasks/deploy.yaml index f73eab840..da46066cb 100644 --- a/tasks/deploy.yaml +++ b/tasks/deploy.yaml @@ -16,14 +16,6 @@ tasks: - description: "Deploy the UDS Core Istio Only Bundle" cmd: uds deploy bundles/k3d-istio/uds-bundle-k3d-core-istio-${UDS_ARCH}-${VERSION}.tar.zst --confirm --no-progress - - name: out-of-band-tls-certs - actions: - - description: "Deploy the TLS certs for Istio" - cmd: | - set -e - npm ci - npx --yes ts-node bundles/tls-certs.ts - - name: single-package actions: # @todo (jeff): this pepr package versioning is still janky From 2ffb8472c0e3d15225160ffa202dd3d973da8483 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Sun, 17 Dec 2023 02:23:25 -0600 Subject: [PATCH 02/98] continue working istio migration --- src/istio/pepr/common.ts | 8 - src/istio/pepr/crds/gateway-v1beta1.ts | 160 ------------------ src/istio/pepr/index.ts | 83 ++++++++- src/istio/pepr/istio-job-termination.ts | 74 -------- src/istio/pepr/istio-virtual-service.ts | 134 --------------- .../network-policies/default-deny-all.yaml | 13 -- .../network-policies/egress-dns.yaml | 17 -- .../network-policies/egress-istiod.yaml | 21 --- .../chart/templates/uds-package.yaml | 12 ++ src/neuvector/zarf.yaml | 8 +- .../istio}/virtualservice-v1beta1.ts | 0 .../crd/generated/package-v1alpha1.ts | 22 ++- src/operator/crd/index.ts | 7 +- src/operator/crd/sources/v1alpha1.ts | 11 +- src/operator/index.ts | 5 +- src/operator/istio.ts | 68 ++++++++ src/operator/network/allow-egress-dns.ts | 4 +- src/operator/network/allow-egress-istiod.ts | 4 +- .../network/allow-egress-within-ns.ts | 4 +- .../allow-ingress-sidecar-monitoring.ts | 4 +- .../network/allow-ingress-within-ns.ts | 4 +- src/operator/network/default-deny-all.ts | 4 +- 22 files changed, 212 insertions(+), 455 deletions(-) delete mode 100644 src/istio/pepr/common.ts delete mode 100644 src/istio/pepr/crds/gateway-v1beta1.ts delete mode 100644 src/istio/pepr/istio-job-termination.ts delete mode 100644 src/istio/pepr/istio-virtual-service.ts delete mode 100644 src/neuvector/chart/templates/network-policies/default-deny-all.yaml delete mode 100644 src/neuvector/chart/templates/network-policies/egress-dns.yaml delete mode 100644 src/neuvector/chart/templates/network-policies/egress-istiod.yaml create mode 100644 src/neuvector/chart/templates/uds-package.yaml rename src/{istio/pepr/crds => operator/crd/generated/istio}/virtualservice-v1beta1.ts (100%) create mode 100644 src/operator/istio.ts diff --git a/src/istio/pepr/common.ts b/src/istio/pepr/common.ts deleted file mode 100644 index cfea1fe5e..000000000 --- a/src/istio/pepr/common.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Capability } from "pepr"; - -export const istio = new Capability({ - name: "istio", - description: "UDS Core Capability for Istio service mesh.", -}); - -export const { Store, When } = istio; diff --git a/src/istio/pepr/crds/gateway-v1beta1.ts b/src/istio/pepr/crds/gateway-v1beta1.ts deleted file mode 100644 index 235c8f17e..000000000 --- a/src/istio/pepr/crds/gateway-v1beta1.ts +++ /dev/null @@ -1,160 +0,0 @@ -// This file is auto-generated by kubernetes-fluent-client, do not edit manually - -import { GenericKind, RegisterKind } from "kubernetes-fluent-client"; - -export class Gateway extends GenericKind { - /** - * Configuration affecting edge load balancer. See more details at: - * https://istio.io/docs/reference/config/networking/gateway.html - */ - spec?: Spec; - status?: { [key: string]: unknown }; -} - -/** - * Configuration affecting edge load balancer. See more details at: - * https://istio.io/docs/reference/config/networking/gateway.html - */ -export interface Spec { - /** - * One or more labels that indicate a specific set of pods/VMs on which this gateway - * configuration should be applied. - */ - selector?: { [key: string]: string }; - /** - * A list of server specifications. - */ - servers?: Server[]; -} - -export interface Server { - /** - * The ip or the Unix domain socket to which the listener should be bound to. - */ - bind?: string; - defaultEndpoint?: string; - /** - * One or more hosts exposed by this gateway. - */ - hosts: string[]; - /** - * An optional name of the server, when set must be unique across all servers. - */ - name?: string; - /** - * The Port on which the proxy should listen for incoming connections. - */ - port: Port; - /** - * Set of TLS related options that govern the server's behavior. - */ - tls?: TLS; -} - -/** - * The Port on which the proxy should listen for incoming connections. - */ -export interface Port { - /** - * Label assigned to the port. - */ - name: string; - /** - * A valid non-negative integer port number. - */ - number: number; - /** - * The protocol exposed on the port. - */ - protocol: string; - targetPort?: number; -} - -/** - * Set of TLS related options that govern the server's behavior. - */ -export interface TLS { - /** - * REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`. - */ - caCertificates?: string; - /** - * Optional: If specified, only support the specified cipher list. - */ - cipherSuites?: string[]; - /** - * For gateways running on Kubernetes, the name of the secret that holds the TLS certs - * including the CA certificates. - */ - credentialName?: string; - /** - * If set to true, the load balancer will send a 301 redirect for all http connections, - * asking the clients to use HTTPS. - */ - httpsRedirect?: boolean; - /** - * Optional: Maximum TLS protocol version. - */ - maxProtocolVersion?: ProtocolVersion; - /** - * Optional: Minimum TLS protocol version. - */ - minProtocolVersion?: ProtocolVersion; - /** - * Optional: Indicates whether connections to this port should be secured using TLS. - */ - mode?: Mode; - /** - * REQUIRED if mode is `SIMPLE` or `MUTUAL`. - */ - privateKey?: string; - /** - * REQUIRED if mode is `SIMPLE` or `MUTUAL`. - */ - serverCertificate?: string; - /** - * A list of alternate names to verify the subject identity in the certificate presented by - * the client. - */ - subjectAltNames?: string[]; - /** - * An optional list of hex-encoded SHA-256 hashes of the authorized client certificates. - */ - verifyCertificateHash?: string[]; - /** - * An optional list of base64-encoded SHA-256 hashes of the SPKIs of authorized client - * certificates. - */ - verifyCertificateSpki?: string[]; -} - -/** - * Optional: Maximum TLS protocol version. - * - * Optional: Minimum TLS protocol version. - */ -export enum ProtocolVersion { - TLSAuto = "TLS_AUTO", - Tlsv10 = "TLSV1_0", - Tlsv11 = "TLSV1_1", - Tlsv12 = "TLSV1_2", - Tlsv13 = "TLSV1_3", -} - -/** - * Optional: Indicates whether connections to this port should be secured using TLS. - */ -export enum Mode { - AutoPassthrough = "AUTO_PASSTHROUGH", - IstioMutual = "ISTIO_MUTUAL", - Mutual = "MUTUAL", - OptionalMutual = "OPTIONAL_MUTUAL", - Passthrough = "PASSTHROUGH", - Simple = "SIMPLE", -} - -RegisterKind(Gateway, { - group: "networking.istio.io", - version: "v1beta1", - kind: "Gateway", -}); diff --git a/src/istio/pepr/index.ts b/src/istio/pepr/index.ts index 8c1ff8d42..6b377f912 100644 --- a/src/istio/pepr/index.ts +++ b/src/istio/pepr/index.ts @@ -1,4 +1,81 @@ -import "./istio-job-termination"; -import "./istio-virtual-service"; +import { Exec, KubeConfig } from "@kubernetes/client-node"; +import { Capability, Log, a } from "pepr"; -export { istio } from "./common"; +export const istio = new Capability({ + name: "istio", + description: "UDS Core Capability for Istio service mesh.", +}); + +const { When } = istio; + +// Keep track of in-progress terminations +const inProgress: Record = {}; + +/** + * Watch Pods with the "batch.kubernetes.io/job-name" and "service.istio.io/canonical-name" labels + * to terminate the sidecar after the job completes successfully. + */ +When(a.Pod) + .IsUpdated() + .WithLabel("batch.kubernetes.io/job-name") + .WithLabel("service.istio.io/canonical-name") + .Watch(async pod => { + Log.info(pod, `Processing Pod ${pod.metadata?.namespace}/${pod.metadata?.name}`); + + if (!pod.metadata?.name || !pod.metadata.namespace) { + Log.error(pod, `Invalid Pod definition`); + return; + } + + const { name, namespace } = pod.metadata; + const key = `${namespace}/${name}`; + + // Ensure termination isn't already in progress + if (inProgress[key]) { + return; + } + + // Only terminate if the pod is running + if (pod.status?.phase == "Running") { + // Check all container statuses + if (!pod.status.containerStatuses) { + Log.error(pod, `Invalid container status in Pod`); + return; + } + const shouldTerminate = pod.status.containerStatuses + // Ignore the istio-proxy container + .filter(c => c.name != "istio-proxy") + // and if ALL are terminated AND have exit code 0, then shouldTerminate is true + .every(c => c.state?.terminated && c.state.terminated.exitCode == 0); + + if (shouldTerminate) { + // Mark the pod as seen + inProgress[key] = true; + + Log.info(`Attempting to terminate sidecar for ${key}`); + try { + const kc = new KubeConfig(); + kc.loadFromDefault(); + const exec = new Exec(kc); + + await exec.exec( + namespace, + name, + "istio-proxy", + ["pilot-agent", "request", "POST", "/quitquitquit"], + null, // Could capture exec stdout here + null, // Could capture exec stderr here + process.stdin, + true, + ); + + Log.info(`Terminated sidecar for ${key}`); + } catch (error) { + Log.error(error, `Failed to terminate the sidecar for ${key}`); + + // Remove the pod from the seen list + inProgress[key] = false; + } + } + } + }); diff --git a/src/istio/pepr/istio-job-termination.ts b/src/istio/pepr/istio-job-termination.ts deleted file mode 100644 index 0b318e164..000000000 --- a/src/istio/pepr/istio-job-termination.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Exec, KubeConfig } from "@kubernetes/client-node"; -import { Log, a } from "pepr"; - -import { When } from "./common"; - -// Keep track of in-progress terminations -const inProgress: Record = {}; - -/** - * Watch Pods with the "batch.kubernetes.io/job-name" and "service.istio.io/canonical-name" labels - * to terminate the sidecar after the job completes successfully. - */ -When(a.Pod) - .IsUpdated() - .WithLabel("batch.kubernetes.io/job-name") - .WithLabel("service.istio.io/canonical-name") - .Watch(async pod => { - if (!pod.metadata?.name || !pod.metadata.namespace) { - Log.error(pod, `Invalid Pod definition`); - return; - } - - const { name, namespace } = pod.metadata; - const key = `${namespace}/${name}`; - - // Ensure termination isn't already in progress - if (inProgress[key]) { - return; - } - - // Only terminate if the pod is running - if (pod.status?.phase == "Running") { - // Check all container statuses - if (!pod.status.containerStatuses) { - Log.error(pod, `Invalid container status in Pod`); - return; - } - const shouldTerminate = pod.status.containerStatuses - // Ignore the istio-proxy container - .filter(c => c.name != "istio-proxy") - // and if ALL are terminated AND have exit code 0, then shouldTerminate is true - .every(c => c.state?.terminated && c.state.terminated.exitCode == 0); - - if (shouldTerminate) { - // Mark the pod as seen - inProgress[key] = true; - - Log.info(`Attempting to terminate sidecar for ${key}`); - try { - const kc = new KubeConfig(); - kc.loadFromDefault(); - const exec = new Exec(kc); - - await exec.exec( - namespace, - name, - "istio-proxy", - ["pilot-agent", "request", "POST", "/quitquitquit"], - null, // Could capture exec stdout here - null, // Could capture exec stderr here - process.stdin, - true, - ); - - Log.info(`Terminated sidecar for ${key}`); - } catch (error) { - Log.error(error, `Failed to terminate the sidecar for ${key}`); - - // Remove the pod from the seen list - inProgress[key] = false; - } - } - } - }); diff --git a/src/istio/pepr/istio-virtual-service.ts b/src/istio/pepr/istio-virtual-service.ts deleted file mode 100644 index 799fee38c..000000000 --- a/src/istio/pepr/istio-virtual-service.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { K8s, Log, a, kind } from "pepr"; - -import { Store, When } from "./common"; -import { Gateway } from "./crds/gateway-v1beta1"; -import { PurpleDestination, VirtualService } from "./crds/virtualservice-v1beta1"; - -// Define the configuration keys -enum config { - Gateway = "uds/istio-gateway", - Host = "uds/istio-host", - Port = "uds/istio-port", - Domain = "uds/istio-domain", -} - -// Define the valid gateway names -const validGateway = ["admin", "tenant", "passthrough"]; - -// Watch ConfigMaps with the "uds/istio-gateway" label to generate a VirtualServices -When(a.ConfigMap) - .IsCreatedOrUpdated() - .WithLabel(config.Gateway) - .Watch(async cm => { - if (!cm.metadata?.name || !cm.metadata.namespace || !cm.metadata.labels) { - Log.error(cm, `Invalid ConfigMap definition`); - return; - } - - // Strip "uds-" prefix from the name - const prefix = new RegExp(`^uds-`); - const name = cm.metadata.name.replace(prefix, ""); - - try { - const svc = await K8s(kind.Service).InNamespace(cm.metadata.namespace).Get(name); - - svc.metadata = svc.metadata || {}; - - // use the labels from the ConfigMap - svc.metadata.labels = cm.metadata.labels; - - await handleSvc(svc); - } catch (e) { - Log.error(e, `Error getting Svc ${cm.metadata.namespace}/${name}`); - } - }); - -// Watch Services with the "uds/istio-gateway" label to generate a VirtualServices -When(a.Service).IsCreatedOrUpdated().WithLabel(config.Gateway).Watch(handleSvc); - -async function handleSvc(svc: a.Service) { - if (!svc.metadata?.labels || !svc.metadata.name || !svc.metadata.uid || !svc.spec?.ports) { - Log.error(svc, `Invalid service definition`); - return; - } - - const logTitle = `VirtualService ${svc.metadata.namespace}/${svc.metadata.name}`; - - try { - // Validate the gateway - const gateway = svc.metadata.labels?.[config.Gateway]; - if (!gateway || !validGateway.includes(gateway)) { - Log.error(`Invalid gateway: ${gateway}`); - return; - } - - // Get the gateway name - const gwNamespace = `istio-${gateway}-gateway`; - const gwName = `${gateway}-gateway`; - - // Get the domain for the gateway - let domain = Store.getItem(gwName); - - // If the domain is not present, fetch it from the Gateway and store it - if (!domain) { - const gw = await K8s(Gateway).InNamespace(gwNamespace).Get(gwName); - domain = gw.metadata?.labels?.[config.Domain] || ""; - - // Store the domain for the gateway - if (domain) { - Store.setItem(gwName, domain); - } - } - - // Get any the host or fallback to a wildcard - const hostPrefix = svc.metadata.labels[config.Host] || "*"; - - // Append the domain, if present - const hosts = [hostPrefix + (domain ? `.${domain}` : "")]; - - // Get the port number - const number = - // Try to parse the port number from the label - parseInt(svc.metadata.labels[config.Port]) || - // Try to parse the port number from a named port - svc.spec.ports.find(p => p.name?.includes("http"))?.port || - // Fallback to the first port - svc.spec.ports[0].port; - - // Create the destination - const destination: PurpleDestination = { - host: `${svc.metadata.name}.${svc.metadata.namespace}.svc.cluster.local`, - port: { number }, - }; - - const payload: VirtualService = { - metadata: { - name: svc.metadata.name, - namespace: svc.metadata.namespace, - // Establish the owner ref - ownerReferences: [ - { - apiVersion: svc.apiVersion!, - kind: svc.kind!, - uid: svc.metadata.uid, - name: svc.metadata.name, - }, - ], - }, - spec: { - hosts, - gateways: [`${gwNamespace}/${gwName}`], - http: [{ route: [{ destination }] }], - }, - }; - - Log.debug(payload, `Applying ${logTitle}`); - - // Apply the VirtualService - await K8s(VirtualService).Apply(payload); - - Log.info(`Applied ${logTitle}`); - } catch (e) { - Log.error(e, `Error applying ${logTitle}`); - } -} diff --git a/src/neuvector/chart/templates/network-policies/default-deny-all.yaml b/src/neuvector/chart/templates/network-policies/default-deny-all.yaml deleted file mode 100644 index 90096c092..000000000 --- a/src/neuvector/chart/templates/network-policies/default-deny-all.yaml +++ /dev/null @@ -1,13 +0,0 @@ - -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: default-deny - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Ingress - - Egress - ingress: [] - egress: [] diff --git a/src/neuvector/chart/templates/network-policies/egress-dns.yaml b/src/neuvector/chart/templates/network-policies/egress-dns.yaml deleted file mode 100644 index 04505a846..000000000 --- a/src/neuvector/chart/templates/network-policies/egress-dns.yaml +++ /dev/null @@ -1,17 +0,0 @@ - -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-dns-egress - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Egress - # Allow access to DNS - egress: - - to: - - namespaceSelector: {} - ports: - - port: 53 - protocol: UDP diff --git a/src/neuvector/chart/templates/network-policies/egress-istiod.yaml b/src/neuvector/chart/templates/network-policies/egress-istiod.yaml deleted file mode 100644 index f1e2f5860..000000000 --- a/src/neuvector/chart/templates/network-policies/egress-istiod.yaml +++ /dev/null @@ -1,21 +0,0 @@ - -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-istiod-egress - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Egress - egress: - - to: - - namespaceSelector: - matchLabels: - # app.kubernetes.io/name: istio-controlplane - kubernetes.io/metadata.name: istio-system - podSelector: - matchLabels: - istio: pilot - ports: - - port: 15012 diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml new file mode 100644 index 000000000..9b17a6861 --- /dev/null +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -0,0 +1,12 @@ +apiVersion: uds.dev/v1alpha1 +kind: Package +metadata: + name: neuvector + namespace: {{ .Release.Namespace }} +spec: + network: + expose: + - service: uds-neuvector-service-webui + gateway: admin + host: neuvector + port: 8443 diff --git a/src/neuvector/zarf.yaml b/src/neuvector/zarf.yaml index d577953e1..5a3dd1cbc 100644 --- a/src/neuvector/zarf.yaml +++ b/src/neuvector/zarf.yaml @@ -14,6 +14,10 @@ components: version: 2.6.4 namespace: neuvector gitPath: charts/crd + - name: uds-neuvector-config + namespace: neuvector + version: 0.1.0 + localPath: chart - name: core url: https://neuvector.github.io/neuvector-helm/ version: 2.6.4 @@ -28,10 +32,6 @@ components: gitPath: charts/monitor valuesFiles: - values/neuvector-monitor-values.yaml - - name: uds-neuvector-config - namespace: neuvector - version: 0.1.0 - localPath: chart images: - docker.io/neuvector/controller:5.2.2-s1 - docker.io/neuvector/manager:5.2.2-s1 diff --git a/src/istio/pepr/crds/virtualservice-v1beta1.ts b/src/operator/crd/generated/istio/virtualservice-v1beta1.ts similarity index 100% rename from src/istio/pepr/crds/virtualservice-v1beta1.ts rename to src/operator/crd/generated/istio/virtualservice-v1beta1.ts diff --git a/src/operator/crd/generated/package-v1alpha1.ts b/src/operator/crd/generated/package-v1alpha1.ts index cf83a10ea..dfa8fd716 100644 --- a/src/operator/crd/generated/package-v1alpha1.ts +++ b/src/operator/crd/generated/package-v1alpha1.ts @@ -32,19 +32,23 @@ export interface Expose { /** * The name of the gateway to expose the service on */ - gateway?: Gateway; + gateway: Gateway; /** * The hostname to expose the service on */ - host?: string; + host: string; /** - * The name of the port to expose + * The mode to expose the service on */ - port?: string; + mode?: Mode; + /** + * The port number to expose + */ + port: number; /** * The name of the service to expose */ - service?: string; + service: string; } /** @@ -56,6 +60,14 @@ export enum Gateway { Tenant = "tenant", } +/** + * The mode to expose the service on + */ +export enum Mode { + HTTP = "http", + TCP = "tcp", +} + /** * NetworkPolicy configuration for the package */ diff --git a/src/operator/crd/index.ts b/src/operator/crd/index.ts index e0c4b3df2..4cd0a6510 100644 --- a/src/operator/crd/index.ts +++ b/src/operator/crd/index.ts @@ -1 +1,6 @@ -export { Package as UDSPackage, DisableDefault, Allow } from "./generated/package-v1alpha1"; +export { + Package as UDSPackage, + DisableDefault, + Allow, + Gateway, +} from "./generated/package-v1alpha1"; diff --git a/src/operator/crd/sources/v1alpha1.ts b/src/operator/crd/sources/v1alpha1.ts index 89fd6c03c..c34356d08 100644 --- a/src/operator/crd/sources/v1alpha1.ts +++ b/src/operator/crd/sources/v1alpha1.ts @@ -26,14 +26,15 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { description: "Expose a service on an Istio Gateway", items: { type: "object", + required: ["service", "port", "gateway", "host"], properties: { service: { description: "The name of the service to expose", type: "string", }, port: { - description: "The name of the port to expose", - type: "string", + description: "The port number to expose", + type: "number", }, gateway: { description: "The name of the gateway to expose the service on", @@ -44,6 +45,12 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { description: "The hostname to expose the service on", type: "string", }, + mode: { + description: "The mode to use when exposing the service", + enum: ["http", "tcp"], + type: "string", + default: "http", + }, }, }, }, diff --git a/src/operator/index.ts b/src/operator/index.ts index bc6a8d09f..4b21f0a3b 100644 --- a/src/operator/index.ts +++ b/src/operator/index.ts @@ -2,6 +2,7 @@ import { Capability, Log } from "pepr"; import { UDSPackage } from "./crd"; import "./crd/register"; +import { virtualService } from "./istio"; import { syncNamespace } from "./namespace"; import { networkPolicies } from "./network"; @@ -27,10 +28,12 @@ When(UDSPackage) const namespace = await syncNamespace(pkg); await networkPolicies(pkg, namespace); + + await virtualService(pkg, namespace); } catch (e) { Log.error( e, - `Error configuring namespace or network policies for ${pkg.metadata.namespace}/${pkg.metadata.name}`, + `Error completing configuration for ${pkg.metadata.namespace}/${pkg.metadata.name}`, ); } }); diff --git a/src/operator/istio.ts b/src/operator/istio.ts new file mode 100644 index 000000000..9130464e8 --- /dev/null +++ b/src/operator/istio.ts @@ -0,0 +1,68 @@ +import { K8s, Log } from "pepr"; +import { V1OwnerReference } from "@kubernetes/client-node"; + +import { UDSConfig } from "./config"; +import { UDSPackage } from "./crd"; +import { HTTPRoute, TCPRoute, VirtualService } from "./crd/generated/istio/virtualservice-v1beta1"; + +/** + * Creates a VirtualService for each exposed service in the package + * + * @param pkg + * @param namespace + */ +export async function virtualService(pkg: UDSPackage, namespace: string) { + const { name: pkgName, uid } = pkg.metadata!; + + // Use the CR as the owner ref for each VirtualService + const ownerReferences: V1OwnerReference[] = [ + { + apiVersion: pkg.apiVersion!, + kind: pkg.kind!, + uid: uid!, + name: pkgName!, + }, + ]; + + for (const expose of pkg.spec?.network?.expose ?? []) { + const { gateway, host, port, service, mode } = expose; + + // Use the package name + service name as the VirtualService name + // This ensures we don't accidentally expose the same service multiple times + const name = `${pkgName}-${service}`; + + // Create the route to the service + const route: TCPRoute[] | HTTPRoute[] = [ + { + destination: { + // Use the service name as the host + host: `${service}.${namespace}.svc.cluster.local`, + // The CRD only uses numeric ports + port: { number: port }, + }, + }, + ]; + + const payload: VirtualService = { + metadata: { + name, + namespace, + ownerReferences, + }, + spec: { + // Use the global DNS domain for the host + hosts: [`${host}.${UDSConfig.domain}`], + // Map the gateway (admin, passthrough or tenant) to the VirtualService + gateways: [`istio-${gateway}-gateway/${gateway}-gateway`], + }, + }; + + // Add the route to the spec based on the mode + payload.spec![mode ?? "http"] = [{ route }]; + + Log.debug(payload, `Applying VirtualService ${name}`); + + // Apply the VirtualService + await K8s(VirtualService).Apply(payload); + } +} diff --git a/src/operator/network/allow-egress-dns.ts b/src/operator/network/allow-egress-dns.ts index 37cd882d2..963a04cff 100644 --- a/src/operator/network/allow-egress-dns.ts +++ b/src/operator/network/allow-egress-dns.ts @@ -1,12 +1,12 @@ import { kind } from "pepr"; -export function allowEgressDNS(ns: string): kind.NetworkPolicy { +export function allowEgressDNS(namespace: string): kind.NetworkPolicy { return { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { name: "allow-egress-dns", - namespace: ns, + namespace, }, spec: { podSelector: {}, diff --git a/src/operator/network/allow-egress-istiod.ts b/src/operator/network/allow-egress-istiod.ts index 23d3bac1e..c0539eb90 100644 --- a/src/operator/network/allow-egress-istiod.ts +++ b/src/operator/network/allow-egress-istiod.ts @@ -1,12 +1,12 @@ import { kind } from "pepr"; -export function allowEgressIstiod(ns: string): kind.NetworkPolicy { +export function allowEgressIstiod(namespace: string): kind.NetworkPolicy { return { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { name: "allow-egress-istiod", - namespace: ns, + namespace, }, spec: { podSelector: {}, diff --git a/src/operator/network/allow-egress-within-ns.ts b/src/operator/network/allow-egress-within-ns.ts index 5c1f73699..373656c8a 100644 --- a/src/operator/network/allow-egress-within-ns.ts +++ b/src/operator/network/allow-egress-within-ns.ts @@ -1,12 +1,12 @@ import { kind } from "pepr"; -export function allowEgressWithinNS(ns: string): kind.NetworkPolicy { +export function allowEgressWithinNS(namespace: string): kind.NetworkPolicy { return { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { name: "allow-egress-within-ns", - namespace: ns, + namespace, }, spec: { podSelector: {}, diff --git a/src/operator/network/allow-ingress-sidecar-monitoring.ts b/src/operator/network/allow-ingress-sidecar-monitoring.ts index 35a698f60..bdcd7a811 100644 --- a/src/operator/network/allow-ingress-sidecar-monitoring.ts +++ b/src/operator/network/allow-ingress-sidecar-monitoring.ts @@ -1,12 +1,12 @@ import { kind } from "pepr"; -export function allowIngressSidecarMonitoring(ns: string): kind.NetworkPolicy { +export function allowIngressSidecarMonitoring(namespace: string): kind.NetworkPolicy { return { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { name: "allow-ingress-sidecar-monitoring", - namespace: ns, + namespace, }, spec: { podSelector: {}, diff --git a/src/operator/network/allow-ingress-within-ns.ts b/src/operator/network/allow-ingress-within-ns.ts index a433ed6c9..a331dfcee 100644 --- a/src/operator/network/allow-ingress-within-ns.ts +++ b/src/operator/network/allow-ingress-within-ns.ts @@ -1,12 +1,12 @@ import { kind } from "pepr"; -export function allowIngressWithinNS(ns: string): kind.NetworkPolicy { +export function allowIngressWithinNS(namespace: string): kind.NetworkPolicy { return { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { name: "allow-ingress-within-ns", - namespace: ns, + namespace, }, spec: { podSelector: {}, diff --git a/src/operator/network/default-deny-all.ts b/src/operator/network/default-deny-all.ts index cd91b72e3..0e4423c90 100644 --- a/src/operator/network/default-deny-all.ts +++ b/src/operator/network/default-deny-all.ts @@ -1,12 +1,12 @@ import { kind } from "pepr"; -export function defaultDenyAll(ns: string): kind.NetworkPolicy { +export function defaultDenyAll(namespace: string): kind.NetworkPolicy { return { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { name: "default-deny-all", - namespace: ns, + namespace, }, spec: { podSelector: {}, From b74742ec94c326b50c3c9beba4535aa2d3f82a64 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 18 Dec 2023 09:29:25 -0600 Subject: [PATCH 03/98] wip: consolidate pepr things --- .github/filters.yaml | 9 +--- package-lock.json | 18 +++---- package.json | 3 +- pepr.ts | 52 ++++--------------- .../networkpolicies/default-deny-all.yaml | 12 ----- .../networkpolicies/egress-istiod.yaml | 19 ------- .../networkpolicies/ingress-tempo.yaml | 23 -------- .../networkpolicies/namespace-allow.yaml | 16 ------ src/grafana/chart/templates/uds-package.yaml | 28 ++++++++++ src/grafana/values/values.yaml | 6 --- src/grafana/zarf.yaml | 8 +-- src/istio/zarf.yaml | 5 ++ .../networkpolicies/default-deny-all.yaml | 12 ----- .../templates/networkpolicies/egress-dns.yaml | 16 ------ .../networkpolicies/egress-istiod.yaml | 19 ------- .../templates/networkpolicies/ingress-ns.yaml | 16 ------ src/loki/chart/templates/uds-package.yaml | 22 ++++++++ .../chart/templates/uds-package.yaml | 5 ++ src/metrics-server/zarf.yaml | 8 +-- .../chart/templates/istio/pepr-config.yaml | 9 ---- src/{operator => pepr}/config.ts | 1 + src/{istio/pepr => pepr/istio}/index.ts | 0 .../generated/istio/virtualservice-v1beta1.ts | 0 .../crd/generated/package-v1alpha1.ts | 0 src/{ => pepr}/operator/crd/index.ts | 0 src/{ => pepr}/operator/crd/register.ts | 0 .../operator/crd/sources/v1alpha1.ts | 0 src/{ => pepr}/operator/index.ts | 8 ++- src/{ => pepr}/operator/istio.ts | 9 ++-- src/{ => pepr}/operator/namespace.ts | 0 src/{ => pepr}/operator/network/README.md | 0 .../operator/network/allow-egress-dns.ts | 0 .../operator/network/allow-egress-istiod.ts | 0 .../network/allow-egress-within-ns.ts | 0 .../allow-ingress-sidecar-monitoring.ts | 0 .../network/allow-ingress-within-ns.ts | 0 src/{ => pepr}/operator/network/builder.ts | 0 .../operator/network/default-deny-all.ts | 0 src/{ => pepr}/operator/network/index.ts | 0 src/{ => pepr}/operator/network/transforms.ts | 0 src/{ => pepr}/operator/test.ts | 0 src/{ => pepr}/policies/README.md | 0 src/{ => pepr}/policies/common.ts | 0 src/{ => pepr}/policies/exemptions/index.ts | 0 .../policies/exemptions/matchers.ts | 0 .../policies/exemptions/networking.ts | 0 .../policies/exemptions/security.ts | 0 src/{ => pepr}/policies/exemptions/storage.ts | 0 src/{ => pepr}/policies/index.ts | 0 src/{ => pepr}/policies/network.spec.ts | 0 src/{ => pepr}/policies/networking.ts | 0 src/{ => pepr}/policies/security.spec.ts | 0 src/{ => pepr}/policies/security.ts | 0 src/{ => pepr}/policies/storage.spec.ts | 0 src/{ => pepr}/policies/storage.ts | 0 src/{operator => pepr}/tasks.yaml | 6 +-- src/policies/tasks.yaml | 4 -- tasks/create.yaml | 4 +- 58 files changed, 108 insertions(+), 230 deletions(-) delete mode 100644 src/grafana/chart/templates/networkpolicies/default-deny-all.yaml delete mode 100644 src/grafana/chart/templates/networkpolicies/egress-istiod.yaml delete mode 100644 src/grafana/chart/templates/networkpolicies/ingress-tempo.yaml delete mode 100644 src/grafana/chart/templates/networkpolicies/namespace-allow.yaml create mode 100644 src/grafana/chart/templates/uds-package.yaml delete mode 100644 src/loki/chart/templates/networkpolicies/default-deny-all.yaml delete mode 100644 src/loki/chart/templates/networkpolicies/egress-dns.yaml delete mode 100644 src/loki/chart/templates/networkpolicies/egress-istiod.yaml delete mode 100644 src/loki/chart/templates/networkpolicies/ingress-ns.yaml create mode 100644 src/loki/chart/templates/uds-package.yaml create mode 100644 src/metrics-server/chart/templates/uds-package.yaml delete mode 100644 src/neuvector/chart/templates/istio/pepr-config.yaml rename src/{operator => pepr}/config.ts (57%) rename src/{istio/pepr => pepr/istio}/index.ts (100%) rename src/{ => pepr}/operator/crd/generated/istio/virtualservice-v1beta1.ts (100%) rename src/{ => pepr}/operator/crd/generated/package-v1alpha1.ts (100%) rename src/{ => pepr}/operator/crd/index.ts (100%) rename src/{ => pepr}/operator/crd/register.ts (100%) rename src/{ => pepr}/operator/crd/sources/v1alpha1.ts (100%) rename src/{ => pepr}/operator/index.ts (77%) rename src/{ => pepr}/operator/istio.ts (87%) rename src/{ => pepr}/operator/namespace.ts (100%) rename src/{ => pepr}/operator/network/README.md (100%) rename src/{ => pepr}/operator/network/allow-egress-dns.ts (100%) rename src/{ => pepr}/operator/network/allow-egress-istiod.ts (100%) rename src/{ => pepr}/operator/network/allow-egress-within-ns.ts (100%) rename src/{ => pepr}/operator/network/allow-ingress-sidecar-monitoring.ts (100%) rename src/{ => pepr}/operator/network/allow-ingress-within-ns.ts (100%) rename src/{ => pepr}/operator/network/builder.ts (100%) rename src/{ => pepr}/operator/network/default-deny-all.ts (100%) rename src/{ => pepr}/operator/network/index.ts (100%) rename src/{ => pepr}/operator/network/transforms.ts (100%) rename src/{ => pepr}/operator/test.ts (100%) rename src/{ => pepr}/policies/README.md (100%) rename src/{ => pepr}/policies/common.ts (100%) rename src/{ => pepr}/policies/exemptions/index.ts (100%) rename src/{ => pepr}/policies/exemptions/matchers.ts (100%) rename src/{ => pepr}/policies/exemptions/networking.ts (100%) rename src/{ => pepr}/policies/exemptions/security.ts (100%) rename src/{ => pepr}/policies/exemptions/storage.ts (100%) rename src/{ => pepr}/policies/index.ts (100%) rename src/{ => pepr}/policies/network.spec.ts (100%) rename src/{ => pepr}/policies/networking.ts (100%) rename src/{ => pepr}/policies/security.spec.ts (100%) rename src/{ => pepr}/policies/security.ts (100%) rename src/{ => pepr}/policies/storage.spec.ts (100%) rename src/{ => pepr}/policies/storage.ts (100%) rename src/{operator => pepr}/tasks.yaml (67%) delete mode 100644 src/policies/tasks.yaml diff --git a/.github/filters.yaml b/.github/filters.yaml index f33602b72..0e97ddef8 100644 --- a/.github/filters.yaml +++ b/.github/filters.yaml @@ -1,12 +1,5 @@ all: - - ".github/**" - - "src/**" - - "bundles/**" - - "packages/**" - - "tasks/**" - - "pepr.ts" - - "package-lock.json" - - "zarf-config.yaml" + - "**" authservice: - "src/authservice/**" diff --git a/package-lock.json b/package-lock.json index 8fce49592..687c0eb46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1681,9 +1681,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.7", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", - "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" @@ -1753,9 +1753,9 @@ "peer": true }, "node_modules/@types/node": { - "version": "20.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", - "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dependencies": { "undici-types": "~5.26.4" } @@ -2888,9 +2888,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.613", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.613.tgz", - "integrity": "sha512-r4x5+FowKG6q+/Wj0W9nidx7QO31BJwmR2uEo+Qh3YLGQ8SbBAFuDFpTxzly/I2gsbrFwBuIjrMp423L3O5U3w==", + "version": "1.4.614", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", + "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", "dev": true }, "node_modules/emittery": { diff --git a/package.json b/package.json index c166fdd71..a95ee0ba9 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "labels": [] }, "env": { - "UDS_DOMAIN": "###ZARF_VAR_DOMAIN###" + "UDS_DOMAIN": "###ZARF_VAR_DOMAIN###", + "UDS_WITH_ISTIO": "###ZARF_CONST_WITH_ISTIO###" } }, "scripts": { diff --git a/pepr.ts b/pepr.ts index fcee1fc0e..2d740d573 100644 --- a/pepr.ts +++ b/pepr.ts @@ -1,52 +1,18 @@ -import { Capability, PeprModule } from "pepr"; +import { PeprModule } from "pepr"; import cfg from "./package.json"; -import { istio } from "./src/istio/pepr"; -import { operator } from "./src/operator"; -import { policies } from "./src/policies"; +import { istio } from "./src/pepr/istio"; +import { operator } from "./src/pepr/operator"; +import { policies } from "./src/pepr/policies"; -/** - * This the root of the UDS Core Pepr Module. To operate on a specific source package, you can - * set the `UDS_PKG` environment variable to the name of the package. - * - * Example: - * UDS_PKG=istio npx pepr build - */ -const sortedCapabilities: Record[] = [ +new PeprModule(cfg, [ // UDS Core Operator - { operator }, + operator, // UDS Core Policies - { policies }, + policies, // Istio service mesh - { istio }, -]; - -// Otherwise, use all capabilities -const allCapabilities = sortedCapabilities.flatMap(data => { - return Object.values(data).flat(); -}); - -const pkg = process.env.UDS_PKG; - -if (!pkg || pkg === "all") { - // Start the Pepr module - new PeprModule(cfg, allCapabilities); -} else { - console.log( - `\n\n************** Pepr capabilities limited to only ${pkg} source package **************n\n`, - ); - - // If the UDS_PKG environment variable is set, then only use that source package - const activeCapability = sortedCapabilities.find(data => data[pkg])?.[pkg]; - - if (!activeCapability) { - console.error(`Source package ${pkg} not found. Exiting...`); - process.exit(1); - } - - // Start the Pepr module - new PeprModule(cfg, [activeCapability]); -} + istio, +]); diff --git a/src/grafana/chart/templates/networkpolicies/default-deny-all.yaml b/src/grafana/chart/templates/networkpolicies/default-deny-all.yaml deleted file mode 100644 index d12d05fb1..000000000 --- a/src/grafana/chart/templates/networkpolicies/default-deny-all.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: default-deny-all-grafana - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Ingress - - Egress - ingress: [] - egress: [] diff --git a/src/grafana/chart/templates/networkpolicies/egress-istiod.yaml b/src/grafana/chart/templates/networkpolicies/egress-istiod.yaml deleted file mode 100644 index 92dd90a5e..000000000 --- a/src/grafana/chart/templates/networkpolicies/egress-istiod.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-istiod-egress - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Egress - egress: - - to: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: istio-system - podSelector: - matchLabels: - app: istiod - ports: - - port: 15012 \ No newline at end of file diff --git a/src/grafana/chart/templates/networkpolicies/ingress-tempo.yaml b/src/grafana/chart/templates/networkpolicies/ingress-tempo.yaml deleted file mode 100644 index d4f8a22cb..000000000 --- a/src/grafana/chart/templates/networkpolicies/ingress-tempo.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-tempo-ingress-writes - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app: prometheus - policyTypes: - - Ingress - # Allow remote writes from Tempo - ingress: - - from: - - namespaceSelector: - matchLabels: - app.kubernetes.io/name: tempo - podSelector: - matchLabels: - app.kubernetes.io/name: tempo - ports: - - port: 9090 - protocol: TCP diff --git a/src/grafana/chart/templates/networkpolicies/namespace-allow.yaml b/src/grafana/chart/templates/networkpolicies/namespace-allow.yaml deleted file mode 100644 index 3038cf2c9..000000000 --- a/src/grafana/chart/templates/networkpolicies/namespace-allow.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-in-ns-grafana - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Ingress - - Egress - ingress: - - from: - - podSelector: {} - egress: - - to: - - podSelector: {} diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml new file mode 100644 index 000000000..ba6170601 --- /dev/null +++ b/src/grafana/chart/templates/uds-package.yaml @@ -0,0 +1,28 @@ +apiVersion: uds.dev/v1alpha1 +kind: Package +metadata: + name: grafana + namespace: {{ .Release.Namespace }} +spec: + network: + expose: + - service: grafana + gateway: admin + host: grafana + port: 80 + + policies: + allow: + - name: tempo-ingress-writes + direction: Ingress + podSelector: + matchLabels: + app: grafana + remoteNamespaceSelector: + matchLabels: + app.kubernetes.io/name: tempo + remotePodSelector: + matchLabels: + app.kubernetes.io/name: tempo + port: 9090 + protocol: TCP diff --git a/src/grafana/values/values.yaml b/src/grafana/values/values.yaml index 61978163f..12f45d95b 100644 --- a/src/grafana/values/values.yaml +++ b/src/grafana/values/values.yaml @@ -1,9 +1,3 @@ -service: - labels: - uds/istio-gateway: admin - uds/istio-host: grafana - uds/istio-port: "80" - sidecar: image: # -- The Docker registry diff --git a/src/grafana/zarf.yaml b/src/grafana/zarf.yaml index a573b8e6f..50068e3f8 100644 --- a/src/grafana/zarf.yaml +++ b/src/grafana/zarf.yaml @@ -9,16 +9,16 @@ components: required: true description: "Deploy Grafana" charts: + - name: uds-grafana-config + namespace: grafana + version: 0.1.0 + localPath: chart - name: grafana url: https://grafana.github.io/helm-charts/ version: 7.0.6 namespace: grafana valuesFiles: - values/values.yaml - - name: uds-grafana-config - namespace: grafana - version: 0.1.0 - localPath: chart images: - docker.io/grafana/grafana:10.1.5 - docker.io/curlimages/curl:7.85.0 diff --git a/src/istio/zarf.yaml b/src/istio/zarf.yaml index 46b9fa39e..01f919b1b 100644 --- a/src/istio/zarf.yaml +++ b/src/istio/zarf.yaml @@ -9,6 +9,11 @@ variables: description: "Cluster domain" default: "uds.dev" +constants: + - name: WITH_ISTIO + description: "Track istio installation" + value: "true" + components: - name: istio-controlplane description: "Install the Istio control plane based on https://istio.io/latest/docs/setup/install/helm/" diff --git a/src/loki/chart/templates/networkpolicies/default-deny-all.yaml b/src/loki/chart/templates/networkpolicies/default-deny-all.yaml deleted file mode 100644 index 050d3502b..000000000 --- a/src/loki/chart/templates/networkpolicies/default-deny-all.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: default-deny-all-{{ .Release.Name }} - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Ingress - - Egress - egress: [] - ingress: [] diff --git a/src/loki/chart/templates/networkpolicies/egress-dns.yaml b/src/loki/chart/templates/networkpolicies/egress-dns.yaml deleted file mode 100644 index 0b36e5734..000000000 --- a/src/loki/chart/templates/networkpolicies/egress-dns.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: egress-dns - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Egress - # Allow access to DNS - egress: - - to: - - namespaceSelector: {} - ports: - - port: 53 - protocol: UDP diff --git a/src/loki/chart/templates/networkpolicies/egress-istiod.yaml b/src/loki/chart/templates/networkpolicies/egress-istiod.yaml deleted file mode 100644 index 6415eebde..000000000 --- a/src/loki/chart/templates/networkpolicies/egress-istiod.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-istiod-egress-{{ .Release.Name }} - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Egress - egress: - - to: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: istio-system - podSelector: - matchLabels: - app: pilot - ports: - - port: 15012 diff --git a/src/loki/chart/templates/networkpolicies/ingress-ns.yaml b/src/loki/chart/templates/networkpolicies/ingress-ns.yaml deleted file mode 100644 index 178de6a80..000000000 --- a/src/loki/chart/templates/networkpolicies/ingress-ns.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-in-ns-{{ .Release.Name }} - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Ingress - - Egress - ingress: - - from: - - podSelector: {} - egress: - - to: - - podSelector: {} diff --git a/src/loki/chart/templates/uds-package.yaml b/src/loki/chart/templates/uds-package.yaml new file mode 100644 index 000000000..1dc5771bc --- /dev/null +++ b/src/loki/chart/templates/uds-package.yaml @@ -0,0 +1,22 @@ +apiVersion: uds.dev/v1alpha1 +kind: Package +metadata: + name: loki + namespace: {{ .Release.Namespace }} +spec: + network: + policies: + allow: + - name: tempo-ingress-writes + direction: Ingress + podSelector: + matchLabels: + app: grafana + remoteNamespaceSelector: + matchLabels: + app.kubernetes.io/name: tempo + remotePodSelector: + matchLabels: + app.kubernetes.io/name: tempo + port: 9090 + protocol: TCP diff --git a/src/metrics-server/chart/templates/uds-package.yaml b/src/metrics-server/chart/templates/uds-package.yaml new file mode 100644 index 000000000..960a2accf --- /dev/null +++ b/src/metrics-server/chart/templates/uds-package.yaml @@ -0,0 +1,5 @@ +apiVersion: uds.dev/v1alpha1 +kind: Package +metadata: + name: metrics-server + namespace: { { .Release.Namespace } } diff --git a/src/metrics-server/zarf.yaml b/src/metrics-server/zarf.yaml index e502bf19c..3bd93ed69 100644 --- a/src/metrics-server/zarf.yaml +++ b/src/metrics-server/zarf.yaml @@ -8,15 +8,15 @@ components: - name: metrics-server required: true charts: + - name: uds-metrics-server-config + namespace: metrics-server + version: 0.1.0 + localPath: chart - name: metrics-server namespace: metrics-server url: https://kubernetes-sigs.github.io/metrics-server version: 3.11.0 valuesFiles: - "values/values.yaml" - - name: uds-metrics-server-config - namespace: metrics-server - version: 0.1.0 - localPath: chart images: - registry.k8s.io/metrics-server/metrics-server:v0.6.4 diff --git a/src/neuvector/chart/templates/istio/pepr-config.yaml b/src/neuvector/chart/templates/istio/pepr-config.yaml deleted file mode 100644 index e25288af8..000000000 --- a/src/neuvector/chart/templates/istio/pepr-config.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: uds-neuvector-service-webui - namespace: {{ .Release.Namespace }} - labels: - "uds/istio-gateway": "admin" - "uds/istio-host": "neuvector" - diff --git a/src/operator/config.ts b/src/pepr/config.ts similarity index 57% rename from src/operator/config.ts rename to src/pepr/config.ts index d67dea199..ffcc70b8d 100644 --- a/src/operator/config.ts +++ b/src/pepr/config.ts @@ -1,3 +1,4 @@ export const UDSConfig = { domain: process.env.UDS_DOMAIN || "uds.dev", + istioInstalled: process.env.UDS_WITH_ISTIO === "true", }; diff --git a/src/istio/pepr/index.ts b/src/pepr/istio/index.ts similarity index 100% rename from src/istio/pepr/index.ts rename to src/pepr/istio/index.ts diff --git a/src/operator/crd/generated/istio/virtualservice-v1beta1.ts b/src/pepr/operator/crd/generated/istio/virtualservice-v1beta1.ts similarity index 100% rename from src/operator/crd/generated/istio/virtualservice-v1beta1.ts rename to src/pepr/operator/crd/generated/istio/virtualservice-v1beta1.ts diff --git a/src/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts similarity index 100% rename from src/operator/crd/generated/package-v1alpha1.ts rename to src/pepr/operator/crd/generated/package-v1alpha1.ts diff --git a/src/operator/crd/index.ts b/src/pepr/operator/crd/index.ts similarity index 100% rename from src/operator/crd/index.ts rename to src/pepr/operator/crd/index.ts diff --git a/src/operator/crd/register.ts b/src/pepr/operator/crd/register.ts similarity index 100% rename from src/operator/crd/register.ts rename to src/pepr/operator/crd/register.ts diff --git a/src/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts similarity index 100% rename from src/operator/crd/sources/v1alpha1.ts rename to src/pepr/operator/crd/sources/v1alpha1.ts diff --git a/src/operator/index.ts b/src/pepr/operator/index.ts similarity index 77% rename from src/operator/index.ts rename to src/pepr/operator/index.ts index 4b21f0a3b..d96b66170 100644 --- a/src/operator/index.ts +++ b/src/pepr/operator/index.ts @@ -5,6 +5,7 @@ import "./crd/register"; import { virtualService } from "./istio"; import { syncNamespace } from "./namespace"; import { networkPolicies } from "./network"; +import { UDSConfig } from "../config"; export const operator = new Capability({ name: "uds-core-operator", @@ -29,7 +30,12 @@ When(UDSPackage) await networkPolicies(pkg, namespace); - await virtualService(pkg, namespace); + // Only configure the VirtualService if Istio is installed + if (UDSConfig.istioInstalled) { + await virtualService(pkg, namespace); + } else { + Log.warn(`Istio is not installed, skipping ${pkg.metadata.name} VirtualService.`); + } } catch (e) { Log.error( e, diff --git a/src/operator/istio.ts b/src/pepr/operator/istio.ts similarity index 87% rename from src/operator/istio.ts rename to src/pepr/operator/istio.ts index 9130464e8..05261dd94 100644 --- a/src/operator/istio.ts +++ b/src/pepr/operator/istio.ts @@ -1,8 +1,8 @@ import { K8s, Log } from "pepr"; import { V1OwnerReference } from "@kubernetes/client-node"; -import { UDSConfig } from "./config"; -import { UDSPackage } from "./crd"; +import { UDSConfig } from "../config"; +import { Gateway, UDSPackage } from "./crd"; import { HTTPRoute, TCPRoute, VirtualService } from "./crd/generated/istio/virtualservice-v1beta1"; /** @@ -43,6 +43,9 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { }, ]; + // For the admin gateway, we need to add the path prefix + const domain = (gateway === Gateway.Admin ? "admin." : "") + UDSConfig.domain; + const payload: VirtualService = { metadata: { name, @@ -51,7 +54,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { }, spec: { // Use the global DNS domain for the host - hosts: [`${host}.${UDSConfig.domain}`], + hosts: [`${host}.${domain}`], // Map the gateway (admin, passthrough or tenant) to the VirtualService gateways: [`istio-${gateway}-gateway/${gateway}-gateway`], }, diff --git a/src/operator/namespace.ts b/src/pepr/operator/namespace.ts similarity index 100% rename from src/operator/namespace.ts rename to src/pepr/operator/namespace.ts diff --git a/src/operator/network/README.md b/src/pepr/operator/network/README.md similarity index 100% rename from src/operator/network/README.md rename to src/pepr/operator/network/README.md diff --git a/src/operator/network/allow-egress-dns.ts b/src/pepr/operator/network/allow-egress-dns.ts similarity index 100% rename from src/operator/network/allow-egress-dns.ts rename to src/pepr/operator/network/allow-egress-dns.ts diff --git a/src/operator/network/allow-egress-istiod.ts b/src/pepr/operator/network/allow-egress-istiod.ts similarity index 100% rename from src/operator/network/allow-egress-istiod.ts rename to src/pepr/operator/network/allow-egress-istiod.ts diff --git a/src/operator/network/allow-egress-within-ns.ts b/src/pepr/operator/network/allow-egress-within-ns.ts similarity index 100% rename from src/operator/network/allow-egress-within-ns.ts rename to src/pepr/operator/network/allow-egress-within-ns.ts diff --git a/src/operator/network/allow-ingress-sidecar-monitoring.ts b/src/pepr/operator/network/allow-ingress-sidecar-monitoring.ts similarity index 100% rename from src/operator/network/allow-ingress-sidecar-monitoring.ts rename to src/pepr/operator/network/allow-ingress-sidecar-monitoring.ts diff --git a/src/operator/network/allow-ingress-within-ns.ts b/src/pepr/operator/network/allow-ingress-within-ns.ts similarity index 100% rename from src/operator/network/allow-ingress-within-ns.ts rename to src/pepr/operator/network/allow-ingress-within-ns.ts diff --git a/src/operator/network/builder.ts b/src/pepr/operator/network/builder.ts similarity index 100% rename from src/operator/network/builder.ts rename to src/pepr/operator/network/builder.ts diff --git a/src/operator/network/default-deny-all.ts b/src/pepr/operator/network/default-deny-all.ts similarity index 100% rename from src/operator/network/default-deny-all.ts rename to src/pepr/operator/network/default-deny-all.ts diff --git a/src/operator/network/index.ts b/src/pepr/operator/network/index.ts similarity index 100% rename from src/operator/network/index.ts rename to src/pepr/operator/network/index.ts diff --git a/src/operator/network/transforms.ts b/src/pepr/operator/network/transforms.ts similarity index 100% rename from src/operator/network/transforms.ts rename to src/pepr/operator/network/transforms.ts diff --git a/src/operator/test.ts b/src/pepr/operator/test.ts similarity index 100% rename from src/operator/test.ts rename to src/pepr/operator/test.ts diff --git a/src/policies/README.md b/src/pepr/policies/README.md similarity index 100% rename from src/policies/README.md rename to src/pepr/policies/README.md diff --git a/src/policies/common.ts b/src/pepr/policies/common.ts similarity index 100% rename from src/policies/common.ts rename to src/pepr/policies/common.ts diff --git a/src/policies/exemptions/index.ts b/src/pepr/policies/exemptions/index.ts similarity index 100% rename from src/policies/exemptions/index.ts rename to src/pepr/policies/exemptions/index.ts diff --git a/src/policies/exemptions/matchers.ts b/src/pepr/policies/exemptions/matchers.ts similarity index 100% rename from src/policies/exemptions/matchers.ts rename to src/pepr/policies/exemptions/matchers.ts diff --git a/src/policies/exemptions/networking.ts b/src/pepr/policies/exemptions/networking.ts similarity index 100% rename from src/policies/exemptions/networking.ts rename to src/pepr/policies/exemptions/networking.ts diff --git a/src/policies/exemptions/security.ts b/src/pepr/policies/exemptions/security.ts similarity index 100% rename from src/policies/exemptions/security.ts rename to src/pepr/policies/exemptions/security.ts diff --git a/src/policies/exemptions/storage.ts b/src/pepr/policies/exemptions/storage.ts similarity index 100% rename from src/policies/exemptions/storage.ts rename to src/pepr/policies/exemptions/storage.ts diff --git a/src/policies/index.ts b/src/pepr/policies/index.ts similarity index 100% rename from src/policies/index.ts rename to src/pepr/policies/index.ts diff --git a/src/policies/network.spec.ts b/src/pepr/policies/network.spec.ts similarity index 100% rename from src/policies/network.spec.ts rename to src/pepr/policies/network.spec.ts diff --git a/src/policies/networking.ts b/src/pepr/policies/networking.ts similarity index 100% rename from src/policies/networking.ts rename to src/pepr/policies/networking.ts diff --git a/src/policies/security.spec.ts b/src/pepr/policies/security.spec.ts similarity index 100% rename from src/policies/security.spec.ts rename to src/pepr/policies/security.spec.ts diff --git a/src/policies/security.ts b/src/pepr/policies/security.ts similarity index 100% rename from src/policies/security.ts rename to src/pepr/policies/security.ts diff --git a/src/policies/storage.spec.ts b/src/pepr/policies/storage.spec.ts similarity index 100% rename from src/policies/storage.spec.ts rename to src/pepr/policies/storage.spec.ts diff --git a/src/policies/storage.ts b/src/pepr/policies/storage.ts similarity index 100% rename from src/policies/storage.ts rename to src/pepr/policies/storage.ts diff --git a/src/operator/tasks.yaml b/src/pepr/tasks.yaml similarity index 67% rename from src/operator/tasks.yaml rename to src/pepr/tasks.yaml index 785be58c9..eb926a3ea 100644 --- a/src/operator/tasks.yaml +++ b/src/pepr/tasks.yaml @@ -1,15 +1,15 @@ tasks: - name: validate actions: - - cmd: "npx jest src/operator/**/*.spec.ts" + - cmd: "npx jest src/pepr/**/*.spec.ts" - name: gen-crds description: "Generate CRDS, requires a running kubernetes cluster" actions: - - cmd: "npx ts-node src/operator/crd/register.ts" + - cmd: "npx ts-node src/pepr/operator/crd/register.ts" env: - "PEPR_WATCH_MODE=true" - - cmd: "npx kubernetes-fluent-client crd packages.uds.dev src/operator/crd/generated" + - cmd: "npx kubernetes-fluent-client crd packages.uds.dev src/pepr/operator/crd/generated" - cmd: "npx pepr format" diff --git a/src/policies/tasks.yaml b/src/policies/tasks.yaml deleted file mode 100644 index 6f8456bb0..000000000 --- a/src/policies/tasks.yaml +++ /dev/null @@ -1,4 +0,0 @@ -tasks: - - name: validate - actions: - - cmd: "npx jest src/policies/**/*.spec.ts" diff --git a/tasks/create.yaml b/tasks/create.yaml index 9c77c90d3..5e8cbf6c6 100644 --- a/tasks/create.yaml +++ b/tasks/create.yaml @@ -33,7 +33,7 @@ tasks: - task: pepr-build - description: "Create the Pepr Zarf Package, if it exists" - cmd: "zarf package create dist --confirm || echo 'Pepr build not required'" + cmd: "zarf package create dist --confirm" - description: "Create the requested Zarf Package (must set UDS_PKG environment variable)" cmd: "zarf package create src/${UDS_PKG} --confirm" @@ -46,4 +46,4 @@ tasks: set -e rm -fr dist npm ci - npx pepr build || echo "Pepr build not required" + npx pepr build From bd43cd863d4c294907824d8b5b31b574e7e8a142 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 18 Dec 2023 09:48:15 -0600 Subject: [PATCH 04/98] I hate you prettier --- src/metrics-server/chart/templates/uds-package.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metrics-server/chart/templates/uds-package.yaml b/src/metrics-server/chart/templates/uds-package.yaml index 960a2accf..2608bf83e 100644 --- a/src/metrics-server/chart/templates/uds-package.yaml +++ b/src/metrics-server/chart/templates/uds-package.yaml @@ -2,4 +2,4 @@ apiVersion: uds.dev/v1alpha1 kind: Package metadata: name: metrics-server - namespace: { { .Release.Namespace } } + namespace: {{ .Release.Namespace }} From 479eec51fdaf16485dab2b55a0ec5d2a9f1844d5 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 18 Dec 2023 10:30:40 -0600 Subject: [PATCH 05/98] fix neuvector service name --- src/neuvector/chart/templates/uds-package.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml index 9b17a6861..a23c55ac8 100644 --- a/src/neuvector/chart/templates/uds-package.yaml +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -6,7 +6,7 @@ metadata: spec: network: expose: - - service: uds-neuvector-service-webui + - service: neuvector-service-webui gateway: admin host: neuvector port: 8443 From 2e621d1b81e2189d51bf1de8250b113610634825 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 18 Dec 2023 10:31:25 -0600 Subject: [PATCH 06/98] add `name` prop for expose to avoid creating extra VS on service name changes --- src/pepr/operator/crd/generated/package-v1alpha1.ts | 8 ++++++-- src/pepr/operator/crd/sources/v1alpha1.ts | 6 +++++- src/pepr/operator/istio.ts | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index dfa8fd716..161a8562f 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -38,9 +38,13 @@ export interface Expose { */ host: string; /** - * The mode to expose the service on + * The mode to use when exposing the service */ mode?: Mode; + /** + * The unique name to use as the VirtualService name + */ + name: string; /** * The port number to expose */ @@ -61,7 +65,7 @@ export enum Gateway { } /** - * The mode to expose the service on + * The mode to use when exposing the service */ export enum Mode { HTTP = "http", diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index c34356d08..46757f54e 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -26,8 +26,12 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { description: "Expose a service on an Istio Gateway", items: { type: "object", - required: ["service", "port", "gateway", "host"], + required: ["name", "service", "port", "gateway", "host"], properties: { + name: { + description: "The unique name to use as the VirtualService name", + type: "string", + }, service: { description: "The name of the service to expose", type: "string", diff --git a/src/pepr/operator/istio.ts b/src/pepr/operator/istio.ts index 05261dd94..06bcc09e0 100644 --- a/src/pepr/operator/istio.ts +++ b/src/pepr/operator/istio.ts @@ -27,9 +27,9 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { for (const expose of pkg.spec?.network?.expose ?? []) { const { gateway, host, port, service, mode } = expose; - // Use the package name + service name as the VirtualService name + // Use the package name + unique name as the VirtualService name // This ensures we don't accidentally expose the same service multiple times - const name = `${pkgName}-${service}`; + const name = `${pkgName}-${expose.name}`; // Create the route to the service const route: TCPRoute[] | HTTPRoute[] = [ From c14adc18055e54dd2f641958a504e98e82c561de Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 18 Dec 2023 10:31:34 -0600 Subject: [PATCH 07/98] add initial CRD validator --- src/pepr/operator/crd/validator.ts | 28 ++++++++++++++++++++++++++++ src/pepr/operator/index.ts | 4 +++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/pepr/operator/crd/validator.ts diff --git a/src/pepr/operator/crd/validator.ts b/src/pepr/operator/crd/validator.ts new file mode 100644 index 000000000..7bc13b77b --- /dev/null +++ b/src/pepr/operator/crd/validator.ts @@ -0,0 +1,28 @@ +import { PeprValidateRequest } from "pepr"; +import { UDSPackage } from "."; + +const invalidNamespaces = ["kube-system", "kube-public", "invalid", "pepr-system"]; + +export async function validator(req: PeprValidateRequest) { + const ns = req.Raw.metadata?.namespace ?? "invalid"; + + if (invalidNamespaces.includes(ns)) { + return req.Deny("invalid namespace"); + } + + // Ensure the name of each expose is unique + const expose = req.Raw.spec?.network?.expose ?? []; + const uniqueNames = new Set(expose.map(e => e.name)); + if (uniqueNames.size !== expose.length) { + return req.Deny("expose.name must be unique"); + } + + // Ensure the name of each network policy is unique + const networkPolicy = req.Raw.spec?.network?.policies?.allow ?? []; + const uniquePolicyNames = new Set(networkPolicy.map(e => e.name)); + if (uniquePolicyNames.size !== networkPolicy.length) { + return req.Deny("networkPolicy.name must be unique"); + } + + return req.Approve(); +} diff --git a/src/pepr/operator/index.ts b/src/pepr/operator/index.ts index d96b66170..2fae32c81 100644 --- a/src/pepr/operator/index.ts +++ b/src/pepr/operator/index.ts @@ -1,11 +1,12 @@ import { Capability, Log } from "pepr"; +import { UDSConfig } from "../config"; import { UDSPackage } from "./crd"; import "./crd/register"; +import { validator } from "./crd/validator"; import { virtualService } from "./istio"; import { syncNamespace } from "./namespace"; import { networkPolicies } from "./network"; -import { UDSConfig } from "../config"; export const operator = new Capability({ name: "uds-core-operator", @@ -16,6 +17,7 @@ export const { Store, When } = operator; When(UDSPackage) .IsCreatedOrUpdated() + .Validate(validator) .Watch(async pkg => { if (!pkg.metadata?.namespace) { Log.error(pkg, `Invalid Package definition`); From f50f31c725e00f3721a6701868fe46eed86958a2 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 18 Dec 2023 10:39:30 -0600 Subject: [PATCH 08/98] update pkg for new required name field --- src/grafana/chart/templates/uds-package.yaml | 3 ++- src/neuvector/chart/templates/uds-package.yaml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index ba6170601..0d9648b89 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -6,7 +6,8 @@ metadata: spec: network: expose: - - service: grafana + - name: grafana-ui + service: grafana gateway: admin host: grafana port: 80 diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml index a23c55ac8..edc506d58 100644 --- a/src/neuvector/chart/templates/uds-package.yaml +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -6,7 +6,8 @@ metadata: spec: network: expose: - - service: neuvector-service-webui + - name: neuvector-dashboard + service: neuvector-service-webui gateway: admin host: neuvector port: 8443 From 821e8db98ca8463d589d4f5f38bb1d915c977693 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 18 Dec 2023 11:18:23 -0600 Subject: [PATCH 09/98] update test package to use CRD --- src/test/app-admin.yaml | 19 ++++++++++++++----- src/test/app-tenant.yaml | 15 ++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/test/app-admin.yaml b/src/test/app-admin.yaml index e499a73a9..ab11750d1 100644 --- a/src/test/app-admin.yaml +++ b/src/test/app-admin.yaml @@ -16,11 +16,6 @@ kind: Service metadata: name: httpbin namespace: test-admin-app - labels: - app: httpbin - service: httpbin - uds/istio-gateway: admin - uds/istio-host: demo spec: ports: - name: http @@ -29,6 +24,20 @@ spec: selector: app: httpbin --- +apiVersion: uds.dev/v1alpha1 +kind: Package +metadata: + name: httpbin + namespace: test-admin-app +spec: + network: + expose: + - name: httpbin + service: httpbin + gateway: admin + host: demo + port: 8000 +--- apiVersion: apps/v1 kind: Deployment metadata: diff --git a/src/test/app-tenant.yaml b/src/test/app-tenant.yaml index 65e31c3d4..6f57daa61 100644 --- a/src/test/app-tenant.yaml +++ b/src/test/app-tenant.yaml @@ -27,14 +27,19 @@ spec: selector: app: httpbin --- -apiVersion: v1 -kind: ConfigMap +apiVersion: uds.dev/v1alpha1 +kind: Package metadata: name: httpbin namespace: test-app - labels: - "uds/istio-gateway": "tenant" - "uds/istio-host": "demo" +spec: + network: + expose: + - name: httpbin + service: httpbin + gateway: tenant + host: demo + port: 8000 --- apiVersion: apps/v1 kind: Deployment From a1e08e41c416f7dafe86ca40b5c288d04e606215 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 21 Dec 2023 15:53:12 -0600 Subject: [PATCH 10/98] allow simpler operator config + add real API server netpol --- package-lock.json | 415 ++++++++++-------- package.json | 5 +- src/grafana/chart/templates/uds-package.yaml | 21 +- src/loki/chart/templates/uds-package.yaml | 15 +- .../chart/templates/uds-package.yaml | 16 + .../network-policies/egress-kube-api.yaml | 38 -- .../network-policies/namespace-allow.yaml | 17 - .../chart/templates/uds-package.yaml | 12 + .../crd/generated/package-v1alpha1.ts | 60 +-- src/pepr/operator/crd/sources/v1alpha1.ts | 60 ++- src/pepr/operator/crd/validator.ts | 9 + src/pepr/operator/istio.ts | 10 +- src/pepr/operator/network/builder.ts | 95 +++- src/pepr/operator/network/index.ts | 4 +- src/pepr/operator/network/transforms.ts | 59 --- src/pepr/operator/test.ts | 8 +- tasks/deploy.yaml | 9 +- test.yaml | 27 ++ 18 files changed, 450 insertions(+), 430 deletions(-) delete mode 100644 src/neuvector/chart/templates/network-policies/egress-kube-api.yaml delete mode 100644 src/neuvector/chart/templates/network-policies/namespace-allow.yaml delete mode 100644 src/pepr/operator/network/transforms.ts create mode 100644 test.yaml diff --git a/package-lock.json b/package-lock.json index 687c0eb46..e4360164d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,12 @@ "name": "uds-core", "version": "0.2.0", "dependencies": { - "pepr": "0.20.1" + "pepr": "0.20.2" }, "devDependencies": { "@jest/globals": "29.7.0", "jest": "29.7.0", - "ts-jest": "29.1.1", - "typescript": "5.2.2" + "ts-jest": "29.1.1" }, "engines": { "node": ">=18.0.0" @@ -691,10 +690,26 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", + "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.4.tgz", - "integrity": "sha512-uBIbiYMeSsy2U0XQoOGVVcpIktjLMEKa7ryz2RLr7L/vTnANNEsPVAh4xOv7ondGz6ac1zVb0F8Jx20rQikffQ==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", + "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", "cpu": [ "arm" ], @@ -708,9 +723,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.4.tgz", - "integrity": "sha512-mRsi2vJsk4Bx/AFsNBqOH2fqedxn5L/moT58xgg51DjX1la64Z3Npicut2VbhvDFO26qjWtPMsVxCd80YTFVeg==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", + "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", "cpu": [ "arm64" ], @@ -724,9 +739,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.4.tgz", - "integrity": "sha512-4iPufZ1TMOD3oBlGFqHXBpa3KFT46aLl6Vy7gwed0ZSYgHaZ/mihbYb4t7Z9etjkC9Al3ZYIoOaHrU60gcMy7g==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", + "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", "cpu": [ "x64" ], @@ -740,9 +755,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.4.tgz", - "integrity": "sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", + "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", "cpu": [ "arm64" ], @@ -756,9 +771,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.4.tgz", - "integrity": "sha512-YHbSFlLgDwglFn0lAO3Zsdrife9jcQXQhgRp77YiTDja23FrC2uwnhXMNkAucthsf+Psr7sTwYEryxz6FPAVqw==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", + "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", "cpu": [ "x64" ], @@ -772,9 +787,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.4.tgz", - "integrity": "sha512-vz59ijyrTG22Hshaj620e5yhs2dU1WJy723ofc+KUgxVCM6zxQESmWdMuVmUzxtGqtj5heHyB44PjV/HKsEmuQ==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", + "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", "cpu": [ "arm64" ], @@ -788,9 +803,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.4.tgz", - "integrity": "sha512-3sRbQ6W5kAiVQRBWREGJNd1YE7OgzS0AmOGjDmX/qZZecq8NFlQsQH0IfXjjmD0XtUYqr64e0EKNFjMUlPL3Cw==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", + "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", "cpu": [ "x64" ], @@ -804,9 +819,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.4.tgz", - "integrity": "sha512-z/4ArqOo9EImzTi4b6Vq+pthLnepFzJ92BnofU1jgNlcVb+UqynVFdoXMCFreTK7FdhqAzH0vmdwW5373Hm9pg==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", + "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", "cpu": [ "arm" ], @@ -820,9 +835,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.4.tgz", - "integrity": "sha512-ZWmWORaPbsPwmyu7eIEATFlaqm0QGt+joRE9sKcnVUG3oBbr/KYdNE2TnkzdQwX6EDRdg/x8Q4EZQTXoClUqqA==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", + "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", "cpu": [ "arm64" ], @@ -836,9 +851,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.4.tgz", - "integrity": "sha512-EGc4vYM7i1GRUIMqRZNCTzJh25MHePYsnQfKDexD8uPTCm9mK56NIL04LUfX2aaJ+C9vyEp2fJ7jbqFEYgO9lQ==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", + "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", "cpu": [ "ia32" ], @@ -852,9 +867,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.4.tgz", - "integrity": "sha512-WVhIKO26kmm8lPmNrUikxSpXcgd6HDog0cx12BUfA2PkmURHSgx9G6vA19lrlQOMw+UjMZ+l3PpbtzffCxFDRg==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", + "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", "cpu": [ "loong64" ], @@ -868,9 +883,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.4.tgz", - "integrity": "sha512-keYY+Hlj5w86hNp5JJPuZNbvW4jql7c1eXdBUHIJGTeN/+0QFutU3GrS+c27L+NTmzi73yhtojHk+lr2+502Mw==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", + "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", "cpu": [ "mips64el" ], @@ -884,9 +899,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.4.tgz", - "integrity": "sha512-tQ92n0WMXyEsCH4m32S21fND8VxNiVazUbU4IUGVXQpWiaAxOBvtOtbEt3cXIV3GEBydYsY8pyeRMJx9kn3rvw==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", + "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", "cpu": [ "ppc64" ], @@ -900,9 +915,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.4.tgz", - "integrity": "sha512-tRRBey6fG9tqGH6V75xH3lFPpj9E8BH+N+zjSUCnFOX93kEzqS0WdyJHkta/mmJHn7MBaa++9P4ARiU4ykjhig==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", + "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", "cpu": [ "riscv64" ], @@ -916,9 +931,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.4.tgz", - "integrity": "sha512-152aLpQqKZYhThiJ+uAM4PcuLCAOxDsCekIbnGzPKVBRUDlgaaAfaUl5NYkB1hgY6WN4sPkejxKlANgVcGl9Qg==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", + "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", "cpu": [ "s390x" ], @@ -932,9 +947,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.4.tgz", - "integrity": "sha512-Mi4aNA3rz1BNFtB7aGadMD0MavmzuuXNTaYL6/uiYIs08U7YMPETpgNn5oue3ICr+inKwItOwSsJDYkrE9ekVg==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", + "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", "cpu": [ "x64" ], @@ -948,9 +963,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.4.tgz", - "integrity": "sha512-9+Wxx1i5N/CYo505CTT7T+ix4lVzEdz0uCoYGxM5JDVlP2YdDC1Bdz+Khv6IbqmisT0Si928eAxbmGkcbiuM/A==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", + "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", "cpu": [ "x64" ], @@ -964,9 +979,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.4.tgz", - "integrity": "sha512-MFsHleM5/rWRW9EivFssop+OulYVUoVcqkyOkjiynKBCGBj9Lihl7kh9IzrreDyXa4sNkquei5/DTP4uCk25xw==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", + "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", "cpu": [ "x64" ], @@ -980,9 +995,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.4.tgz", - "integrity": "sha512-6Xq8SpK46yLvrGxjp6HftkDwPP49puU4OF0hEL4dTxqCbfx09LyrbUj/D7tmIRMj5D5FCUPksBbxyQhp8tmHzw==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", + "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", "cpu": [ "x64" ], @@ -996,9 +1011,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.4.tgz", - "integrity": "sha512-PkIl7Jq4mP6ke7QKwyg4fD4Xvn8PXisagV/+HntWoDEdmerB2LTukRZg728Yd1Fj+LuEX75t/hKXE2Ppk8Hh1w==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", + "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", "cpu": [ "arm64" ], @@ -1012,9 +1027,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.4.tgz", - "integrity": "sha512-ga676Hnvw7/ycdKB53qPusvsKdwrWzEyJ+AtItHGoARszIqvjffTwaaW3b2L6l90i7MO9i+dlAW415INuRhSGg==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", + "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", "cpu": [ "ia32" ], @@ -1028,9 +1043,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.4.tgz", - "integrity": "sha512-HP0GDNla1T3ZL8Ko/SHAS2GgtjOg+VmWnnYLhuTksr++EnduYB0f3Y2LzHsUwb2iQ13JGoY6G3R8h6Du/WG6uA==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", + "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", "cpu": [ "x64" ], @@ -1091,9 +1106,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", - "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1840,16 +1855,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", - "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.15.0.tgz", + "integrity": "sha512-j5qoikQqPccq9QoBAupOP+CBu8BaJ8BLjaXSioDISeTZkVO3ig7oSIKh3H+rEpee7xCXtWwSB4KIL5l6hWZzpg==", "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/type-utils": "6.7.3", - "@typescript-eslint/utils": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/type-utils": "6.15.0", + "@typescript-eslint/utils": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1875,15 +1890,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", - "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.15.0.tgz", + "integrity": "sha512-MkgKNnsjC6QwcMdlNAel24jjkEO/0hQaMDLqP4S9zq5HBAUJNQB6y+3DwLjX7b3l2b37eNAxMPLwb3/kh8VKdA==", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", "debug": "^4.3.4" }, "engines": { @@ -1903,13 +1918,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", - "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.15.0.tgz", + "integrity": "sha512-+BdvxYBltqrmgCNu4Li+fGDIkW9n//NrruzG9X1vBzaNK+ExVXPoGB71kneaVw/Jp+4rH/vaMAGC6JfMbHstVg==", "peer": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3" + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1920,13 +1935,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", - "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.15.0.tgz", + "integrity": "sha512-CnmHKTfX6450Bo49hPg2OkIm/D/TVYV7jO1MCfPYGwf6x3GO0VU8YMO5AYMn+u3X05lRRxA4fWCz87GFQV6yVQ==", "peer": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/utils": "6.15.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1947,9 +1962,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", - "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.15.0.tgz", + "integrity": "sha512-yXjbt//E4T/ee8Ia1b5mGlbNj9fB9lJP4jqLbZualwpP2BCQ5is6BcWwxpIsY4XKAhmdv3hrW92GdtJbatC6dQ==", "peer": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1960,13 +1975,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", - "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.15.0.tgz", + "integrity": "sha512-7mVZJN7Hd15OmGuWrp2T9UvqR2Ecg+1j/Bp1jXUEY2GZKV6FXlOIoqVDmLpBiEiq3katvj/2n2mR0SDwtloCew==", "peer": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1987,17 +2002,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", - "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.15.0.tgz", + "integrity": "sha512-eF82p0Wrrlt8fQSRL0bGXzK5nWPRV2dYQZdajcfzOD9+cQz9O7ugifrJxclB+xVOvWvagXfqS4Es7vpLP4augw==", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", "semver": "^7.5.4" }, "engines": { @@ -2012,12 +2027,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", - "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.15.0.tgz", + "integrity": "sha512-1zvtdC1a9h5Tb5jU9x3ADNXO9yjP8rXlaoChu0DQX40vf5ACVpYIVIZhIMZ6d5sDXH7vq4dsZBT1fEGj8D2n2w==", "peer": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/types": "6.15.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -2028,6 +2043,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "peer": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -2517,9 +2538,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001570", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", - "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "version": "1.0.30001571", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz", + "integrity": "sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ==", "dev": true, "funding": [ { @@ -2656,9 +2677,9 @@ } }, "node_modules/commander": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", - "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "peer": true, "engines": { "node": ">=16" @@ -2888,9 +2909,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.614", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", - "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", + "version": "1.4.615", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", + "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", "dev": true }, "node_modules/emittery": { @@ -2936,9 +2957,9 @@ } }, "node_modules/esbuild": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.4.tgz", - "integrity": "sha512-x7jL0tbRRpv4QUyuDMjONtWFciygUxWaUM1kMX2zWxI0X2YWOt7MSA0g4UdeSiHM8fcYVzpQhKYOycZwxTdZkA==", + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", + "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", "hasInstallScript": true, "peer": true, "bin": { @@ -2948,28 +2969,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.19.4", - "@esbuild/android-arm64": "0.19.4", - "@esbuild/android-x64": "0.19.4", - "@esbuild/darwin-arm64": "0.19.4", - "@esbuild/darwin-x64": "0.19.4", - "@esbuild/freebsd-arm64": "0.19.4", - "@esbuild/freebsd-x64": "0.19.4", - "@esbuild/linux-arm": "0.19.4", - "@esbuild/linux-arm64": "0.19.4", - "@esbuild/linux-ia32": "0.19.4", - "@esbuild/linux-loong64": "0.19.4", - "@esbuild/linux-mips64el": "0.19.4", - "@esbuild/linux-ppc64": "0.19.4", - "@esbuild/linux-riscv64": "0.19.4", - "@esbuild/linux-s390x": "0.19.4", - "@esbuild/linux-x64": "0.19.4", - "@esbuild/netbsd-x64": "0.19.4", - "@esbuild/openbsd-x64": "0.19.4", - "@esbuild/sunos-x64": "0.19.4", - "@esbuild/win32-arm64": "0.19.4", - "@esbuild/win32-ia32": "0.19.4", - "@esbuild/win32-x64": "0.19.4" + "@esbuild/aix-ppc64": "0.19.10", + "@esbuild/android-arm": "0.19.10", + "@esbuild/android-arm64": "0.19.10", + "@esbuild/android-x64": "0.19.10", + "@esbuild/darwin-arm64": "0.19.10", + "@esbuild/darwin-x64": "0.19.10", + "@esbuild/freebsd-arm64": "0.19.10", + "@esbuild/freebsd-x64": "0.19.10", + "@esbuild/linux-arm": "0.19.10", + "@esbuild/linux-arm64": "0.19.10", + "@esbuild/linux-ia32": "0.19.10", + "@esbuild/linux-loong64": "0.19.10", + "@esbuild/linux-mips64el": "0.19.10", + "@esbuild/linux-ppc64": "0.19.10", + "@esbuild/linux-riscv64": "0.19.10", + "@esbuild/linux-s390x": "0.19.10", + "@esbuild/linux-x64": "0.19.10", + "@esbuild/netbsd-x64": "0.19.10", + "@esbuild/openbsd-x64": "0.19.10", + "@esbuild/sunos-x64": "0.19.10", + "@esbuild/win32-arm64": "0.19.10", + "@esbuild/win32-ia32": "0.19.10", + "@esbuild/win32-x64": "0.19.10" } }, "node_modules/escalade": { @@ -2998,18 +3020,19 @@ } }, "node_modules/eslint": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", - "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.50.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -3346,9 +3369,9 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "peer": true, "dependencies": { "reusify": "^1.0.4" @@ -4708,9 +4731,9 @@ } }, "node_modules/kubernetes-fluent-client": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/kubernetes-fluent-client/-/kubernetes-fluent-client-1.9.0.tgz", - "integrity": "sha512-MbR4stfoaj4gB+JcrYk6vBZzWrTWRnD9iX1JfVRo7sXQpoknPcsm/9YvLeRLblXtvuGOzE3vZZ21MOGQ3+creA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/kubernetes-fluent-client/-/kubernetes-fluent-client-1.10.0.tgz", + "integrity": "sha512-jkLCc10eKplU0VUEouIMgQYhpn1O3lcan7dX4TPwAT8g0anrH97XcL8FXOHerGYKizq3KDNjRnPkRpBZwlJFfw==", "dependencies": { "@kubernetes/client-node": "1.0.0-rc3", "byline": "5.0.0", @@ -4718,7 +4741,7 @@ "http-status-codes": "2.3.0", "node-fetch": "2.7.0", "quicktype-core": "23.0.80", - "type-fest": "4.8.2", + "type-fest": "4.8.3", "yargs": "17.7.2" }, "bin": { @@ -4729,9 +4752,9 @@ } }, "node_modules/kubernetes-fluent-client/node_modules/type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.3.tgz", + "integrity": "sha512-//BaTm14Q/gHBn09xlnKNqfI8t6bmdzx2DXYfPBNofN0WUybCEUDcbCWcTa0oF09lzLjZgPphXAsvRiMK0V6Bw==", "engines": { "node": ">=16" }, @@ -5309,17 +5332,17 @@ } }, "node_modules/pepr": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.20.1.tgz", - "integrity": "sha512-Im0Qi7a96dFmvKL792XlbfFXq7QmFrfDHi/JL/vYIlrU4+H6iCfe7j3jT2TPCKe4wGItTPV2aR+h6+Zrri5WMQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.20.2.tgz", + "integrity": "sha512-N6adF/KZPpObmBzGLlQhZbnU6p4/H57XIju1MBoiKkqUxvt6+pf25GI+dMu9Jx2UtbfHkNVD/RPzrTrQTQVPpQ==", "dependencies": { "@types/ramda": "0.29.9", "express": "4.18.2", "fast-json-patch": "3.1.1", - "kubernetes-fluent-client": "1.9.0", + "kubernetes-fluent-client": "1.10.0", "pino": "8.17.1", "pino-pretty": "10.3.0", - "prom-client": "15.0.0", + "prom-client": "15.1.0", "ramda": "0.29.1" }, "bin": { @@ -5329,15 +5352,15 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "6.7.3", - "@typescript-eslint/parser": "6.7.3", - "commander": "11.0.0", - "esbuild": "0.19.4", - "eslint": "8.50.0", + "@typescript-eslint/eslint-plugin": "6.15.0", + "@typescript-eslint/parser": "6.15.0", + "commander": "11.1.0", + "esbuild": "0.19.10", + "eslint": "8.56.0", "node-forge": "1.3.1", - "prettier": "3.0.3", + "prettier": "3.1.1", "prompts": "2.4.2", - "typescript": "5.2.2", + "typescript": "5.3.3", "uuid": "9.0.1" } }, @@ -5508,9 +5531,9 @@ } }, "node_modules/prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", "peer": true, "bin": { "prettier": "bin/prettier.cjs" @@ -5562,9 +5585,9 @@ "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==" }, "node_modules/prom-client": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.0.0.tgz", - "integrity": "sha512-UocpgIrKyA2TKLVZDSfm8rGkL13C19YrQBAiG3xo3aDFWcHedxRxI3z+cIcucoxpSO0h5lff5iv/SXoxyeopeA==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.0.tgz", + "integrity": "sha512-cCD7jLTqyPdjEPBo/Xk4Iu8jxjuZgZJ3e/oET3L+ZwOuap/7Cw3dH/TJSsZKs1TQLZ2IHpIlRAKw82ef06kmMw==", "dependencies": { "@opentelemetry/api": "^1.4.0", "tdigest": "^0.1.1" @@ -5697,6 +5720,21 @@ "yaml": "^2.3.1" } }, + "node_modules/quicktype-core/node_modules/readable-stream": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/ramda": { "version": "0.29.1", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.1.tgz", @@ -5735,9 +5773,9 @@ "dev": true }, "node_modules/readable-stream": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", - "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.1.tgz", + "integrity": "sha512-uQjbf34vmf/asGnOHQEw07Q4llgMACQZTWWa4MmICS0IKJoHbLwKCy71H3eR99Dw5iYejc6W+pqZZEeqRtUFAw==", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -6492,9 +6530,10 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index a95ee0ba9..3c2a710c4 100644 --- a/package.json +++ b/package.json @@ -32,13 +32,12 @@ "k3d-setup": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'" }, "dependencies": { - "pepr": "0.20.1" + "pepr": "0.20.2" }, "devDependencies": { "@jest/globals": "29.7.0", "jest": "29.7.0", - "ts-jest": "29.1.1", - "typescript": "5.2.2" + "ts-jest": "29.1.1" }, "jest": { "preset": "ts-jest", diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index 0d9648b89..a19dcd348 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -6,24 +6,19 @@ metadata: spec: network: expose: - - name: grafana-ui - service: grafana + - name: grafana gateway: admin - host: grafana port: 80 - + policies: allow: - name: tempo-ingress-writes direction: Ingress - podSelector: - matchLabels: - app: grafana - remoteNamespaceSelector: - matchLabels: - app.kubernetes.io/name: tempo - remotePodSelector: - matchLabels: - app.kubernetes.io/name: tempo + podLabels: + app: grafana + remoteNamespaceLabels: + app.kubernetes.io/name: tempo + remotePodLabels: + app.kubernetes.io/name: tempo port: 9090 protocol: TCP diff --git a/src/loki/chart/templates/uds-package.yaml b/src/loki/chart/templates/uds-package.yaml index 1dc5771bc..dafef8352 100644 --- a/src/loki/chart/templates/uds-package.yaml +++ b/src/loki/chart/templates/uds-package.yaml @@ -9,14 +9,11 @@ spec: allow: - name: tempo-ingress-writes direction: Ingress - podSelector: - matchLabels: - app: grafana - remoteNamespaceSelector: - matchLabels: - app.kubernetes.io/name: tempo - remotePodSelector: - matchLabels: - app.kubernetes.io/name: tempo + podLabels: + app: grafana + remoteNamespaceLabels: + app.kubernetes.io/name: tempo + remotePodLabels: + app.kubernetes.io/name: tempo port: 9090 protocol: TCP diff --git a/src/metrics-server/chart/templates/uds-package.yaml b/src/metrics-server/chart/templates/uds-package.yaml index 2608bf83e..ae96e7e22 100644 --- a/src/metrics-server/chart/templates/uds-package.yaml +++ b/src/metrics-server/chart/templates/uds-package.yaml @@ -3,3 +3,19 @@ kind: Package metadata: name: metrics-server namespace: {{ .Release.Namespace }} +spec: + network: + policies: + allow: + - name: kubeapi-egress + direction: Egress + remoteGenerated: KubeAPI + podLabels: + app.kubernetes.io/name: metrics-server + - name: istio-ingress + direction: Ingress + podLabels: + app.kubernetes.io/name: metrics-server + remoteNamespaceLabels: + kubernetes.io/metadata.name: "istio-system" + port: 443 diff --git a/src/neuvector/chart/templates/network-policies/egress-kube-api.yaml b/src/neuvector/chart/templates/network-policies/egress-kube-api.yaml deleted file mode 100644 index 53a0e2b95..000000000 --- a/src/neuvector/chart/templates/network-policies/egress-kube-api.yaml +++ /dev/null @@ -1,38 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: egress-kube-api-controller - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app: neuvector-controller-pod - egress: - - to: - - ipBlock: - cidr: "0.0.0.0/0" - # ONLY Block requests to cloud metadata IP - except: - - 169.254.169.254/32 - policyTypes: - - Egress ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: egress-kube-api-updater - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app: neuvector-updater-pod - egress: - - to: - - ipBlock: - cidr: "0.0.0.0/0" - # if 0.0.0.0/0 ONLY Block requests to cloud metadata IP - except: - - 169.254.169.254/32 - policyTypes: - - Egress - diff --git a/src/neuvector/chart/templates/network-policies/namespace-allow.yaml b/src/neuvector/chart/templates/network-policies/namespace-allow.yaml deleted file mode 100644 index 0b108d753..000000000 --- a/src/neuvector/chart/templates/network-policies/namespace-allow.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-in-ns - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Ingress - - Egress - ingress: - - from: - - podSelector: {} - egress: - - to: - - podSelector: {} - diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml index edc506d58..0e500867a 100644 --- a/src/neuvector/chart/templates/uds-package.yaml +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -11,3 +11,15 @@ spec: gateway: admin host: neuvector port: 8443 + policies: + allow: + - name: controller-kubeapi-egress + direction: Egress + remoteGenerated: KubeAPI + podLabels: + app: neuvector-controller-pod + - name: updater-kubeapi-egress + direction: Egress + remoteGenerated: KubeAPI + podLabels: + app: neuvector-updater-pod diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index 161a8562f..07e296dd0 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -30,13 +30,13 @@ export interface Network { export interface Expose { /** - * The name of the gateway to expose the service on + * The name of the gateway to expose the service on (default: tenant) */ - gateway: Gateway; + gateway?: Gateway; /** - * The hostname to expose the service on + * The hostname to expose the service on (default: name) */ - host: string; + host?: string; /** * The mode to use when exposing the service */ @@ -50,13 +50,13 @@ export interface Expose { */ port: number; /** - * The name of the service to expose + * The name of the service to expose (default: name) */ - service: string; + service?: string; } /** - * The name of the gateway to expose the service on + * The name of the gateway to expose the service on (default: tenant) */ export enum Gateway { Admin = "admin", @@ -100,9 +100,10 @@ export interface Allow { */ name: string; /** - * The local pod selector to apply the policy to + * Labels to match pods in the namespace to apply the policy to. Leave empty to apply to all + * pods in the namespace */ - podSelector: PodSelector; + podLabels?: { [key: string]: string }; /** * The port to allow */ @@ -112,13 +113,17 @@ export interface Allow { */ protocol?: Protocol; /** - * The remote namespace selector + * Custom generated remote selector for the policy */ - remoteNamespaceSelector?: RemoteNamespaceSelector; + remoteGenerated?: RemoteGenerated; /** - * The remote pod selector + * The remote namespace selector labels */ - remotePodSelector?: RemotePodSelector; + remoteNamespaceLabels?: { [key: string]: string }; + /** + * The remote pod selector labels + */ + remotePodLabels?: { [key: string]: string }; } /** @@ -129,16 +134,6 @@ export enum Direction { Ingress = "Ingress", } -/** - * The local pod selector to apply the policy to - */ -export interface PodSelector { - /** - * The labels to match - */ - matchLabels?: { [key: string]: string }; -} - /** * The protocol (TCP, UDP, or SCTP) to allow. Defaults to TCP. */ @@ -149,23 +144,10 @@ export enum Protocol { } /** - * The remote namespace selector + * Custom generated remote selector for the policy */ -export interface RemoteNamespaceSelector { - /** - * The labels to match - */ - matchLabels?: { [key: string]: string }; -} - -/** - * The remote pod selector - */ -export interface RemotePodSelector { - /** - * The labels to match - */ - matchLabels?: { [key: string]: string }; +export enum RemoteGenerated { + KubeAPI = "KubeAPI", } export enum DisableDefault { diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index 46757f54e..1bb8cc609 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -26,14 +26,14 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { description: "Expose a service on an Istio Gateway", items: { type: "object", - required: ["name", "service", "port", "gateway", "host"], + required: ["name", "port"], properties: { name: { description: "The unique name to use as the VirtualService name", type: "string", }, service: { - description: "The name of the service to expose", + description: "The name of the service to expose (default: name)", type: "string", }, port: { @@ -41,12 +41,14 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { type: "number", }, gateway: { - description: "The name of the gateway to expose the service on", + description: + "The name of the gateway to expose the service on (default: tenant)", enum: ["admin", "tenant", "passthrough"], type: "string", + default: "tenant", }, host: { - description: "The hostname to expose the service on", + description: "The hostname to expose the service on (default: name)", type: "string", }, mode: { @@ -75,7 +77,7 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { type: "array", items: { type: "object", - required: ["name", "direction", "podSelector"], + required: ["name", "direction"], properties: { name: { description: "The name of the policy", @@ -93,45 +95,33 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { enum: ["Ingress", "Egress"], type: "string", }, - podSelector: { - description: "The local pod selector to apply the policy to", + podLabels: { + description: + "Labels to match pods in the namespace to apply the policy to. Leave empty to apply to all pods in the namespace", type: "object", - properties: { - matchLabels: { - description: "The labels to match", - type: "object", - additionalProperties: { - type: "string", - }, - }, + additionalProperties: { + type: "string", }, }, - remoteNamespaceSelector: { - description: "The remote namespace selector", + remoteNamespaceLabels: { + description: "The remote namespace selector labels", type: "object", - properties: { - matchLabels: { - description: "The labels to match", - type: "object", - additionalProperties: { - type: "string", - }, - }, + additionalProperties: { + type: "string", }, }, - remotePodSelector: { - description: "The remote pod selector", + remotePodLabels: { + description: "The remote pod selector labels", type: "object", - properties: { - matchLabels: { - description: "The labels to match", - type: "object", - additionalProperties: { - type: "string", - }, - }, + additionalProperties: { + type: "string", }, }, + remoteGenerated: { + description: "Custom generated remote selector for the policy", + type: "string", + enum: ["KubeAPI"], + }, port: { description: "The port to allow", type: "number", diff --git a/src/pepr/operator/crd/validator.ts b/src/pepr/operator/crd/validator.ts index 7bc13b77b..0c72c32cb 100644 --- a/src/pepr/operator/crd/validator.ts +++ b/src/pepr/operator/crd/validator.ts @@ -24,5 +24,14 @@ export async function validator(req: PeprValidateRequest) { return req.Deny("networkPolicy.name must be unique"); } + for (const policy of networkPolicy) { + // remoteGenerated cannot be combined with remoteNamespaceLabels or remotePodLabels + if (policy.remoteGenerated && (policy.remoteNamespaceLabels || policy.remotePodLabels)) { + return req.Deny( + "remoteGenerated cannot be combined with remoteNamespaceLabels or remotePodLabels", + ); + } + } + return req.Approve(); } diff --git a/src/pepr/operator/istio.ts b/src/pepr/operator/istio.ts index 06bcc09e0..15918c8f1 100644 --- a/src/pepr/operator/istio.ts +++ b/src/pepr/operator/istio.ts @@ -25,7 +25,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { ]; for (const expose of pkg.spec?.network?.expose ?? []) { - const { gateway, host, port, service, mode } = expose; + const { gateway = Gateway.Tenant, host, port, service, mode } = expose; // Use the package name + unique name as the VirtualService name // This ensures we don't accidentally expose the same service multiple times @@ -35,8 +35,8 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { const route: TCPRoute[] | HTTPRoute[] = [ { destination: { - // Use the service name as the host - host: `${service}.${namespace}.svc.cluster.local`, + // Use the service name as the host if provide, otherwise use the expose name + host: `${service || expose.name}.${namespace}.svc.cluster.local`, // The CRD only uses numeric ports port: { number: port }, }, @@ -53,8 +53,8 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { ownerReferences, }, spec: { - // Use the global DNS domain for the host - hosts: [`${host}.${domain}`], + // Append the UDS Domain to the host. Use the expose name if no host is provided + hosts: [`${host || expose.name}.${domain}`], // Map the gateway (admin, passthrough or tenant) to the VirtualService gateways: [`istio-${gateway}-gateway/${gateway}-gateway`], }, diff --git a/src/pepr/operator/network/builder.ts b/src/pepr/operator/network/builder.ts index 03017d36a..fceb11a4d 100644 --- a/src/pepr/operator/network/builder.ts +++ b/src/pepr/operator/network/builder.ts @@ -1,9 +1,16 @@ -import { kind } from "pepr"; -import { V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; +import { V1APIGroup, V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; +import { K8s, Log, kind } from "pepr"; import { Allow, UDSPackage } from "../crd"; +import { RemoteGenerated } from "../crd/generated/package-v1alpha1"; -export function builder(namespace: string, pkg: UDSPackage, policy: Allow): kind.NetworkPolicy { +let apiServerPeers: V1NetworkPolicyPeer[]; + +export async function builder( + namespace: string, + pkg: UDSPackage, + policy: Allow, +): Promise { const pkgName = pkg.metadata!.name!; const name = `${pkgName}-${policy.name}`; @@ -21,15 +28,35 @@ export function builder(namespace: string, pkg: UDSPackage, policy: Allow): kind }, spec: { policyTypes: [policy.direction], - podSelector: policy.podSelector, + podSelector: { + matchLabels: policy.podLabels, + }, }, }; - // Create the remote (peer) to match against - const peer: V1NetworkPolicyPeer = { - namespaceSelector: policy.remoteNamespaceSelector, - podSelector: policy.remotePodSelector, - }; + // Create the remote (peer) to match against + let peers: V1NetworkPolicyPeer[]; + + // Check if remoteGenerated is set + switch (policy.remoteGenerated) { + // KubeAPI maps to the Kubernetes API server + case RemoteGenerated.KubeAPI: + peers = await generateKubeAPI(); + break; + + // Default to namespace and pod labels + default: + peers = [ + { + namespaceSelector: { + matchLabels: policy.remoteNamespaceLabels, + }, + podSelector: { + matchLabels: policy.remotePodLabels, + }, + }, + ]; + } // Create the port to match against const ports: V1NetworkPolicyPort[] = [ @@ -42,13 +69,59 @@ export function builder(namespace: string, pkg: UDSPackage, policy: Allow): kind // Add the ingress or egress rule switch (policy.direction) { case "Ingress": - generated.spec!.ingress = [{ from: [peer], ports }]; + generated.spec!.ingress = [{ from: peers, ports }]; break; case "Egress": - generated.spec!.egress = [{ to: [peer], ports }]; + generated.spec!.egress = [{ to: peers, ports }]; break; } return generated; } + +async function generateKubeAPI(): Promise { + // Return the cached value if it exists + // @todo: evaluate if this ever changes with node autoscaling + if (apiServerPeers) { + return apiServerPeers; + } + + try { + // Read the API server endpoints from the cluster + const { serverAddressByClientCIDRs } = await K8s(V1APIGroup).Raw("/api"); + + const peers = serverAddressByClientCIDRs?.flatMap(s => { + // Parse the value to get the host + const match = s.serverAddress.match(/^(?[^:]+):(?\d+)$/); + + // Throw an error if the host is not found + if (!match?.groups?.host) { + throw new Error(`Unable to parse serverAddress: ${s.serverAddress}`); + } + + // Otherwise, add the ipBlock to the peers map + return { + ipBlock: { + cidr: `${match.groups.host}/32`, + }, + }; + }); + + // If the peers are found, cache and return them + if (peers?.length) { + apiServerPeers = peers; + return peers; + } + } catch (err) { + Log.debug(err); + } + + // Log a warning and default to 0.0.0.0/0 if the IP is not found + Log.warn("Unable to get api-server-cidr, defaulting to 0.0.0.0/0"); + return [ + { + ipBlock: { cidr: "0.0.0.0/0" }, + }, + ]; +} diff --git a/src/pepr/operator/network/index.ts b/src/pepr/operator/network/index.ts index 4ece60a0a..f0be720ba 100644 --- a/src/pepr/operator/network/index.ts +++ b/src/pepr/operator/network/index.ts @@ -9,7 +9,6 @@ import { allowIngressWithinNS } from "./allow-ingress-within-ns"; import { defaultDenyAll } from "./default-deny-all"; // Import the NetworkPolicy transforms webhook -import "./transforms"; import { builder } from "./builder"; export async function networkPolicies(pkg: UDSPackage, namespace: string) { @@ -37,7 +36,8 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // Process custom policies for (const policy of customPolicies) { - policies.push(builder(namespace, pkg, policy)); + const generatedPolicy = await builder(namespace, pkg, policy); + policies.push(generatedPolicy); } for (const policy of policies) { diff --git a/src/pepr/operator/network/transforms.ts b/src/pepr/operator/network/transforms.ts deleted file mode 100644 index 3da244010..000000000 --- a/src/pepr/operator/network/transforms.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { K8s, Log, PeprMutateRequest, a, kind } from "pepr"; - -import { Store, When } from "../../policies/common"; - -export enum TransformLabels { - KEY = "uds/transform", - API_SERVER = "api-server", -} - -When(a.NetworkPolicy) - .IsCreatedOrUpdated() - .WithLabel(TransformLabels.KEY) - .Mutate(async request => { - const target = request.Raw.metadata?.labels?.[TransformLabels.KEY]; - - switch (target) { - case TransformLabels.API_SERVER: - await apiServer(request); - break; - - default: - throw new Error("Invalid or missing transform label"); - } - }); - -async function apiServer(request: PeprMutateRequest) { - const types = request.Raw.spec?.policyTypes; - - if (!types || !request.Raw.spec) { - throw new Error("You must specify at least one policyTypes"); - } - - // If the serverIP is not cached, get it from the kubernetes service - const ipBlock = { - cidr: Store.getItem("api-server-cidr") || "", - }; - - if (!ipBlock.cidr) { - const svc = await K8s(kind.Service).InNamespace("default").Get("kubernetes"); - - // If the IP is found, cache it - if (svc.spec?.clusterIP) { - ipBlock.cidr = `${svc.spec.clusterIP}/32`; - Store.setItem("api-server-cidr", ipBlock.cidr); - } else { - // Otherwise, log a warning and default to 0.0.0.0/0 - Log.warn("Unable to get api-server-cidr, defaulting to 0.0.0.0/0"); - ipBlock.cidr = "0.0.0.0/0"; - } - } - - if (types.includes("Ingress")) { - request.Raw.spec.ingress = [{ from: [{ ipBlock }] }]; - } - - if (types.includes("Egress")) { - request.Raw.spec.egress = [{ to: [{ ipBlock }] }]; - } -} diff --git a/src/pepr/operator/test.ts b/src/pepr/operator/test.ts index 6d87a9ed0..126fbe077 100644 --- a/src/pepr/operator/test.ts +++ b/src/pepr/operator/test.ts @@ -18,13 +18,11 @@ K8s(UDSPackage) labels: { demo: "test", }, - podSelector: { - matchLabels: { - app: "some-cool-test", - }, + podLabels: { + app: "some-cool-test", }, port: 80, - remoteNamespaceSelector: {}, + remoteNamespaceLabels: {}, }, ], }, diff --git a/tasks/deploy.yaml b/tasks/deploy.yaml index da46066cb..985cf107c 100644 --- a/tasks/deploy.yaml +++ b/tasks/deploy.yaml @@ -19,10 +19,7 @@ tasks: - name: single-package actions: # @todo (jeff): this pepr package versioning is still janky + - description: "Deploy the Pepr Module" + cmd: zarf package deploy build/zarf-package-pepr-uds-core-${UDS_ARCH}-0.2.0.tar.zst --confirm - description: "Deploy the requested Zarf Package (must set UDS_PKG environment variable)" - cmd: | - set -e - zarf package deploy build/zarf-package-uds-core-${UDS_PKG}-${UDS_ARCH}.tar.zst --confirm - - peprBuild="build/zarf-package-pepr-uds-core-${UDS_ARCH}-0.2.0.tar.zst" - [ -f "${peprBuild}" ] && zarf package deploy "${peprBuild}" --confirm || echo "Pepr build not required" + cmd: zarf package deploy build/zarf-package-uds-core-${UDS_PKG}-${UDS_ARCH}.tar.zst --confirm diff --git a/test.yaml b/test.yaml new file mode 100644 index 000000000..c85be07e9 --- /dev/null +++ b/test.yaml @@ -0,0 +1,27 @@ + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + creationTimestamp: "2023-12-19T08:16:38Z" + generation: 2 + labels: + uds/package: metrics-server + name: metrics-server-istio-ingress + namespace: metrics-server + resourceVersion: "3588" + uid: 6fb67791-280d-404d-9251-22f4d3e38a16 +spec: + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: istio-system + podSelector: {} + ports: + - port: 443 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: metrics-server + policyTypes: + - Ingress From 4cf40d35d020ff6e87bd359d8047e1dbf60db4fe Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Sun, 31 Dec 2023 03:39:25 -0600 Subject: [PATCH 11/98] uds/zarf version bump --- .vscode/settings.json | 7 ++++--- README.md | 4 ++-- bundles/k3d-istio/uds-bundle.yaml | 4 ++-- bundles/k3d-standard/uds-bundle.yaml | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 465ff4c6c..1b602431c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,23 +3,24 @@ "enableTurboSourcemaps": true, "resolveSourceMapLocations": [ "${workspaceFolder}/**", + "node_modules/kubernetes-fluent-client/**", "node_modules/pepr/**" ] }, "yaml.schemas": { // renovate: datasource=github-tags depName=defenseunicorns/uds-cli versioning=semver - "https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.4.1/uds.schema.json": [ + "https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.5.2/uds.schema.json": [ "uds-bundle.yaml" ], // renovate: datasource=github-tags depName=defenseunicorns/uds-cli versioning=semver - "https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.4.1/tasks.schema.json": [ + "https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.5.2/tasks.schema.json": [ "tasks.yaml", "tasks/**/*.yaml", "src/**/validate.yaml" ], // renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver - "https://raw.githubusercontent.com/defenseunicorns/zarf/v0.31.1/zarf.schema.json": [ + "https://raw.githubusercontent.com/defenseunicorns/zarf/v0.32.0/zarf.schema.json": [ "zarf.yaml" ] }, diff --git a/README.md b/README.md index 42c460b1b..80a2e7d06 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ The core applications are: | Dependency | Minimum Version | | -------------------------------------------------------------- | --------------- | -| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.31.1 | -| [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.4.1 | +| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.32.0 | +| [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.5.2 | | [NodeJS](https://nodejs.org/en/download/) | LTS or Current | diff --git a/bundles/k3d-istio/uds-bundle.yaml b/bundles/k3d-istio/uds-bundle.yaml index f95a07f70..cc360e091 100644 --- a/bundles/k3d-istio/uds-bundle.yaml +++ b/bundles/k3d-istio/uds-bundle.yaml @@ -6,7 +6,7 @@ metadata: version: "0.6.2" # x-release-please-end -zarf-packages: +packages: - name: uds-k3d-dev repository: ghcr.io/defenseunicorns/packages/uds-k3d # renovate: datasource=github-tags depName=defenseunicorns/uds-k3d versioning=semver @@ -27,7 +27,7 @@ zarf-packages: - name: policies description: "Minio policies" path: policies - + - name: init repository: ghcr.io/defenseunicorns/packages/init # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver diff --git a/bundles/k3d-standard/uds-bundle.yaml b/bundles/k3d-standard/uds-bundle.yaml index d5b9a5b96..e420f7c8c 100644 --- a/bundles/k3d-standard/uds-bundle.yaml +++ b/bundles/k3d-standard/uds-bundle.yaml @@ -6,7 +6,7 @@ metadata: version: "0.6.2" # x-release-please-end -zarf-packages: +packages: - name: uds-k3d-dev repository: ghcr.io/defenseunicorns/packages/uds-k3d # renovate: datasource=github-tags depName=defenseunicorns/uds-k3d versioning=semver From 842f46403235f182bb369655316f00316b8a1ee0 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Sun, 31 Dec 2023 03:40:17 -0600 Subject: [PATCH 12/98] pepr watcher rc update --- package-lock.json | 136 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/package-lock.json b/package-lock.json index e4360164d..a2df0b880 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "uds-core", "version": "0.2.0", "dependencies": { - "pepr": "0.20.2" + "pepr": "0.21.0-rc0" }, "devDependencies": { "@jest/globals": "29.7.0", @@ -135,9 +135,9 @@ } }, "node_modules/@babel/core": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", - "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -145,10 +145,10 @@ "@babel/generator": "^7.23.6", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.6", + "@babel/helpers": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.6", + "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -339,13 +339,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", - "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz", + "integrity": "sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.6", + "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" }, "engines": { @@ -641,9 +641,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", - "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", @@ -1587,9 +1587,9 @@ } }, "node_modules/@kubernetes/client-node": { - "version": "1.0.0-rc3", - "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-1.0.0-rc3.tgz", - "integrity": "sha512-bTYMBZXVrjfi98N5EZbrmPtcT9NY+TddunSEc25DcsRF1c5c93e5jT+zFwId19hG8e/ue5deKe7YDQiRYFpMlQ==", + "version": "1.0.0-rc4", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-1.0.0-rc4.tgz", + "integrity": "sha512-S7UMp/4jKxjrvO9dUHhx3AmiNTSnxtHR7k3+DI7cEuaOB7QaurtTjJJuAYf+Gi/yO6HpeyvB82uPHwfKyqivdg==", "dependencies": { "@types/js-yaml": "^4.0.1", "@types/node": "^20.3.1", @@ -1715,9 +1715,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", - "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" @@ -1768,17 +1768,17 @@ "peer": true }, "node_modules/@types/node": { - "version": "20.10.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", - "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", + "version": "20.10.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz", + "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==", + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.10.tgz", + "integrity": "sha512-PPpPK6F9ALFTn59Ka3BaL+qGuipRfxNE8qVgkp0bVixeiR2c2/L+IVOiBdu9JhhT22sWnQEp6YyHGI2b2+CMcA==", "dependencies": { "@types/node": "*", "form-data": "^4.0.0" @@ -2073,9 +2073,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "peer": true, "bin": { "acorn": "bin/acorn" @@ -2538,9 +2538,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001571", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz", - "integrity": "sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ==", + "version": "1.0.30001572", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz", + "integrity": "sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw==", "dev": true, "funding": [ { @@ -2909,9 +2909,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.615", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", - "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", + "version": "1.4.616", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz", + "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==", "dev": true }, "node_modules/emittery": { @@ -4731,17 +4731,17 @@ } }, "node_modules/kubernetes-fluent-client": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/kubernetes-fluent-client/-/kubernetes-fluent-client-1.10.0.tgz", - "integrity": "sha512-jkLCc10eKplU0VUEouIMgQYhpn1O3lcan7dX4TPwAT8g0anrH97XcL8FXOHerGYKizq3KDNjRnPkRpBZwlJFfw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/kubernetes-fluent-client/-/kubernetes-fluent-client-2.0.1.tgz", + "integrity": "sha512-MbRr6RIFn8R4Z3I6LjkYYRD/sS7KAegKfdlR7VbW9IxTvm5PsNjh9TyTVZ0D/8RsVmGohiXUhzrTomZz62c8Jw==", "dependencies": { - "@kubernetes/client-node": "1.0.0-rc3", + "@kubernetes/client-node": "1.0.0-rc4", "byline": "5.0.0", "fast-json-patch": "3.1.1", "http-status-codes": "2.3.0", "node-fetch": "2.7.0", "quicktype-core": "23.0.80", - "type-fest": "4.8.3", + "type-fest": "4.9.0", "yargs": "17.7.2" }, "bin": { @@ -4752,9 +4752,9 @@ } }, "node_modules/kubernetes-fluent-client/node_modules/type-fest": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.3.tgz", - "integrity": "sha512-//BaTm14Q/gHBn09xlnKNqfI8t6bmdzx2DXYfPBNofN0WUybCEUDcbCWcTa0oF09lzLjZgPphXAsvRiMK0V6Bw==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.9.0.tgz", + "integrity": "sha512-KS/6lh/ynPGiHD/LnAobrEFq3Ad4pBzOlJ1wAnJx9N4EYoqFhMfLIBjUT2UEx4wg5ZE+cC1ob6DCSpppVo+rtg==", "engines": { "node": ">=16" }, @@ -5160,11 +5160,11 @@ } }, "node_modules/openid-client": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.1.tgz", - "integrity": "sha512-PtrWsY+dXg6y8mtMPyL/namZSYVz8pjXz3yJiBNZsEdCnu9miHLB4ELVC85WvneMKo2Rg62Ay7NkuCpM0bgiLQ==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.2.tgz", + "integrity": "sha512-TIVimoK/fAvpiISLcoGZyNJx2TOfd5AE6TXn58FFj6Y8qbU/jqky54Aws7sYKuCph1bLPWSRUa1r/Rd6K21bhg==", "dependencies": { - "jose": "^4.15.1", + "jose": "^4.15.4", "lru-cache": "^6.0.0", "object-hash": "^2.2.0", "oidc-token-hash": "^5.0.3" @@ -5332,16 +5332,16 @@ } }, "node_modules/pepr": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.20.2.tgz", - "integrity": "sha512-N6adF/KZPpObmBzGLlQhZbnU6p4/H57XIju1MBoiKkqUxvt6+pf25GI+dMu9Jx2UtbfHkNVD/RPzrTrQTQVPpQ==", + "version": "0.21.0-rc0", + "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.21.0-rc0.tgz", + "integrity": "sha512-T3VSvYUTnQaQJ/hBPlXR0HBs0g9qxjvLBtRcTC73kW2wiKAyE2gPH14ejZBPJTA3tZ4HYvUAvD3LtjTaFfyG3Q==", "dependencies": { "@types/ramda": "0.29.9", "express": "4.18.2", "fast-json-patch": "3.1.1", - "kubernetes-fluent-client": "1.10.0", - "pino": "8.17.1", - "pino-pretty": "10.3.0", + "kubernetes-fluent-client": "2.0.1", + "pino": "8.17.2", + "pino-pretty": "10.3.1", "prom-client": "15.1.0", "ramda": "0.29.1" }, @@ -5382,16 +5382,16 @@ } }, "node_modules/pino": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.17.1.tgz", - "integrity": "sha512-YoN7/NJgnsJ+fkADZqjhRt96iepWBndQHeClmSBH0sQWCb8zGD74t00SK4eOtKFi/f8TUmQnfmgglEhd2kI1RQ==", + "version": "8.17.2", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.17.2.tgz", + "integrity": "sha512-LA6qKgeDMLr2ux2y/YiUt47EfgQ+S9LznBWOJdN3q1dx2sv0ziDLUBeVpyVv17TEcGCBuWf0zNtg3M5m1NhhWQ==", "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "v1.1.0", "pino-std-serializers": "^6.0.0", - "process-warning": "^2.0.0", + "process-warning": "^3.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", @@ -5412,9 +5412,9 @@ } }, "node_modules/pino-pretty": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.0.tgz", - "integrity": "sha512-JthvQW289q3454mhM3/38wFYGWPiBMR28T3CpDNABzoTQOje9UKS7XCJQSnjWF9LQGQkGd8D7h0oq+qwiM3jFA==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.1.tgz", + "integrity": "sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==", "dependencies": { "colorette": "^2.0.7", "dateformat": "^4.6.3", @@ -5580,9 +5580,9 @@ } }, "node_modules/process-warning": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", - "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" }, "node_modules/prom-client": { "version": "15.1.0", @@ -5773,9 +5773,9 @@ "dev": true }, "node_modules/readable-stream": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.1.tgz", - "integrity": "sha512-uQjbf34vmf/asGnOHQEw07Q4llgMACQZTWWa4MmICS0IKJoHbLwKCy71H3eR99Dw5iYejc6W+pqZZEeqRtUFAw==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -6756,9 +6756,9 @@ } }, "node_modules/ws": { - "version": "8.15.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", - "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index 3c2a710c4..6b24666a2 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "k3d-setup": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'" }, "dependencies": { - "pepr": "0.20.2" + "pepr": "0.21.0-rc0" }, "devDependencies": { "@jest/globals": "29.7.0", From 9c8a1f4e6b872926c7cfa759787e88a55d8f0a82 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Sun, 31 Dec 2023 03:40:51 -0600 Subject: [PATCH 13/98] dont rely on name for resource pruning/updating --- src/grafana/chart/templates/uds-package.yaml | 6 +-- src/loki/chart/templates/uds-package.yaml | 3 +- .../chart/templates/uds-package.yaml | 6 +-- .../chart/templates/uds-package.yaml | 9 ++-- .../crd/generated/package-v1alpha1.ts | 18 ++----- src/pepr/operator/crd/index.ts | 4 +- src/pepr/operator/crd/sources/v1alpha1.ts | 34 ++++++++----- src/pepr/operator/crd/validator.ts | 15 +----- src/pepr/operator/istio.ts | 48 ++++++++++++++----- src/pepr/operator/network/builder.ts | 8 +++- src/pepr/operator/network/index.ts | 28 +++++++++-- src/pepr/operator/test.ts | 1 - 12 files changed, 108 insertions(+), 72 deletions(-) diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index a19dcd348..4d4a5097c 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -6,14 +6,14 @@ metadata: spec: network: expose: - - name: grafana + - service: grafana + host: grafana gateway: admin port: 80 policies: allow: - - name: tempo-ingress-writes - direction: Ingress + - direction: Ingress podLabels: app: grafana remoteNamespaceLabels: diff --git a/src/loki/chart/templates/uds-package.yaml b/src/loki/chart/templates/uds-package.yaml index dafef8352..66e6334bd 100644 --- a/src/loki/chart/templates/uds-package.yaml +++ b/src/loki/chart/templates/uds-package.yaml @@ -7,8 +7,7 @@ spec: network: policies: allow: - - name: tempo-ingress-writes - direction: Ingress + - direction: Ingress podLabels: app: grafana remoteNamespaceLabels: diff --git a/src/metrics-server/chart/templates/uds-package.yaml b/src/metrics-server/chart/templates/uds-package.yaml index ae96e7e22..6409b5dad 100644 --- a/src/metrics-server/chart/templates/uds-package.yaml +++ b/src/metrics-server/chart/templates/uds-package.yaml @@ -7,13 +7,11 @@ spec: network: policies: allow: - - name: kubeapi-egress - direction: Egress + - direction: Egress remoteGenerated: KubeAPI podLabels: app.kubernetes.io/name: metrics-server - - name: istio-ingress - direction: Ingress + - direction: Ingress podLabels: app.kubernetes.io/name: metrics-server remoteNamespaceLabels: diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml index 0e500867a..18584a4fc 100644 --- a/src/neuvector/chart/templates/uds-package.yaml +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -6,20 +6,17 @@ metadata: spec: network: expose: - - name: neuvector-dashboard - service: neuvector-service-webui + - service: neuvector-service-webui gateway: admin host: neuvector port: 8443 policies: allow: - - name: controller-kubeapi-egress - direction: Egress + - direction: Egress remoteGenerated: KubeAPI podLabels: app: neuvector-controller-pod - - name: updater-kubeapi-egress - direction: Egress + - direction: Egress remoteGenerated: KubeAPI podLabels: app: neuvector-updater-pod diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index 07e296dd0..5beb27a09 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -4,7 +4,7 @@ import { GenericKind, RegisterKind } from "kubernetes-fluent-client"; export class Package extends GenericKind { spec?: Spec; - status?: { [key: string]: never }; + status?: { [key: string]: unknown }; } export interface Spec { @@ -34,25 +34,21 @@ export interface Expose { */ gateway?: Gateway; /** - * The hostname to expose the service on (default: name) + * The hostname to expose the service on */ - host?: string; + host: string; /** * The mode to use when exposing the service */ mode?: Mode; - /** - * The unique name to use as the VirtualService name - */ - name: string; /** * The port number to expose */ port: number; /** - * The name of the service to expose (default: name) + * The name of the service to expose */ - service?: string; + service: string; } /** @@ -95,10 +91,6 @@ export interface Allow { * The labels to apply to the policy */ labels?: { [key: string]: string }; - /** - * The name of the policy - */ - name: string; /** * Labels to match pods in the namespace to apply the policy to. Leave empty to apply to all * pods in the namespace diff --git a/src/pepr/operator/crd/index.ts b/src/pepr/operator/crd/index.ts index 4cd0a6510..15acdf355 100644 --- a/src/pepr/operator/crd/index.ts +++ b/src/pepr/operator/crd/index.ts @@ -1,6 +1,6 @@ export { - Package as UDSPackage, - DisableDefault, Allow, + DisableDefault, Gateway, + Package as UDSPackage, } from "./generated/package-v1alpha1"; diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index 1bb8cc609..3c4cc835d 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -4,6 +4,20 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { name: "v1alpha1", served: true, storage: true, + additionalPrinterColumns: [ + { + name: "Status", + type: "string", + description: "The status of the package", + jsonPath: ".status.phase", + }, + { + name: "Age", + type: "date", + description: "The age of the package", + jsonPath: ".metadata.creationTimestamp", + }, + ], schema: { openAPIV3Schema: { type: "object", @@ -26,18 +40,16 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { description: "Expose a service on an Istio Gateway", items: { type: "object", - required: ["name", "port"], + required: ["service", "host", "port"], properties: { - name: { - description: "The unique name to use as the VirtualService name", - type: "string", - }, service: { - description: "The name of the service to expose (default: name)", + description: "The name of the service to expose", type: "string", }, port: { description: "The port number to expose", + minimum: 1, + maximum: 65535, type: "number", }, gateway: { @@ -48,7 +60,7 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { default: "tenant", }, host: { - description: "The hostname to expose the service on (default: name)", + description: "The hostname to expose the service on", type: "string", }, mode: { @@ -77,12 +89,8 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { type: "array", items: { type: "object", - required: ["name", "direction"], + required: ["direction"], properties: { - name: { - description: "The name of the policy", - type: "string", - }, labels: { description: "The labels to apply to the policy", type: "object", @@ -124,6 +132,8 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { }, port: { description: "The port to allow", + minimum: 1, + maximum: 65535, type: "number", }, protocol: { diff --git a/src/pepr/operator/crd/validator.ts b/src/pepr/operator/crd/validator.ts index 0c72c32cb..eff6d6f26 100644 --- a/src/pepr/operator/crd/validator.ts +++ b/src/pepr/operator/crd/validator.ts @@ -1,28 +1,17 @@ import { PeprValidateRequest } from "pepr"; import { UDSPackage } from "."; -const invalidNamespaces = ["kube-system", "kube-public", "invalid", "pepr-system"]; +const invalidNamespaces = ["kube-system", "kube-public", "_unknown_", "pepr-system"]; export async function validator(req: PeprValidateRequest) { - const ns = req.Raw.metadata?.namespace ?? "invalid"; + const ns = req.Raw.metadata?.namespace ?? "_unknown_"; if (invalidNamespaces.includes(ns)) { return req.Deny("invalid namespace"); } - // Ensure the name of each expose is unique - const expose = req.Raw.spec?.network?.expose ?? []; - const uniqueNames = new Set(expose.map(e => e.name)); - if (uniqueNames.size !== expose.length) { - return req.Deny("expose.name must be unique"); - } - // Ensure the name of each network policy is unique const networkPolicy = req.Raw.spec?.network?.policies?.allow ?? []; - const uniquePolicyNames = new Set(networkPolicy.map(e => e.name)); - if (uniquePolicyNames.size !== networkPolicy.length) { - return req.Deny("networkPolicy.name must be unique"); - } for (const policy of networkPolicy) { // remoteGenerated cannot be combined with remoteNamespaceLabels or remotePodLabels diff --git a/src/pepr/operator/istio.ts b/src/pepr/operator/istio.ts index 15918c8f1..185de289a 100644 --- a/src/pepr/operator/istio.ts +++ b/src/pepr/operator/istio.ts @@ -12,31 +12,36 @@ import { HTTPRoute, TCPRoute, VirtualService } from "./crd/generated/istio/virtu * @param namespace */ export async function virtualService(pkg: UDSPackage, namespace: string) { - const { name: pkgName, uid } = pkg.metadata!; + const pkgName = pkg.metadata!.name!; + const uid = pkg.metadata!.uid!; + + const generation = (pkg.metadata?.generation ?? 0).toString(); // Use the CR as the owner ref for each VirtualService const ownerReferences: V1OwnerReference[] = [ { apiVersion: pkg.apiVersion!, kind: pkg.kind!, - uid: uid!, - name: pkgName!, + uid: uid, + name: pkgName, }, ]; - for (const expose of pkg.spec?.network?.expose ?? []) { + // Get the list of exposed services + const exposeList = pkg.spec?.network?.expose ?? []; + + // Iterate over each exposed service + for (const expose of exposeList) { const { gateway = Gateway.Tenant, host, port, service, mode } = expose; - // Use the package name + unique name as the VirtualService name - // This ensures we don't accidentally expose the same service multiple times - const name = `${pkgName}-${expose.name}`; + const name = `${pkgName}-${gateway}-${host}`.toLowerCase(); // Create the route to the service const route: TCPRoute[] | HTTPRoute[] = [ { destination: { - // Use the service name as the host if provide, otherwise use the expose name - host: `${service || expose.name}.${namespace}.svc.cluster.local`, + // Use the service name as the host + host: `${service}.${namespace}.svc.cluster.local`, // The CRD only uses numeric ports port: { number: port }, }, @@ -50,11 +55,15 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { metadata: { name, namespace, + labels: { + "uds/package": pkgName, + "uds/generation": generation, + }, ownerReferences, }, spec: { - // Append the UDS Domain to the host. Use the expose name if no host is provided - hosts: [`${host || expose.name}.${domain}`], + // Append the UDS Domain to the host + hosts: [`${host}.${domain}`], // Map the gateway (admin, passthrough or tenant) to the VirtualService gateways: [`istio-${gateway}-gateway/${gateway}-gateway`], }, @@ -68,4 +77,21 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { // Apply the VirtualService await K8s(VirtualService).Apply(payload); } + + // Get all related VirtualServices in the namespace + const virtualServices = await K8s(VirtualService) + .InNamespace(namespace) + .WithLabel("uds/package", pkgName) + .Get(); + + // Find any orphaned VirtualServices (not matching the current generation) + const orphanedVS = virtualServices.items.filter( + vs => vs.metadata?.labels?.["uds/generation"] !== generation, + ); + + // Delete any orphaned VirtualServices + for (const vs of orphanedVS) { + Log.debug(vs, `Deleting orphaned VirtualService ${vs.metadata!.name}`); + await K8s(VirtualService).Delete(vs); + } } diff --git a/src/pepr/operator/network/builder.ts b/src/pepr/operator/network/builder.ts index fceb11a4d..6dcf622aa 100644 --- a/src/pepr/operator/network/builder.ts +++ b/src/pepr/operator/network/builder.ts @@ -10,9 +10,14 @@ export async function builder( namespace: string, pkg: UDSPackage, policy: Allow, + generation: string, + idx: number, ): Promise { const pkgName = pkg.metadata!.name!; - const name = `${pkgName}-${policy.name}`; + const target = Object.values(policy.podLabels!).join("-"); + + // Create a unique name for the NetworkPolicy based on the package name, index, direction, pod labels, and port + const name = `${pkgName}-${idx}-${policy.direction}-${target}-${policy.port}`.toLowerCase(); // Create the NetworkPolicy const generated: kind.NetworkPolicy = { @@ -23,6 +28,7 @@ export async function builder( namespace, labels: { "uds/package": pkgName, + "uds/generation": generation, ...policy.labels, }, }, diff --git a/src/pepr/operator/network/index.ts b/src/pepr/operator/network/index.ts index f0be720ba..c30fc5895 100644 --- a/src/pepr/operator/network/index.ts +++ b/src/pepr/operator/network/index.ts @@ -1,4 +1,4 @@ -import { K8s, kind } from "pepr"; +import { K8s, Log, kind } from "pepr"; import { DisableDefault, UDSPackage } from "../crd"; import { allowEgressDNS } from "./allow-egress-dns"; @@ -15,6 +15,9 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { const disabled = pkg.spec?.network?.policies?.disableDefaults ?? []; const customPolicies = pkg.spec?.network?.policies?.allow ?? []; + // Get the current generation of the package + const generation = (pkg.metadata?.generation ?? 0).toString(); + const policies = [ // All traffic must be explicitly allowed defaultDenyAll(namespace), @@ -35,13 +38,30 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { } // Process custom policies - for (const policy of customPolicies) { - const generatedPolicy = await builder(namespace, pkg, policy); + for (const [idx, policy] of customPolicies.entries()) { + const generatedPolicy = await builder(namespace, pkg, policy, generation, idx); policies.push(generatedPolicy); } + // Apply each policy, overwriting any existing policy for (const policy of policies) { - // Apply the policy, overwriting any existing policy await K8s(kind.NetworkPolicy).Apply(policy); } + + // Delete any policies that are no longer needed + const policyList = await K8s(kind.NetworkPolicy) + .InNamespace(namespace) + .WithLabel("uds/package", pkg.metadata!.name!) + .Get(); + + // Find any orphaned polices (not matching the current generation) + const orphanedNetPol = policyList.items.filter( + vs => vs.metadata?.labels?.["uds/generation"] !== generation, + ); + + // Delete any orphaned policies + for (const vs of orphanedNetPol) { + Log.debug(vs, `Deleting orphaned VirtualService ${vs.metadata!.name}`); + await K8s(kind.NetworkPolicy).Delete(vs); + } } diff --git a/src/pepr/operator/test.ts b/src/pepr/operator/test.ts index 126fbe077..209af92ec 100644 --- a/src/pepr/operator/test.ts +++ b/src/pepr/operator/test.ts @@ -13,7 +13,6 @@ K8s(UDSPackage) policies: { allow: [ { - name: "some-cool-test", direction: Direction.Ingress, labels: { demo: "test", From df8f1ec39bb8737c83d803186987b6c9196bee44 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Sun, 31 Dec 2023 03:59:56 -0600 Subject: [PATCH 14/98] match name convention of standard netpols --- src/pepr/operator/network/builder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/operator/network/builder.ts b/src/pepr/operator/network/builder.ts index 6dcf622aa..e5faf131d 100644 --- a/src/pepr/operator/network/builder.ts +++ b/src/pepr/operator/network/builder.ts @@ -17,7 +17,7 @@ export async function builder( const target = Object.values(policy.podLabels!).join("-"); // Create a unique name for the NetworkPolicy based on the package name, index, direction, pod labels, and port - const name = `${pkgName}-${idx}-${policy.direction}-${target}-${policy.port}`.toLowerCase(); + const name = `allow-${policy.direction}-${target}-${pkgName}-${idx}`.toLowerCase(); // Create the NetworkPolicy const generated: kind.NetworkPolicy = { From 0e00743b07f2da8f12d7418ba46eaaf4276b5340 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Sun, 31 Dec 2023 04:00:09 -0600 Subject: [PATCH 15/98] update test pkg uds CRs --- src/test/app-admin.yaml | 3 +-- src/test/app-tenant.yaml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/app-admin.yaml b/src/test/app-admin.yaml index ab11750d1..eaec5b5fb 100644 --- a/src/test/app-admin.yaml +++ b/src/test/app-admin.yaml @@ -32,8 +32,7 @@ metadata: spec: network: expose: - - name: httpbin - service: httpbin + - service: httpbin gateway: admin host: demo port: 8000 diff --git a/src/test/app-tenant.yaml b/src/test/app-tenant.yaml index 6f57daa61..61e5e539f 100644 --- a/src/test/app-tenant.yaml +++ b/src/test/app-tenant.yaml @@ -35,8 +35,7 @@ metadata: spec: network: expose: - - name: httpbin - service: httpbin + - service: httpbin gateway: tenant host: demo port: 8000 From a03974fa63084a8a3b629e5fd62a99eab1e0f628 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 1 Jan 2024 16:41:56 -0600 Subject: [PATCH 16/98] forec:true & owenerref common func --- src/pepr/operator/crd/index.ts | 17 +++++++++++++++ src/pepr/operator/crd/register.ts | 35 +++++++++++++++++-------------- src/pepr/operator/istio.ts | 22 +++++-------------- src/pepr/operator/namespace.ts | 13 +++++++----- 4 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/pepr/operator/crd/index.ts b/src/pepr/operator/crd/index.ts index 15acdf355..1ddcc70a5 100644 --- a/src/pepr/operator/crd/index.ts +++ b/src/pepr/operator/crd/index.ts @@ -1,6 +1,23 @@ +import { V1OwnerReference } from "@kubernetes/client-node"; + +import { Package as UDSPackage } from "./generated/package-v1alpha1"; + export { Allow, DisableDefault, Gateway, Package as UDSPackage, } from "./generated/package-v1alpha1"; + +export function getOwnerRef(pkg: UDSPackage): V1OwnerReference[] { + const { name, uid } = pkg.metadata!; + + return [ + { + apiVersion: pkg.apiVersion!, + kind: pkg.kind!, + uid: uid!, + name: name!, + }, + ]; +} diff --git a/src/pepr/operator/crd/register.ts b/src/pepr/operator/crd/register.ts index a0e450b40..3332753f1 100644 --- a/src/pepr/operator/crd/register.ts +++ b/src/pepr/operator/crd/register.ts @@ -5,24 +5,27 @@ import { v1alpha1 } from "./sources/v1alpha1"; // Register the CRD if we're in watch mode if (process.env.PEPR_WATCH_MODE === "true") { K8s(kind.CustomResourceDefinition) - .Apply({ - apiVersion: "apiextensions.k8s.io/v1", - kind: "CustomResourceDefinition", - metadata: { - name: "packages.uds.dev", - }, - spec: { - group: "uds.dev", - versions: [v1alpha1], - scope: "Namespaced", - names: { - plural: "packages", - singular: "package", - kind: "Package", - shortNames: ["pkg"], + .Apply( + { + apiVersion: "apiextensions.k8s.io/v1", + kind: "CustomResourceDefinition", + metadata: { + name: "packages.uds.dev", + }, + spec: { + group: "uds.dev", + versions: [v1alpha1], + scope: "Namespaced", + names: { + plural: "packages", + singular: "package", + kind: "Package", + shortNames: ["pkg"], + }, }, }, - }) + { force: true }, + ) .then(() => { Log.info("CRD registered"); }) diff --git a/src/pepr/operator/istio.ts b/src/pepr/operator/istio.ts index 185de289a..de34ed71a 100644 --- a/src/pepr/operator/istio.ts +++ b/src/pepr/operator/istio.ts @@ -1,8 +1,7 @@ import { K8s, Log } from "pepr"; -import { V1OwnerReference } from "@kubernetes/client-node"; import { UDSConfig } from "../config"; -import { Gateway, UDSPackage } from "./crd"; +import { Gateway, UDSPackage, getOwnerRef } from "./crd"; import { HTTPRoute, TCPRoute, VirtualService } from "./crd/generated/istio/virtualservice-v1beta1"; /** @@ -13,20 +12,8 @@ import { HTTPRoute, TCPRoute, VirtualService } from "./crd/generated/istio/virtu */ export async function virtualService(pkg: UDSPackage, namespace: string) { const pkgName = pkg.metadata!.name!; - const uid = pkg.metadata!.uid!; - const generation = (pkg.metadata?.generation ?? 0).toString(); - // Use the CR as the owner ref for each VirtualService - const ownerReferences: V1OwnerReference[] = [ - { - apiVersion: pkg.apiVersion!, - kind: pkg.kind!, - uid: uid, - name: pkgName, - }, - ]; - // Get the list of exposed services const exposeList = pkg.spec?.network?.expose ?? []; @@ -59,7 +46,8 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { "uds/package": pkgName, "uds/generation": generation, }, - ownerReferences, + // Use the CR as the owner ref for each VirtualService + ownerReferences: getOwnerRef(pkg), }, spec: { // Append the UDS Domain to the host @@ -74,8 +62,8 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { Log.debug(payload, `Applying VirtualService ${name}`); - // Apply the VirtualService - await K8s(VirtualService).Apply(payload); + // Apply the VirtualService and force overwrite any existing policy + await K8s(VirtualService).Apply(payload, { force: true }); } // Get all related VirtualServices in the namespace diff --git a/src/pepr/operator/namespace.ts b/src/pepr/operator/namespace.ts index c10f0502e..5d00c8938 100644 --- a/src/pepr/operator/namespace.ts +++ b/src/pepr/operator/namespace.ts @@ -22,12 +22,15 @@ export async function syncNamespace(pkg: UDSPackage) { labels[pkgLabel] = pkg.metadata.name; // Apply the updated Namespace - await K8s(kind.Namespace).Apply({ - metadata: { - name: pkg.metadata.namespace, - labels, + await K8s(kind.Namespace).Apply( + { + metadata: { + name: pkg.metadata.namespace, + labels, + }, }, - }); + { force: true }, + ); } return pkg.metadata.namespace; From c714e2f901ba1b9593741d6bc48f995e22ff80cd Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 1 Jan 2024 16:42:23 -0600 Subject: [PATCH 17/98] ouch fail --- src/pepr/operator/network/allow-egress-within-ns.ts | 9 --------- src/pepr/operator/network/allow-ingress-within-ns.ts | 9 --------- 2 files changed, 18 deletions(-) diff --git a/src/pepr/operator/network/allow-egress-within-ns.ts b/src/pepr/operator/network/allow-egress-within-ns.ts index 373656c8a..b8e017247 100644 --- a/src/pepr/operator/network/allow-egress-within-ns.ts +++ b/src/pepr/operator/network/allow-egress-within-ns.ts @@ -11,15 +11,6 @@ export function allowEgressWithinNS(namespace: string): kind.NetworkPolicy { spec: { podSelector: {}, policyTypes: ["Egress"], - egress: [ - { - to: [ - { - namespaceSelector: {}, - }, - ], - }, - ], }, }; } diff --git a/src/pepr/operator/network/allow-ingress-within-ns.ts b/src/pepr/operator/network/allow-ingress-within-ns.ts index a331dfcee..9c0b9e186 100644 --- a/src/pepr/operator/network/allow-ingress-within-ns.ts +++ b/src/pepr/operator/network/allow-ingress-within-ns.ts @@ -11,15 +11,6 @@ export function allowIngressWithinNS(namespace: string): kind.NetworkPolicy { spec: { podSelector: {}, policyTypes: ["Ingress"], - ingress: [ - { - from: [ - { - namespaceSelector: {}, - }, - ], - }, - ], }, }; } From 6783fce8831cbf41664de1bb719354c5e334cbe5 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 1 Jan 2024 16:42:45 -0600 Subject: [PATCH 18/98] make netpol labels consistent --- src/pepr/operator/network/builder.ts | 4 +--- src/pepr/operator/network/index.ts | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/pepr/operator/network/builder.ts b/src/pepr/operator/network/builder.ts index e5faf131d..e4d9704e5 100644 --- a/src/pepr/operator/network/builder.ts +++ b/src/pepr/operator/network/builder.ts @@ -10,7 +10,6 @@ export async function builder( namespace: string, pkg: UDSPackage, policy: Allow, - generation: string, idx: number, ): Promise { const pkgName = pkg.metadata!.name!; @@ -27,8 +26,7 @@ export async function builder( name, namespace, labels: { - "uds/package": pkgName, - "uds/generation": generation, + "uds/builder": "true", ...policy.labels, }, }, diff --git a/src/pepr/operator/network/index.ts b/src/pepr/operator/network/index.ts index c30fc5895..9f4251a4c 100644 --- a/src/pepr/operator/network/index.ts +++ b/src/pepr/operator/network/index.ts @@ -1,6 +1,6 @@ import { K8s, Log, kind } from "pepr"; -import { DisableDefault, UDSPackage } from "../crd"; +import { DisableDefault, UDSPackage, getOwnerRef } from "../crd"; import { allowEgressDNS } from "./allow-egress-dns"; import { allowEgressIstiod } from "./allow-egress-istiod"; import { allowEgressWithinNS } from "./allow-egress-within-ns"; @@ -39,13 +39,23 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // Process custom policies for (const [idx, policy] of customPolicies.entries()) { - const generatedPolicy = await builder(namespace, pkg, policy, generation, idx); + const generatedPolicy = await builder(namespace, pkg, policy, idx); policies.push(generatedPolicy); } - // Apply each policy, overwriting any existing policy + // Iterate over each policy and apply it for (const policy of policies) { - await K8s(kind.NetworkPolicy).Apply(policy); + // Add the package name and generation to the labels + policy.metadata = policy.metadata ?? {}; + policy.metadata.labels = policy.metadata?.labels ?? {}; + policy.metadata.labels["uds/package"] = pkg.metadata!.name!; + policy.metadata.labels["uds/generation"] = generation; + + // Use the CR as the owner ref for each NetworkPolicy + policy.metadata.ownerReferences = getOwnerRef(pkg); + + // Apply the NetworkPolicy and force overwrite any existing policy + await K8s(kind.NetworkPolicy).Apply(policy, { force: true }); } // Delete any policies that are no longer needed From 2a4b11eb04cc1b81c131ed97a95207e2383a7f58 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 1 Jan 2024 16:42:57 -0600 Subject: [PATCH 19/98] pepr 0.21 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index a2df0b880..61d9053eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "uds-core", "version": "0.2.0", "dependencies": { - "pepr": "0.21.0-rc0" + "pepr": "0.21.0" }, "devDependencies": { "@jest/globals": "29.7.0", @@ -5332,9 +5332,9 @@ } }, "node_modules/pepr": { - "version": "0.21.0-rc0", - "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.21.0-rc0.tgz", - "integrity": "sha512-T3VSvYUTnQaQJ/hBPlXR0HBs0g9qxjvLBtRcTC73kW2wiKAyE2gPH14ejZBPJTA3tZ4HYvUAvD3LtjTaFfyG3Q==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.21.0.tgz", + "integrity": "sha512-6uEGeJ3t5RAY1NotbsXpkZ2tPoGsQWFHqfrkpjnxC1xwPEIyFWykHZZ6J9ZhtU3fx3SIroT5DlJ5Qchg4OE2SA==", "dependencies": { "@types/ramda": "0.29.9", "express": "4.18.2", diff --git a/package.json b/package.json index 6b24666a2..d0012c24e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "k3d-setup": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'" }, "dependencies": { - "pepr": "0.21.0-rc0" + "pepr": "0.21.0" }, "devDependencies": { "@jest/globals": "29.7.0", From 1ab7f471eee473750b2fb07ecca1a42b90f634a8 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 1 Jan 2024 16:45:10 -0600 Subject: [PATCH 20/98] cleanup zarf/uds cli version updates --- .github/actions/setup/action.yaml | 4 ++-- bundles/k3d-istio/uds-bundle.yaml | 2 +- bundles/k3d-standard/uds-bundle.yaml | 2 +- tasks/setup.yaml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/actions/setup/action.yaml b/.github/actions/setup/action.yaml index be9130bfc..28c11ca87 100644 --- a/.github/actions/setup/action.yaml +++ b/.github/actions/setup/action.yaml @@ -9,7 +9,7 @@ runs: uses: defenseunicorns/setup-zarf@main with: # renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver - version: v0.31.1 + version: v0.32.0 download-init-package: true - name: Use Node.js latest @@ -27,4 +27,4 @@ runs: - name: Install UDS CLI shell: bash # renovate: datasource=github-tags depName=defenseunicorns/uds-cli versioning=semver - run: brew install defenseunicorns/tap/uds@0.4.1 + run: brew install defenseunicorns/tap/uds@0.5.2 diff --git a/bundles/k3d-istio/uds-bundle.yaml b/bundles/k3d-istio/uds-bundle.yaml index cc360e091..076335f50 100644 --- a/bundles/k3d-istio/uds-bundle.yaml +++ b/bundles/k3d-istio/uds-bundle.yaml @@ -31,7 +31,7 @@ packages: - name: init repository: ghcr.io/defenseunicorns/packages/init # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver - ref: v0.31.1 + ref: v0.32.0 - name: core-istio path: ../../build/ diff --git a/bundles/k3d-standard/uds-bundle.yaml b/bundles/k3d-standard/uds-bundle.yaml index e420f7c8c..f392581a7 100644 --- a/bundles/k3d-standard/uds-bundle.yaml +++ b/bundles/k3d-standard/uds-bundle.yaml @@ -31,7 +31,7 @@ packages: - name: init repository: ghcr.io/defenseunicorns/packages/init # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver - ref: v0.31.1 + ref: v0.32.0 - name: core path: ../../build/ diff --git a/tasks/setup.yaml b/tasks/setup.yaml index 392ceaa08..da324adba 100644 --- a/tasks/setup.yaml +++ b/tasks/setup.yaml @@ -7,4 +7,4 @@ tasks: - description: "Initialize the cluster with Zarf" # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver - cmd: "zarf package deploy oci://defenseunicorns/init:v0.31.1-${UDS_ARCH} --confirm" + cmd: "zarf package deploy oci://defenseunicorns/init:v0.32.0-${UDS_ARCH} --confirm" From 2c7fd9aebf8f0e63aa07f4b165af47cc32690bd3 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 1 Jan 2024 17:35:42 -0600 Subject: [PATCH 21/98] back to zarf v0.31.4 until UDS CLI is updated --- .github/actions/setup/action.yaml | 2 +- .vscode/settings.json | 2 +- README.md | 2 +- bundles/k3d-istio/uds-bundle.yaml | 2 +- bundles/k3d-standard/uds-bundle.yaml | 2 +- tasks/setup.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/actions/setup/action.yaml b/.github/actions/setup/action.yaml index 28c11ca87..40850710f 100644 --- a/.github/actions/setup/action.yaml +++ b/.github/actions/setup/action.yaml @@ -9,7 +9,7 @@ runs: uses: defenseunicorns/setup-zarf@main with: # renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver - version: v0.32.0 + version: v0.31.4 download-init-package: true - name: Use Node.js latest diff --git a/.vscode/settings.json b/.vscode/settings.json index 1b602431c..c7184a0b8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,7 +20,7 @@ "src/**/validate.yaml" ], // renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver - "https://raw.githubusercontent.com/defenseunicorns/zarf/v0.32.0/zarf.schema.json": [ + "https://raw.githubusercontent.com/defenseunicorns/zarf/v0.31.4/zarf.schema.json": [ "zarf.yaml" ] }, diff --git a/README.md b/README.md index 80a2e7d06..e4de53033 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ The core applications are: | Dependency | Minimum Version | | -------------------------------------------------------------- | --------------- | -| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.32.0 | +| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.31.4 | | [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.5.2 | | [NodeJS](https://nodejs.org/en/download/) | LTS or Current | diff --git a/bundles/k3d-istio/uds-bundle.yaml b/bundles/k3d-istio/uds-bundle.yaml index 076335f50..6eebc9853 100644 --- a/bundles/k3d-istio/uds-bundle.yaml +++ b/bundles/k3d-istio/uds-bundle.yaml @@ -31,7 +31,7 @@ packages: - name: init repository: ghcr.io/defenseunicorns/packages/init # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver - ref: v0.32.0 + ref: v0.31.4 - name: core-istio path: ../../build/ diff --git a/bundles/k3d-standard/uds-bundle.yaml b/bundles/k3d-standard/uds-bundle.yaml index f392581a7..85f957c4f 100644 --- a/bundles/k3d-standard/uds-bundle.yaml +++ b/bundles/k3d-standard/uds-bundle.yaml @@ -31,7 +31,7 @@ packages: - name: init repository: ghcr.io/defenseunicorns/packages/init # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver - ref: v0.32.0 + ref: v0.31.4 - name: core path: ../../build/ diff --git a/tasks/setup.yaml b/tasks/setup.yaml index da324adba..f25360bb5 100644 --- a/tasks/setup.yaml +++ b/tasks/setup.yaml @@ -7,4 +7,4 @@ tasks: - description: "Initialize the cluster with Zarf" # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver - cmd: "zarf package deploy oci://defenseunicorns/init:v0.32.0-${UDS_ARCH} --confirm" + cmd: "zarf package deploy oci://defenseunicorns/init:v0.31.4-${UDS_ARCH} --confirm" From 389bd8e30bda8850116c49165bc17de200e58d03 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 1 Jan 2024 17:37:05 -0600 Subject: [PATCH 22/98] auto-wire ingress allow NetPol for generated Istio VS --- .../network-policies/ingress-istio.yaml | 25 -------------- .../network-policies/ingress-monitoring.yaml | 22 ------------- .../ingress-sidecar-monitoring.yaml | 21 ------------ .../chart/templates/uds-package.yaml | 21 ++++++++++++ src/pepr/config.ts | 2 ++ src/pepr/operator/crd/index.ts | 1 + src/pepr/operator/network/index.ts | 33 ++++++++++++++++++- 7 files changed, 56 insertions(+), 69 deletions(-) delete mode 100644 src/neuvector/chart/templates/network-policies/ingress-istio.yaml delete mode 100644 src/neuvector/chart/templates/network-policies/ingress-monitoring.yaml delete mode 100644 src/neuvector/chart/templates/network-policies/ingress-sidecar-monitoring.yaml diff --git a/src/neuvector/chart/templates/network-policies/ingress-istio.yaml b/src/neuvector/chart/templates/network-policies/ingress-istio.yaml deleted file mode 100644 index f939669bd..000000000 --- a/src/neuvector/chart/templates/network-policies/ingress-istio.yaml +++ /dev/null @@ -1,25 +0,0 @@ - -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-istio-ingress - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app: neuvector-manager-pod - policyTypes: - - Ingress - - Egress - ingress: - - from: - - podSelector: - matchLabels: - app: admin-ingressgateway - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: istio-admin-gateway - ports: - - port: 8443 - protocol: TCP - diff --git a/src/neuvector/chart/templates/network-policies/ingress-monitoring.yaml b/src/neuvector/chart/templates/network-policies/ingress-monitoring.yaml deleted file mode 100644 index 1b1a4cd26..000000000 --- a/src/neuvector/chart/templates/network-policies/ingress-monitoring.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-scraping - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app: neuvector-prometheus-exporter-pod - ingress: - - ports: - - protocol: TCP - port: 8068 - from: - - podSelector: - matchLabels: - app: prometheus - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: monitoring - policyTypes: - - Ingress diff --git a/src/neuvector/chart/templates/network-policies/ingress-sidecar-monitoring.yaml b/src/neuvector/chart/templates/network-policies/ingress-sidecar-monitoring.yaml deleted file mode 100644 index 660092bb7..000000000 --- a/src/neuvector/chart/templates/network-policies/ingress-sidecar-monitoring.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-sidecar-scraping - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Ingress - ingress: - - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: monitoring - podSelector: - matchLabels: - app: prometheus - ports: - - protocol: TCP - port: 15020 - diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml index 18584a4fc..1ba9cef2b 100644 --- a/src/neuvector/chart/templates/uds-package.yaml +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -20,3 +20,24 @@ spec: remoteGenerated: KubeAPI podLabels: app: neuvector-updater-pod + - direction: Ingress + remoteNamespaceLabels: + app.kubernetes.io/name: monitoring + remotePodLabels: + app: prometheus + podLabels: + app: neuvector-prometheus-exporter-pod + port: 8068 + + + +# apiVersion: networking.k8s.io/v1 +# kind: NetworkPolicy +# metadata: +# name: allow-istio-ingress +# # namespace: {{ .Release.Namespace }} +# namespace: neuvector +# spec: +# podSelector: +# matchLabels: +# app: neuvector-manager-pod diff --git a/src/pepr/config.ts b/src/pepr/config.ts index ffcc70b8d..b8b2eac40 100644 --- a/src/pepr/config.ts +++ b/src/pepr/config.ts @@ -1,4 +1,6 @@ export const UDSConfig = { domain: process.env.UDS_DOMAIN || "uds.dev", istioInstalled: process.env.UDS_WITH_ISTIO === "true", + // domain: "uds.dev", + // istioInstalled: true, }; diff --git a/src/pepr/operator/crd/index.ts b/src/pepr/operator/crd/index.ts index 1ddcc70a5..a742b8a0e 100644 --- a/src/pepr/operator/crd/index.ts +++ b/src/pepr/operator/crd/index.ts @@ -6,6 +6,7 @@ export { Allow, DisableDefault, Gateway, + Direction, Package as UDSPackage, } from "./generated/package-v1alpha1"; diff --git a/src/pepr/operator/network/index.ts b/src/pepr/operator/network/index.ts index 9f4251a4c..c3e11b4a2 100644 --- a/src/pepr/operator/network/index.ts +++ b/src/pepr/operator/network/index.ts @@ -1,6 +1,6 @@ import { K8s, Log, kind } from "pepr"; -import { DisableDefault, UDSPackage, getOwnerRef } from "../crd"; +import { Allow, Direction, DisableDefault, Gateway, UDSPackage, getOwnerRef } from "../crd"; import { allowEgressDNS } from "./allow-egress-dns"; import { allowEgressIstiod } from "./allow-egress-istiod"; import { allowEgressWithinNS } from "./allow-egress-within-ns"; @@ -43,6 +43,37 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { policies.push(generatedPolicy); } + // Generate NetworkPolicies for any VirtualServices that are generated + const exposeList = pkg.spec?.network?.expose ?? []; + for (const [idx, expose] of exposeList.entries()) { + const { gateway = Gateway.Tenant, port, service } = expose; + + let podLabels: Record = {}; + try { + const svcDef = await K8s(kind.Service).InNamespace(namespace).Get(service); + podLabels = svcDef.spec?.selector as Record; + } catch (e) { + Log.error(e, `Unable to load the service ${namespace}/${service}`); + } + + // Create the NetworkPolicy for the VirtualService + const policy: Allow = { + direction: Direction.Ingress, + podLabels, + remotePodLabels: { + app: `${gateway}-ingressgateway`, + }, + remoteNamespaceLabels: { + "kubernetes.io/metadata.name": `istio-${gateway}-gateway`, + }, + port, + }; + + // Generate the policy with a base index of 1000 + const generatedPolicy = await builder(namespace, pkg, policy, 1000 + idx); + policies.push(generatedPolicy); + } + // Iterate over each policy and apply it for (const policy of policies) { // Add the package name and generation to the labels From 4b73dc8b49326b214e3608dfb2f7c566721842bd Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:02:26 -0600 Subject: [PATCH 23/98] update test app expose entries --- src/test/app-admin.yaml | 2 ++ src/test/app-tenant.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/test/app-admin.yaml b/src/test/app-admin.yaml index eaec5b5fb..ed36c2b66 100644 --- a/src/test/app-admin.yaml +++ b/src/test/app-admin.yaml @@ -33,6 +33,8 @@ spec: network: expose: - service: httpbin + podLabels: + app: httpbin gateway: admin host: demo port: 8000 diff --git a/src/test/app-tenant.yaml b/src/test/app-tenant.yaml index 61e5e539f..5e5c3f162 100644 --- a/src/test/app-tenant.yaml +++ b/src/test/app-tenant.yaml @@ -36,6 +36,8 @@ spec: network: expose: - service: httpbin + podLabels: + app: httpbin gateway: tenant host: demo port: 8000 From 2cab4fcb6c5a3ac81f7527ae1ba2eb5666624dc8 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:02:53 -0600 Subject: [PATCH 24/98] pepr 0.21.1 (PatchStatus) --- package-lock.json | 22 +++++++++++----------- package.json | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61d9053eb..19eaa8045 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "uds-core", "version": "0.2.0", "dependencies": { - "pepr": "0.21.0" + "pepr": "0.21.1" }, "devDependencies": { "@jest/globals": "29.7.0", @@ -2909,9 +2909,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.616", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz", - "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==", + "version": "1.4.617", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.617.tgz", + "integrity": "sha512-sYNE3QxcDS4ANW1k4S/wWYMXjCVcFSOX3Bg8jpuMFaXt/x8JCmp0R1Xe1ZXDX4WXnSRBf+GJ/3eGWicUuQq5cg==", "dev": true }, "node_modules/emittery": { @@ -4731,9 +4731,9 @@ } }, "node_modules/kubernetes-fluent-client": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/kubernetes-fluent-client/-/kubernetes-fluent-client-2.0.1.tgz", - "integrity": "sha512-MbRr6RIFn8R4Z3I6LjkYYRD/sS7KAegKfdlR7VbW9IxTvm5PsNjh9TyTVZ0D/8RsVmGohiXUhzrTomZz62c8Jw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/kubernetes-fluent-client/-/kubernetes-fluent-client-2.1.0.tgz", + "integrity": "sha512-siF3UtMqWqrt2zr9OmdcsRZ40a3BQ+9TdujLcu936RACexA+XavBCjKxLpV0q0DVe6t4yfL1xH+u0Le5DFyxZQ==", "dependencies": { "@kubernetes/client-node": "1.0.0-rc4", "byline": "5.0.0", @@ -5332,14 +5332,14 @@ } }, "node_modules/pepr": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.21.0.tgz", - "integrity": "sha512-6uEGeJ3t5RAY1NotbsXpkZ2tPoGsQWFHqfrkpjnxC1xwPEIyFWykHZZ6J9ZhtU3fx3SIroT5DlJ5Qchg4OE2SA==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.21.1.tgz", + "integrity": "sha512-H5VDQAOiOv7GjnrLKHU8FTx7V6W2ke2VuGGtWewbSBjvts8tgm/Qq5yzf3Sm8J4yR5J8h/qg7GXNRPwiUqHP1g==", "dependencies": { "@types/ramda": "0.29.9", "express": "4.18.2", "fast-json-patch": "3.1.1", - "kubernetes-fluent-client": "2.0.1", + "kubernetes-fluent-client": "2.1.0", "pino": "8.17.2", "pino-pretty": "10.3.1", "prom-client": "15.1.0", diff --git a/package.json b/package.json index d0012c24e..791353bd9 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "k3d-setup": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'" }, "dependencies": { - "pepr": "0.21.0" + "pepr": "0.21.1" }, "devDependencies": { "@jest/globals": "29.7.0", From acb4803a622e6a26d02b5b064a0878deb03df4f5 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:04:08 -0600 Subject: [PATCH 25/98] update app uds pkg crds --- src/grafana/chart/templates/uds-package.yaml | 23 ++++---- src/loki/chart/templates/uds-package.yaml | 21 ++++---- .../chart/templates/uds-package.yaml | 23 ++++---- .../chart/templates/uds-package.yaml | 53 +++++++++---------- 4 files changed, 57 insertions(+), 63 deletions(-) diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index 4d4a5097c..f599287eb 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -7,18 +7,19 @@ spec: network: expose: - service: grafana + podLabels: + app.kubernetes.io/name: grafana host: grafana gateway: admin port: 80 - policies: - allow: - - direction: Ingress - podLabels: - app: grafana - remoteNamespaceLabels: - app.kubernetes.io/name: tempo - remotePodLabels: - app.kubernetes.io/name: tempo - port: 9090 - protocol: TCP + allow: + - direction: Ingress + podLabels: + app: grafana + remoteNamespaceLabels: + app.kubernetes.io/name: tempo + remotePodLabels: + app.kubernetes.io/name: tempo + port: 9090 + protocol: TCP diff --git a/src/loki/chart/templates/uds-package.yaml b/src/loki/chart/templates/uds-package.yaml index 66e6334bd..1265e1360 100644 --- a/src/loki/chart/templates/uds-package.yaml +++ b/src/loki/chart/templates/uds-package.yaml @@ -5,14 +5,13 @@ metadata: namespace: {{ .Release.Namespace }} spec: network: - policies: - allow: - - direction: Ingress - podLabels: - app: grafana - remoteNamespaceLabels: - app.kubernetes.io/name: tempo - remotePodLabels: - app.kubernetes.io/name: tempo - port: 9090 - protocol: TCP + allow: + - direction: Ingress + podLabels: + app: grafana + remoteNamespaceLabels: + app.kubernetes.io/name: tempo + remotePodLabels: + app.kubernetes.io/name: tempo + port: 9090 + protocol: TCP diff --git a/src/metrics-server/chart/templates/uds-package.yaml b/src/metrics-server/chart/templates/uds-package.yaml index 6409b5dad..28299065a 100644 --- a/src/metrics-server/chart/templates/uds-package.yaml +++ b/src/metrics-server/chart/templates/uds-package.yaml @@ -5,15 +5,14 @@ metadata: namespace: {{ .Release.Namespace }} spec: network: - policies: - allow: - - direction: Egress - remoteGenerated: KubeAPI - podLabels: - app.kubernetes.io/name: metrics-server - - direction: Ingress - podLabels: - app.kubernetes.io/name: metrics-server - remoteNamespaceLabels: - kubernetes.io/metadata.name: "istio-system" - port: 443 + allow: + - direction: Egress + remoteGenerated: KubeAPI + podLabels: + app.kubernetes.io/name: metrics-server + - direction: Ingress + podLabels: + app.kubernetes.io/name: metrics-server + remoteNamespaceLabels: + kubernetes.io/metadata.name: "istio-system" + port: 443 diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml index 1ba9cef2b..eec9dd809 100644 --- a/src/neuvector/chart/templates/uds-package.yaml +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -7,37 +7,32 @@ spec: network: expose: - service: neuvector-service-webui + podLabels: + app: neuvector-manager-pod gateway: admin host: neuvector port: 8443 - policies: - allow: - - direction: Egress - remoteGenerated: KubeAPI - podLabels: - app: neuvector-controller-pod - - direction: Egress - remoteGenerated: KubeAPI - podLabels: - app: neuvector-updater-pod - - direction: Ingress - remoteNamespaceLabels: - app.kubernetes.io/name: monitoring - remotePodLabels: - app: prometheus - podLabels: - app: neuvector-prometheus-exporter-pod - port: 8068 + allow: + # Permit intra-namespace communication + - direction: Ingress + remoteGenerated: IntraNamespace + - direction: Egress + remoteGenerated: IntraNamespace - -# apiVersion: networking.k8s.io/v1 -# kind: NetworkPolicy -# metadata: -# name: allow-istio-ingress -# # namespace: {{ .Release.Namespace }} -# namespace: neuvector -# spec: -# podSelector: -# matchLabels: -# app: neuvector-manager-pod + - direction: Egress + remoteGenerated: KubeAPI + podLabels: + app: neuvector-controller-pod + - direction: Egress + remoteGenerated: KubeAPI + podLabels: + app: neuvector-updater-pod + - direction: Ingress + remoteNamespaceLabels: + app.kubernetes.io/name: monitoring + remotePodLabels: + app: prometheus + podLabels: + app: neuvector-prometheus-exporter-pod + port: 8068 From 18f3676c9188cfd4197a17ad65ed6db1a45cbf84 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:08:48 -0600 Subject: [PATCH 26/98] move controller logic to controllers folder --- .../{istio.ts => controllers/istio/index.ts} | 17 +++++-- .../namespace/index.ts} | 2 +- .../network/allow-egress-dns.ts | 0 .../network/allow-egress-istiod.ts | 0 .../allow-ingress-sidecar-monitoring.ts | 0 .../network/default-deny-all.ts | 0 .../network/generate.ts} | 46 ++++++++++++------- .../{ => controllers}/network/index.ts | 41 ++++++----------- src/pepr/operator/network/README.md | 1 - .../network/allow-egress-within-ns.ts | 16 ------- .../network/allow-ingress-within-ns.ts | 16 ------- 11 files changed, 58 insertions(+), 81 deletions(-) rename src/pepr/operator/{istio.ts => controllers/istio/index.ts} (87%) rename src/pepr/operator/{namespace.ts => controllers/namespace/index.ts} (96%) rename src/pepr/operator/{ => controllers}/network/allow-egress-dns.ts (100%) rename src/pepr/operator/{ => controllers}/network/allow-egress-istiod.ts (100%) rename src/pepr/operator/{ => controllers}/network/allow-ingress-sidecar-monitoring.ts (100%) rename src/pepr/operator/{ => controllers}/network/default-deny-all.ts (100%) rename src/pepr/operator/{network/builder.ts => controllers/network/generate.ts} (77%) rename src/pepr/operator/{ => controllers}/network/index.ts (68%) delete mode 100644 src/pepr/operator/network/README.md delete mode 100644 src/pepr/operator/network/allow-egress-within-ns.ts delete mode 100644 src/pepr/operator/network/allow-ingress-within-ns.ts diff --git a/src/pepr/operator/istio.ts b/src/pepr/operator/controllers/istio/index.ts similarity index 87% rename from src/pepr/operator/istio.ts rename to src/pepr/operator/controllers/istio/index.ts index de34ed71a..b917f4cd4 100644 --- a/src/pepr/operator/istio.ts +++ b/src/pepr/operator/controllers/istio/index.ts @@ -1,8 +1,12 @@ import { K8s, Log } from "pepr"; -import { UDSConfig } from "../config"; -import { Gateway, UDSPackage, getOwnerRef } from "./crd"; -import { HTTPRoute, TCPRoute, VirtualService } from "./crd/generated/istio/virtualservice-v1beta1"; +import { UDSConfig } from "../../../config"; +import { Gateway, UDSPackage, getOwnerRef } from "../../crd"; +import { + HTTPRoute, + TCPRoute, + VirtualService, +} from "../../crd/generated/istio/virtualservice-v1beta1"; /** * Creates a VirtualService for each exposed service in the package @@ -17,6 +21,8 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { // Get the list of exposed services const exposeList = pkg.spec?.network?.expose ?? []; + const payloads: VirtualService[] = []; + // Iterate over each exposed service for (const expose of exposeList) { const { gateway = Gateway.Tenant, host, port, service, mode } = expose; @@ -64,6 +70,8 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { // Apply the VirtualService and force overwrite any existing policy await K8s(VirtualService).Apply(payload, { force: true }); + + payloads.push(payload); } // Get all related VirtualServices in the namespace @@ -82,4 +90,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { Log.debug(vs, `Deleting orphaned VirtualService ${vs.metadata!.name}`); await K8s(VirtualService).Delete(vs); } + + // Return the list of generated VirtualServices + return payloads; } diff --git a/src/pepr/operator/namespace.ts b/src/pepr/operator/controllers/namespace/index.ts similarity index 96% rename from src/pepr/operator/namespace.ts rename to src/pepr/operator/controllers/namespace/index.ts index 5d00c8938..600e77cf6 100644 --- a/src/pepr/operator/namespace.ts +++ b/src/pepr/operator/controllers/namespace/index.ts @@ -1,5 +1,5 @@ import { K8s, kind } from "pepr"; -import { UDSPackage } from "./crd"; +import { UDSPackage } from "../../crd"; /** * Syncs the package namespace istio-injection label and adds a label for the package name diff --git a/src/pepr/operator/network/allow-egress-dns.ts b/src/pepr/operator/controllers/network/allow-egress-dns.ts similarity index 100% rename from src/pepr/operator/network/allow-egress-dns.ts rename to src/pepr/operator/controllers/network/allow-egress-dns.ts diff --git a/src/pepr/operator/network/allow-egress-istiod.ts b/src/pepr/operator/controllers/network/allow-egress-istiod.ts similarity index 100% rename from src/pepr/operator/network/allow-egress-istiod.ts rename to src/pepr/operator/controllers/network/allow-egress-istiod.ts diff --git a/src/pepr/operator/network/allow-ingress-sidecar-monitoring.ts b/src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts similarity index 100% rename from src/pepr/operator/network/allow-ingress-sidecar-monitoring.ts rename to src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts diff --git a/src/pepr/operator/network/default-deny-all.ts b/src/pepr/operator/controllers/network/default-deny-all.ts similarity index 100% rename from src/pepr/operator/network/default-deny-all.ts rename to src/pepr/operator/controllers/network/default-deny-all.ts diff --git a/src/pepr/operator/network/builder.ts b/src/pepr/operator/controllers/network/generate.ts similarity index 77% rename from src/pepr/operator/network/builder.ts rename to src/pepr/operator/controllers/network/generate.ts index e4d9704e5..2672364c0 100644 --- a/src/pepr/operator/network/builder.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -1,19 +1,19 @@ import { V1APIGroup, V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; import { K8s, Log, kind } from "pepr"; -import { Allow, UDSPackage } from "../crd"; -import { RemoteGenerated } from "../crd/generated/package-v1alpha1"; +import { Allow, UDSPackage } from "../../crd"; +import { RemoteGenerated } from "../../crd/generated/package-v1alpha1"; let apiServerPeers: V1NetworkPolicyPeer[]; -export async function builder( +export async function generate( namespace: string, pkg: UDSPackage, policy: Allow, idx: number, ): Promise { const pkgName = pkg.metadata!.name!; - const target = Object.values(policy.podLabels!).join("-"); + const target = Object.values(policy.podLabels || ["all-pods"]).join("-"); // Create a unique name for the NetworkPolicy based on the package name, index, direction, pod labels, and port const name = `allow-${policy.direction}-${target}-${pkgName}-${idx}`.toLowerCase(); @@ -39,7 +39,25 @@ export async function builder( }; // Create the remote (peer) to match against - let peers: V1NetworkPolicyPeer[]; + let peers: V1NetworkPolicyPeer[] = []; + + // Add the remoteNamespaceLabels if they exist + if (policy.remoteNamespaceLabels) { + peers.push({ + namespaceSelector: { + matchLabels: policy.remoteNamespaceLabels, + }, + }); + } + + // Add the remotePodLabels if they exist + if (policy.remotePodLabels) { + peers.push({ + podSelector: { + matchLabels: policy.remotePodLabels, + }, + }); + } // Check if remoteGenerated is set switch (policy.remoteGenerated) { @@ -48,18 +66,14 @@ export async function builder( peers = await generateKubeAPI(); break; - // Default to namespace and pod labels - default: - peers = [ - { - namespaceSelector: { - matchLabels: policy.remoteNamespaceLabels, - }, - podSelector: { - matchLabels: policy.remotePodLabels, - }, + // IntraNamespace maps to the current namespace + case RemoteGenerated.IntraNamespace: + peers.push({ + podSelector: { + matchLabels: {}, }, - ]; + }); + break; } // Create the port to match against diff --git a/src/pepr/operator/network/index.ts b/src/pepr/operator/controllers/network/index.ts similarity index 68% rename from src/pepr/operator/network/index.ts rename to src/pepr/operator/controllers/network/index.ts index c3e11b4a2..bdde74913 100644 --- a/src/pepr/operator/network/index.ts +++ b/src/pepr/operator/controllers/network/index.ts @@ -1,19 +1,16 @@ import { K8s, Log, kind } from "pepr"; -import { Allow, Direction, DisableDefault, Gateway, UDSPackage, getOwnerRef } from "../crd"; +import { Allow, Direction, Gateway, UDSPackage, getOwnerRef } from "../../crd"; import { allowEgressDNS } from "./allow-egress-dns"; import { allowEgressIstiod } from "./allow-egress-istiod"; -import { allowEgressWithinNS } from "./allow-egress-within-ns"; import { allowIngressSidecarMonitoring } from "./allow-ingress-sidecar-monitoring"; -import { allowIngressWithinNS } from "./allow-ingress-within-ns"; import { defaultDenyAll } from "./default-deny-all"; // Import the NetworkPolicy transforms webhook -import { builder } from "./builder"; +import { generate } from "./generate"; export async function networkPolicies(pkg: UDSPackage, namespace: string) { - const disabled = pkg.spec?.network?.policies?.disableDefaults ?? []; - const customPolicies = pkg.spec?.network?.policies?.allow ?? []; + const customPolicies = pkg.spec?.network?.allow ?? []; // Get the current generation of the package const generation = (pkg.metadata?.generation ?? 0).toString(); @@ -21,40 +18,25 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { const policies = [ // All traffic must be explicitly allowed defaultDenyAll(namespace), + + // Allow DNS lookups + allowEgressDNS(namespace), + // Istio rules allowEgressIstiod(namespace), allowIngressSidecarMonitoring(namespace), ]; - // Allow DNS lookups - if (!disabled.includes(DisableDefault.DNSLookup)) { - policies.push(allowEgressDNS(namespace)); - } - - // Allow all traffic within the namespace - if (!disabled.includes(DisableDefault.PermissiveNamespace)) { - policies.push(allowEgressWithinNS(namespace)); - policies.push(allowIngressWithinNS(namespace)); - } - // Process custom policies for (const [idx, policy] of customPolicies.entries()) { - const generatedPolicy = await builder(namespace, pkg, policy, idx); + const generatedPolicy = await generate(namespace, pkg, policy, idx); policies.push(generatedPolicy); } // Generate NetworkPolicies for any VirtualServices that are generated const exposeList = pkg.spec?.network?.expose ?? []; for (const [idx, expose] of exposeList.entries()) { - const { gateway = Gateway.Tenant, port, service } = expose; - - let podLabels: Record = {}; - try { - const svcDef = await K8s(kind.Service).InNamespace(namespace).Get(service); - podLabels = svcDef.spec?.selector as Record; - } catch (e) { - Log.error(e, `Unable to load the service ${namespace}/${service}`); - } + const { gateway = Gateway.Tenant, port, podLabels } = expose; // Create the NetworkPolicy for the VirtualService const policy: Allow = { @@ -70,7 +52,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { }; // Generate the policy with a base index of 1000 - const generatedPolicy = await builder(namespace, pkg, policy, 1000 + idx); + const generatedPolicy = await generate(namespace, pkg, policy, 1000 + idx); policies.push(generatedPolicy); } @@ -105,4 +87,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { Log.debug(vs, `Deleting orphaned VirtualService ${vs.metadata!.name}`); await K8s(kind.NetworkPolicy).Delete(vs); } + + // Return the list of policies + return policies; } diff --git a/src/pepr/operator/network/README.md b/src/pepr/operator/network/README.md deleted file mode 100644 index 3b11be709..000000000 --- a/src/pepr/operator/network/README.md +++ /dev/null @@ -1 +0,0 @@ -This folder contains UDS Core common network policies for the cluster. They establish a baseline security posture that should be used in conjunction with individual allow policies for each workload. diff --git a/src/pepr/operator/network/allow-egress-within-ns.ts b/src/pepr/operator/network/allow-egress-within-ns.ts deleted file mode 100644 index b8e017247..000000000 --- a/src/pepr/operator/network/allow-egress-within-ns.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { kind } from "pepr"; - -export function allowEgressWithinNS(namespace: string): kind.NetworkPolicy { - return { - apiVersion: "networking.k8s.io/v1", - kind: "NetworkPolicy", - metadata: { - name: "allow-egress-within-ns", - namespace, - }, - spec: { - podSelector: {}, - policyTypes: ["Egress"], - }, - }; -} diff --git a/src/pepr/operator/network/allow-ingress-within-ns.ts b/src/pepr/operator/network/allow-ingress-within-ns.ts deleted file mode 100644 index 9c0b9e186..000000000 --- a/src/pepr/operator/network/allow-ingress-within-ns.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { kind } from "pepr"; - -export function allowIngressWithinNS(namespace: string): kind.NetworkPolicy { - return { - apiVersion: "networking.k8s.io/v1", - kind: "NetworkPolicy", - metadata: { - name: "allow-ingress-within-ns", - namespace, - }, - spec: { - podSelector: {}, - policyTypes: ["Ingress"], - }, - }; -} From f98ecb97e563909738563d4607271f5ea2ef6a8d Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:19:49 -0600 Subject: [PATCH 27/98] istio ns label brittleness --- .../operator/controllers/namespace/index.ts | 3 ++ src/test/app-admin.yaml | 30 +++++++++---------- src/test/app-tenant.yaml | 30 +++++++++---------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/pepr/operator/controllers/namespace/index.ts b/src/pepr/operator/controllers/namespace/index.ts index 600e77cf6..88b981575 100644 --- a/src/pepr/operator/controllers/namespace/index.ts +++ b/src/pepr/operator/controllers/namespace/index.ts @@ -31,6 +31,9 @@ export async function syncNamespace(pkg: UDSPackage) { }, { force: true }, ); + + // @todo: Add a finalizer to remove the label when the package is deleted + // @todo: Check for pods without sidecars and address them } return pkg.metadata.namespace; diff --git a/src/test/app-admin.yaml b/src/test/app-admin.yaml index ed36c2b66..57bcc5a26 100644 --- a/src/test/app-admin.yaml +++ b/src/test/app-admin.yaml @@ -5,6 +5,21 @@ metadata: labels: zarf.dev/agent: ignore --- +apiVersion: uds.dev/v1alpha1 +kind: Package +metadata: + name: httpbin + namespace: test-admin-app +spec: + network: + expose: + - service: httpbin + podLabels: + app: httpbin + gateway: admin + host: demo + port: 8000 +--- apiVersion: v1 kind: ServiceAccount metadata: @@ -24,21 +39,6 @@ spec: selector: app: httpbin --- -apiVersion: uds.dev/v1alpha1 -kind: Package -metadata: - name: httpbin - namespace: test-admin-app -spec: - network: - expose: - - service: httpbin - podLabels: - app: httpbin - gateway: admin - host: demo - port: 8000 ---- apiVersion: apps/v1 kind: Deployment metadata: diff --git a/src/test/app-tenant.yaml b/src/test/app-tenant.yaml index 5e5c3f162..ad5509527 100644 --- a/src/test/app-tenant.yaml +++ b/src/test/app-tenant.yaml @@ -5,6 +5,21 @@ metadata: labels: zarf.dev/agent: ignore --- +apiVersion: uds.dev/v1alpha1 +kind: Package +metadata: + name: httpbin + namespace: test-app +spec: + network: + expose: + - service: httpbin + podLabels: + app: httpbin + gateway: tenant + host: demo + port: 8000 +--- apiVersion: v1 kind: ServiceAccount metadata: @@ -27,21 +42,6 @@ spec: selector: app: httpbin --- -apiVersion: uds.dev/v1alpha1 -kind: Package -metadata: - name: httpbin - namespace: test-app -spec: - network: - expose: - - service: httpbin - podLabels: - app: httpbin - gateway: tenant - host: demo - port: 8000 ---- apiVersion: apps/v1 kind: Deployment metadata: From 3e492e3f9b04c2c82af2b070ea844adc82d186cd Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:21:28 -0600 Subject: [PATCH 28/98] create separate reconciler file + use PathStatus() for status updates --- src/pepr/operator/index.ts | 39 ++++------------- src/pepr/operator/reconciler.ts | 74 +++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 32 deletions(-) create mode 100644 src/pepr/operator/reconciler.ts diff --git a/src/pepr/operator/index.ts b/src/pepr/operator/index.ts index 2fae32c81..13be13f4f 100644 --- a/src/pepr/operator/index.ts +++ b/src/pepr/operator/index.ts @@ -1,12 +1,9 @@ -import { Capability, Log } from "pepr"; +import { Capability } from "pepr"; -import { UDSConfig } from "../config"; import { UDSPackage } from "./crd"; import "./crd/register"; import { validator } from "./crd/validator"; -import { virtualService } from "./istio"; -import { syncNamespace } from "./namespace"; -import { networkPolicies } from "./network"; +import { Queue } from "./enque"; export const operator = new Capability({ name: "uds-core-operator", @@ -15,33 +12,11 @@ export const operator = new Capability({ export const { Store, When } = operator; +const queue = new Queue(); + When(UDSPackage) .IsCreatedOrUpdated() + // Advanced CR validation .Validate(validator) - .Watch(async pkg => { - if (!pkg.metadata?.namespace) { - Log.error(pkg, `Invalid Package definition`); - return; - } - - Log.debug(pkg, `Processing Package ${pkg.metadata.namespace}/${pkg.metadata.name}`); - - // Configure the namespace and namespace-wide network policies - try { - const namespace = await syncNamespace(pkg); - - await networkPolicies(pkg, namespace); - - // Only configure the VirtualService if Istio is installed - if (UDSConfig.istioInstalled) { - await virtualService(pkg, namespace); - } else { - Log.warn(`Istio is not installed, skipping ${pkg.metadata.name} VirtualService.`); - } - } catch (e) { - Log.error( - e, - `Error completing configuration for ${pkg.metadata.namespace}/${pkg.metadata.name}`, - ); - } - }); + // Enqueue the package for processing + .Watch(pkg => queue.enqueue(pkg)); diff --git a/src/pepr/operator/reconciler.ts b/src/pepr/operator/reconciler.ts new file mode 100644 index 000000000..c8fafc33f --- /dev/null +++ b/src/pepr/operator/reconciler.ts @@ -0,0 +1,74 @@ +import { K8s, Log } from "pepr"; + +import { UDSConfig } from "../config"; +import { virtualService } from "./controllers/istio"; +import { syncNamespace } from "./controllers/namespace"; +import { networkPolicies } from "./controllers/network"; +import { Phase, Status, UDSPackage } from "./crd"; +import { VirtualService } from "./crd/generated/istio/virtualservice-v1beta1"; + +/** + * The reconciler is called from the queue and is responsible for reconciling the state of the package + * with the cluster. This includes creating the namespace, network policies and virtual services. + * + * @param pkg the package to reconcile + */ +export async function reconciler(pkg: UDSPackage) { + if (!pkg.metadata?.namespace) { + Log.error(pkg, `Invalid Package definition`); + return; + } + + const isPending = pkg.status?.phase === Phase.Pending; + const isCurrentGeneration = pkg.metadata.generation === pkg.status?.observedGeneration; + + if (isPending || isCurrentGeneration) { + Log.debug(pkg, `Skipping pending or completed package`); + return; + } + + Log.debug(pkg, `Processing Package ${pkg.metadata.namespace}/${pkg.metadata.name}`); + + // Configure the namespace and namespace-wide network policies + try { + void updateStatus(pkg, { phase: Phase.Pending }); + + const namespace = await syncNamespace(pkg); + + const netPol = await networkPolicies(pkg, namespace); + + // Only configure the VirtualService if Istio is installed + let vs: VirtualService[] = []; + if (UDSConfig.istioInstalled) { + vs = await virtualService(pkg, namespace); + } else { + Log.warn(`Istio is not installed, skipping ${pkg.metadata.name} VirtualService.`); + } + + void updateStatus(pkg, { + phase: Phase.Ready, + endpoints: vs.map(v => v.spec!.hosts!.join(",")), + networkPolicyCount: netPol.length, + observedGeneration: pkg.metadata.generation, + }); + } catch (e) { + Log.error(e, `Error configuring for ${pkg.metadata.namespace}/${pkg.metadata.name}`); + void updateStatus(pkg, { phase: Phase.Failed }); + } +} + +/** + * Updates the status of the package + * + * @param pkg The package to update + * @param status The new status + */ +async function updateStatus(pkg: UDSPackage, status: Status) { + await K8s(UDSPackage).PatchStatus({ + metadata: { + name: pkg.metadata!.name, + namespace: pkg.metadata!.namespace, + }, + status, + }); +} From a4b79e39ff7ea3da3db5b569941d7da714ffed10 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:22:07 -0600 Subject: [PATCH 29/98] add enqueue to control reconcile flow --- src/pepr/operator/enque.ts | 68 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/pepr/operator/enque.ts diff --git a/src/pepr/operator/enque.ts b/src/pepr/operator/enque.ts new file mode 100644 index 000000000..4b37edc8b --- /dev/null +++ b/src/pepr/operator/enque.ts @@ -0,0 +1,68 @@ +import { Log } from "pepr"; + +import { UDSPackage } from "./crd"; +import { reconciler } from "./reconciler"; + +type QueueItem = { + pkg: UDSPackage; + resolve: (value: void | PromiseLike) => void; + reject: (reason?: string) => void; +}; + +/** + * Queue is a FIFO queue for reconciling packages + */ +export class Queue { + #queue: QueueItem[] = []; + #pendingPromise = false; + + /** + * Enqueue adds a package to the queue and returns a promise that resolves when the package is + * reconciled. + * + * @param pkg The package to reconcile + * @returns A promise that resolves when the package is reconciled + */ + enqueue(pkg: UDSPackage) { + Log.debug(`Enqueueing ${pkg.metadata!.namespace}/${pkg.metadata!.name}`); + return new Promise((resolve, reject) => { + this.#queue.push({ pkg, resolve, reject }); + return this.#dequeue(); + }); + } + + /** + * Dequeue reconciles the next package in the queue + * + * @returns A promise that resolves when the package is reconciled + */ + async #dequeue() { + // If there is a pending promise, do nothing + if (this.#pendingPromise) return false; + + // Take the next item from the queue + const item = this.#queue.shift(); + + // If there is no item, do nothing + if (!item) return false; + + try { + // Set the pending promise flag to avoid concurrent reconciliations + this.#pendingPromise = true; + + // Reconcile the package + await reconciler(item.pkg); + + // Reset the pending promise flag and resolve the promise + this.#pendingPromise = false; + item.resolve(); + } catch (e) { + // Reset the pending promise flag and reject the promise on error + this.#pendingPromise = false; + item.reject(e); + } finally { + // After the package is reconciled, dequeue the next package + await this.#dequeue(); + } + } +} From 87f38e41735140af6d6e7d873b90ba972409df74 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:22:35 -0600 Subject: [PATCH 30/98] register the CRD for watch or dev mode --- src/pepr/operator/crd/register.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pepr/operator/crd/register.ts b/src/pepr/operator/crd/register.ts index 3332753f1..df3fdb665 100644 --- a/src/pepr/operator/crd/register.ts +++ b/src/pepr/operator/crd/register.ts @@ -2,8 +2,8 @@ import { K8s, Log, kind } from "pepr"; import { v1alpha1 } from "./sources/v1alpha1"; -// Register the CRD if we're in watch mode -if (process.env.PEPR_WATCH_MODE === "true") { +// Register the CRD if we're in watch or dev mode +if (process.env.PEPR_WATCH_MODE === "true" || process.env.PEPR_MODE === "dev") { K8s(kind.CustomResourceDefinition) .Apply( { From f4e5fc5bd74954e7f52f030d8830390bb3e8e686 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:23:25 -0600 Subject: [PATCH 31/98] update CRD def --- .../crd/generated/package-v1alpha1.ts | 122 ++++++------- src/pepr/operator/crd/index.ts | 5 +- src/pepr/operator/crd/sources/v1alpha1.ts | 162 ++++++++++-------- src/pepr/operator/crd/validator.ts | 2 +- 4 files changed, 159 insertions(+), 132 deletions(-) diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index 5beb27a09..9a6bd14ed 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -4,7 +4,7 @@ import { GenericKind, RegisterKind } from "kubernetes-fluent-client"; export class Package extends GenericKind { spec?: Spec; - status?: { [key: string]: unknown }; + status?: Status; } export interface Spec { @@ -19,67 +19,13 @@ export interface Spec { */ export interface Network { /** - * Expose a service on an Istio Gateway - */ - expose?: Expose[]; - /** - * NetworkPolicy configuration for the package - */ - policies?: Policies; -} - -export interface Expose { - /** - * The name of the gateway to expose the service on (default: tenant) - */ - gateway?: Gateway; - /** - * The hostname to expose the service on - */ - host: string; - /** - * The mode to use when exposing the service - */ - mode?: Mode; - /** - * The port number to expose - */ - port: number; - /** - * The name of the service to expose - */ - service: string; -} - -/** - * The name of the gateway to expose the service on (default: tenant) - */ -export enum Gateway { - Admin = "admin", - Passthrough = "passthrough", - Tenant = "tenant", -} - -/** - * The mode to use when exposing the service - */ -export enum Mode { - HTTP = "http", - TCP = "tcp", -} - -/** - * NetworkPolicy configuration for the package - */ -export interface Policies { - /** - * Allow specific traffic + * Allow specific traffic (namespace will have a default-deny policy) */ allow?: Allow[]; /** - * Disable default UDS NetworkPolicy configurations + * Expose a service on an Istio Gateway */ - disableDefaults?: DisableDefault[]; + expose?: Expose[]; } export interface Allow { @@ -139,12 +85,66 @@ export enum Protocol { * Custom generated remote selector for the policy */ export enum RemoteGenerated { + IntraNamespace = "IntraNamespace", KubeAPI = "KubeAPI", } -export enum DisableDefault { - DNSLookup = "dnsLookup", - PermissiveNamespace = "permissiveNamespace", +export interface Expose { + /** + * The name of the gateway to expose the service on (default: tenant) + */ + gateway?: Gateway; + /** + * The hostname to expose the service on + */ + host: string; + /** + * The mode to use when exposing the service + */ + mode?: Mode; + /** + * Labels to match pods in the namespace to apply the policy to. Leave empty to apply to all + * pods in the namespace + */ + podLabels: { [key: string]: string }; + /** + * The port number to expose + */ + port: number; + /** + * The name of the service to expose + */ + service: string; +} + +/** + * The name of the gateway to expose the service on (default: tenant) + */ +export enum Gateway { + Admin = "admin", + Passthrough = "passthrough", + Tenant = "tenant", +} + +/** + * The mode to use when exposing the service + */ +export enum Mode { + HTTP = "http", + TCP = "tcp", +} + +export interface Status { + endpoints?: string[]; + networkPolicyCount?: number; + observedGeneration?: number; + phase?: Phase; +} + +export enum Phase { + Failed = "Failed", + Pending = "Pending", + Ready = "Ready", } RegisterKind(Package, { diff --git a/src/pepr/operator/crd/index.ts b/src/pepr/operator/crd/index.ts index a742b8a0e..a7c6320a8 100644 --- a/src/pepr/operator/crd/index.ts +++ b/src/pepr/operator/crd/index.ts @@ -4,9 +4,10 @@ import { Package as UDSPackage } from "./generated/package-v1alpha1"; export { Allow, - DisableDefault, - Gateway, Direction, + Gateway, + Phase, + Status, Package as UDSPackage, } from "./generated/package-v1alpha1"; diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index 3c4cc835d..a0e46a7aa 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -11,6 +11,18 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { description: "The status of the package", jsonPath: ".status.phase", }, + { + name: "Endpoints", + type: "string", + description: "Service endpoints exposed by the package", + jsonPath: ".status.endpoints", + }, + { + name: "Network Policies", + type: "integer", + description: "The number of network policies created by the package", + jsonPath: ".status.networkPolicyCount", + }, { name: "Age", type: "date", @@ -18,12 +30,33 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { jsonPath: ".metadata.creationTimestamp", }, ], + subresources: { + status: {}, + }, schema: { openAPIV3Schema: { type: "object", properties: { status: { type: "object", + properties: { + observedGeneration: { + type: "integer", + }, + phase: { + enum: ["Pending", "Ready", "Failed"], + type: "string", + }, + endpoints: { + type: "array", + items: { + type: "string", + }, + }, + networkPolicyCount: { + type: "integer", + }, + }, // JS Lib uses _ instead of - which makes the API Server very sad "x-kubernetes-preserve-unknown-fields": true, } as V1JSONSchemaProps, @@ -40,12 +73,20 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { description: "Expose a service on an Istio Gateway", items: { type: "object", - required: ["service", "host", "port"], + required: ["service", "podLabels", "host", "port"], properties: { service: { description: "The name of the service to expose", type: "string", }, + podLabels: { + description: + "Labels to match pods in the namespace to apply the policy to. Leave empty to apply to all pods in the namespace", + type: "object", + additionalProperties: { + type: "string", + }, + }, port: { description: "The port number to expose", minimum: 1, @@ -72,78 +113,63 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { }, }, }, - policies: { - type: "object", - description: "NetworkPolicy configuration for the package", - properties: { - disableDefaults: { - description: "Disable default UDS NetworkPolicy configurations", - type: "array", - items: { + allow: { + description: "Allow specific traffic (namespace will have a default-deny policy)", + type: "array", + items: { + type: "object", + required: ["direction"], + properties: { + labels: { + description: "The labels to apply to the policy", + type: "object", + additionalProperties: { + type: "string", + }, + }, + direction: { + description: "The direction of the traffic", + enum: ["Ingress", "Egress"], type: "string", - enum: ["dnsLookup", "permissiveNamespace"], }, - }, - allow: { - description: "Allow specific traffic", - type: "array", - items: { + podLabels: { + description: + "Labels to match pods in the namespace to apply the policy to. Leave empty to apply to all pods in the namespace", + type: "object", + additionalProperties: { + type: "string", + }, + }, + remoteNamespaceLabels: { + description: "The remote namespace selector labels", + type: "object", + additionalProperties: { + type: "string", + }, + }, + remotePodLabels: { + description: "The remote pod selector labels", type: "object", - required: ["direction"], - properties: { - labels: { - description: "The labels to apply to the policy", - type: "object", - additionalProperties: { - type: "string", - }, - }, - direction: { - description: "The direction of the traffic", - enum: ["Ingress", "Egress"], - type: "string", - }, - podLabels: { - description: - "Labels to match pods in the namespace to apply the policy to. Leave empty to apply to all pods in the namespace", - type: "object", - additionalProperties: { - type: "string", - }, - }, - remoteNamespaceLabels: { - description: "The remote namespace selector labels", - type: "object", - additionalProperties: { - type: "string", - }, - }, - remotePodLabels: { - description: "The remote pod selector labels", - type: "object", - additionalProperties: { - type: "string", - }, - }, - remoteGenerated: { - description: "Custom generated remote selector for the policy", - type: "string", - enum: ["KubeAPI"], - }, - port: { - description: "The port to allow", - minimum: 1, - maximum: 65535, - type: "number", - }, - protocol: { - description: - "The protocol (TCP, UDP, or SCTP) to allow. Defaults to TCP.", - type: "string", - enum: ["TCP", "UDP", "SCTP"], - }, + additionalProperties: { + type: "string", }, }, + remoteGenerated: { + description: "Custom generated remote selector for the policy", + type: "string", + enum: ["KubeAPI", "IntraNamespace"], + }, + port: { + description: "The port to allow", + minimum: 1, + maximum: 65535, + type: "number", + }, + protocol: { + description: "The protocol (TCP, UDP, or SCTP) to allow. Defaults to TCP.", + type: "string", + enum: ["TCP", "UDP", "SCTP"], + }, }, }, }, diff --git a/src/pepr/operator/crd/validator.ts b/src/pepr/operator/crd/validator.ts index eff6d6f26..9db422e48 100644 --- a/src/pepr/operator/crd/validator.ts +++ b/src/pepr/operator/crd/validator.ts @@ -11,7 +11,7 @@ export async function validator(req: PeprValidateRequest) { } // Ensure the name of each network policy is unique - const networkPolicy = req.Raw.spec?.network?.policies?.allow ?? []; + const networkPolicy = req.Raw.spec?.network?.allow ?? []; for (const policy of networkPolicy) { // remoteGenerated cannot be combined with remoteNamespaceLabels or remotePodLabels From 774976ee09492af50727dc8c3d5a3e0aa060bfbb Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 03:41:05 -0600 Subject: [PATCH 32/98] leave bully.ts there for now until we decided if its worth adding a stress test --- src/pepr/operator/bully.ts | 53 ++++++++++++++++++++++++++++++++++++++ src/pepr/operator/test.ts | 36 -------------------------- 2 files changed, 53 insertions(+), 36 deletions(-) create mode 100644 src/pepr/operator/bully.ts delete mode 100644 src/pepr/operator/test.ts diff --git a/src/pepr/operator/bully.ts b/src/pepr/operator/bully.ts new file mode 100644 index 000000000..e2762ca40 --- /dev/null +++ b/src/pepr/operator/bully.ts @@ -0,0 +1,53 @@ +import { K8s, kind } from "pepr"; +import { UDSPackage } from "./crd"; +import { Direction, Gateway } from "./crd/generated/package-v1alpha1"; + +const intervalMS = 50; +let inc = 0; + +setInterval(async () => { + const namespace = `bully-${inc++}`; + + await K8s(kind.Namespace).Apply({ + metadata: { + name: namespace, + }, + }); + + const pkg = await K8s(UDSPackage).Apply({ + metadata: { + name: `random-${Math.random() * 1000}`, + namespace, + }, + spec: { + network: { + expose: [ + { + gateway: Gateway.Tenant, + service: "test", + port: 80, + host: `test-${Math.random() * 1000}`, + podLabels: { + app: "some-cool-test", + }, + }, + ], + allow: [ + { + direction: Direction.Ingress, + labels: { + demo: "test", + }, + podLabels: { + app: "some-cool-test", + }, + port: 80, + remoteNamespaceLabels: {}, + }, + ], + }, + }, + }); + + console.log(pkg); +}, intervalMS); diff --git a/src/pepr/operator/test.ts b/src/pepr/operator/test.ts deleted file mode 100644 index 209af92ec..000000000 --- a/src/pepr/operator/test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { K8s } from "pepr"; -import { UDSPackage } from "./crd"; -import { Direction } from "./crd/generated/package-v1alpha1"; - -K8s(UDSPackage) - .Apply({ - metadata: { - name: "testing-123", - namespace: "demo", - }, - spec: { - network: { - policies: { - allow: [ - { - direction: Direction.Ingress, - labels: { - demo: "test", - }, - podLabels: { - app: "some-cool-test", - }, - port: 80, - remoteNamespaceLabels: {}, - }, - ], - }, - }, - }, - }) - .then(pkg => { - console.log(pkg); - }) - .catch(err => { - console.error(err); - }); From 901665983e51d90273d87c43c17999fae3907bad Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 3 Jan 2024 17:24:28 -0600 Subject: [PATCH 33/98] update renovate tag for zarf init pkg --- bundles/k3d-istio/uds-bundle.yaml | 2 +- bundles/k3d-standard/uds-bundle.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/k3d-istio/uds-bundle.yaml b/bundles/k3d-istio/uds-bundle.yaml index 6eebc9853..afdb48e93 100644 --- a/bundles/k3d-istio/uds-bundle.yaml +++ b/bundles/k3d-istio/uds-bundle.yaml @@ -30,7 +30,7 @@ packages: - name: init repository: ghcr.io/defenseunicorns/packages/init - # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver + # renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver ref: v0.31.4 - name: core-istio diff --git a/bundles/k3d-standard/uds-bundle.yaml b/bundles/k3d-standard/uds-bundle.yaml index 85f957c4f..ae94ca7f4 100644 --- a/bundles/k3d-standard/uds-bundle.yaml +++ b/bundles/k3d-standard/uds-bundle.yaml @@ -30,7 +30,7 @@ packages: - name: init repository: ghcr.io/defenseunicorns/packages/init - # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver + # renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver ref: v0.31.4 - name: core From d29fca82c7d7b4e487203b6b125001aa0f001d13 Mon Sep 17 00:00:00 2001 From: Megamind <882485+jeff-mccoy@users.noreply.github.com> Date: Wed, 3 Jan 2024 17:24:55 -0600 Subject: [PATCH 34/98] Update src/pepr/istio/index.ts Co-authored-by: Micah Nagel --- src/pepr/istio/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/istio/index.ts b/src/pepr/istio/index.ts index 6b377f912..a3a5d1fbb 100644 --- a/src/pepr/istio/index.ts +++ b/src/pepr/istio/index.ts @@ -20,7 +20,7 @@ When(a.Pod) .WithLabel("batch.kubernetes.io/job-name") .WithLabel("service.istio.io/canonical-name") .Watch(async pod => { - Log.info(pod, `Processing Pod ${pod.metadata?.namespace}/${pod.metadata?.name}`); + Log.info(pod, `Processing Pod ${pod.metadata?.namespace}/${pod.metadata?.name} for istio job termination`); if (!pod.metadata?.name || !pod.metadata.namespace) { Log.error(pod, `Invalid Pod definition`); From 1061ad12ea46003dd18ccd1d43c4efec0ca8909c Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 13:07:30 -0600 Subject: [PATCH 35/98] get apiserver address for netpols from endpointslices vs `/api` --- .../operator/controllers/network/generate.ts | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index 2672364c0..cc06d9e8e 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -1,4 +1,4 @@ -import { V1APIGroup, V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; +import { V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; import { K8s, Log, kind } from "pepr"; import { Allow, UDSPackage } from "../../crd"; @@ -26,7 +26,7 @@ export async function generate( name, namespace, labels: { - "uds/builder": "true", + "uds/generator": "true", ...policy.labels, }, }, @@ -64,6 +64,7 @@ export async function generate( // KubeAPI maps to the Kubernetes API server case RemoteGenerated.KubeAPI: peers = await generateKubeAPI(); + generated.metadata!.labels!["uds/generated"] = "kubeapi"; break; // IntraNamespace maps to the current namespace @@ -107,29 +108,19 @@ async function generateKubeAPI(): Promise { try { // Read the API server endpoints from the cluster - const { serverAddressByClientCIDRs } = await K8s(V1APIGroup).Raw("/api"); + const { endpoints } = await K8s(kind.EndpointSlice).InNamespace("default").Get("kubernetes"); - const peers = serverAddressByClientCIDRs?.flatMap(s => { - // Parse the value to get the host - const match = s.serverAddress.match(/^(?[^:]+):(?\d+)$/); + const peers = endpoints?.flatMap(e => e.addresses); - // Throw an error if the host is not found - if (!match?.groups?.host) { - throw new Error(`Unable to parse serverAddress: ${s.serverAddress}`); - } - - // Otherwise, add the ipBlock to the peers map - return { + // If the peers are found, cache and return them + if (peers?.length) { + apiServerPeers = peers.flatMap(ip => ({ ipBlock: { - cidr: `${match.groups.host}/32`, + cidr: `${ip}/32`, }, - }; - }); + })); - // If the peers are found, cache and return them - if (peers?.length) { - apiServerPeers = peers; - return peers; + return apiServerPeers; } } catch (err) { Log.debug(err); From ab680926d94cd2925218cd3979403fecbc2b3218 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 13:41:31 -0600 Subject: [PATCH 36/98] update name pattern for netpols --- .../controllers/network/allow-egress-dns.ts | 2 +- .../network/allow-egress-istiod.ts | 2 +- .../allow-ingress-sidecar-monitoring.ts | 2 +- .../operator/controllers/network/generate.ts | 4 +--- .../operator/controllers/network/index.ts | 21 ++++++++++++------- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/pepr/operator/controllers/network/allow-egress-dns.ts b/src/pepr/operator/controllers/network/allow-egress-dns.ts index 963a04cff..aa040ecf5 100644 --- a/src/pepr/operator/controllers/network/allow-egress-dns.ts +++ b/src/pepr/operator/controllers/network/allow-egress-dns.ts @@ -5,7 +5,7 @@ export function allowEgressDNS(namespace: string): kind.NetworkPolicy { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { - name: "allow-egress-dns", + name: `egress-dns`, namespace, }, spec: { diff --git a/src/pepr/operator/controllers/network/allow-egress-istiod.ts b/src/pepr/operator/controllers/network/allow-egress-istiod.ts index c0539eb90..d397d83a9 100644 --- a/src/pepr/operator/controllers/network/allow-egress-istiod.ts +++ b/src/pepr/operator/controllers/network/allow-egress-istiod.ts @@ -5,7 +5,7 @@ export function allowEgressIstiod(namespace: string): kind.NetworkPolicy { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { - name: "allow-egress-istiod", + name: `egress-istiod`, namespace, }, spec: { diff --git a/src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts b/src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts index bdcd7a811..7e99ee508 100644 --- a/src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts +++ b/src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts @@ -5,7 +5,7 @@ export function allowIngressSidecarMonitoring(namespace: string): kind.NetworkPo apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { - name: "allow-ingress-sidecar-monitoring", + name: "ingress-sidecar-monitoring", namespace, }, spec: { diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index cc06d9e8e..74bc46da4 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -10,13 +10,11 @@ export async function generate( namespace: string, pkg: UDSPackage, policy: Allow, - idx: number, ): Promise { - const pkgName = pkg.metadata!.name!; const target = Object.values(policy.podLabels || ["all-pods"]).join("-"); // Create a unique name for the NetworkPolicy based on the package name, index, direction, pod labels, and port - const name = `allow-${policy.direction}-${target}-${pkgName}-${idx}`.toLowerCase(); + const name = `${policy.direction}-${target}`.toLowerCase(); // Create the NetworkPolicy const generated: kind.NetworkPolicy = { diff --git a/src/pepr/operator/controllers/network/index.ts b/src/pepr/operator/controllers/network/index.ts index bdde74913..40f568438 100644 --- a/src/pepr/operator/controllers/network/index.ts +++ b/src/pepr/operator/controllers/network/index.ts @@ -28,14 +28,14 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { ]; // Process custom policies - for (const [idx, policy] of customPolicies.entries()) { - const generatedPolicy = await generate(namespace, pkg, policy, idx); + for (const policy of customPolicies) { + const generatedPolicy = await generate(namespace, pkg, policy); policies.push(generatedPolicy); } // Generate NetworkPolicies for any VirtualServices that are generated const exposeList = pkg.spec?.network?.expose ?? []; - for (const [idx, expose] of exposeList.entries()) { + for (const expose of exposeList) { const { gateway = Gateway.Tenant, port, podLabels } = expose; // Create the NetworkPolicy for the VirtualService @@ -52,18 +52,23 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { }; // Generate the policy with a base index of 1000 - const generatedPolicy = await generate(namespace, pkg, policy, 1000 + idx); + const generatedPolicy = await generate(namespace, pkg, policy); policies.push(generatedPolicy); } // Iterate over each policy and apply it - for (const policy of policies) { + for (const [idx, policy] of policies.entries()) { // Add the package name and generation to the labels policy.metadata = policy.metadata ?? {}; policy.metadata.labels = policy.metadata?.labels ?? {}; policy.metadata.labels["uds/package"] = pkg.metadata!.name!; policy.metadata.labels["uds/generation"] = generation; + // If not the default deny all policy, add the index to the name + if (idx > 0) { + policy.metadata.name = `allow-${pkg.metadata!.name}-${idx}-${policy.metadata.name}`; + } + // Use the CR as the owner ref for each NetworkPolicy policy.metadata.ownerReferences = getOwnerRef(pkg); @@ -83,9 +88,9 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { ); // Delete any orphaned policies - for (const vs of orphanedNetPol) { - Log.debug(vs, `Deleting orphaned VirtualService ${vs.metadata!.name}`); - await K8s(kind.NetworkPolicy).Delete(vs); + for (const netPol of orphanedNetPol) { + Log.debug(netPol, `Deleting orphaned VirtualService ${netPol.metadata!.name}`); + await K8s(kind.NetworkPolicy).Delete(netPol); } // Return the list of policies From ea332b8838a7f342125c7d54cb09f3519596a671 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 13:41:59 -0600 Subject: [PATCH 37/98] do not retry same failed generation --- src/pepr/operator/reconciler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pepr/operator/reconciler.ts b/src/pepr/operator/reconciler.ts index c8fafc33f..c31514aa0 100644 --- a/src/pepr/operator/reconciler.ts +++ b/src/pepr/operator/reconciler.ts @@ -45,7 +45,7 @@ export async function reconciler(pkg: UDSPackage) { Log.warn(`Istio is not installed, skipping ${pkg.metadata.name} VirtualService.`); } - void updateStatus(pkg, { + await updateStatus(pkg, { phase: Phase.Ready, endpoints: vs.map(v => v.spec!.hosts!.join(",")), networkPolicyCount: netPol.length, @@ -53,7 +53,7 @@ export async function reconciler(pkg: UDSPackage) { }); } catch (e) { Log.error(e, `Error configuring for ${pkg.metadata.namespace}/${pkg.metadata.name}`); - void updateStatus(pkg, { phase: Phase.Failed }); + void updateStatus(pkg, { phase: Phase.Failed, observedGeneration: pkg.metadata.generation }); } } From 484db6385601361c80123a27b0b8032e1e1840e3 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 13:45:04 -0600 Subject: [PATCH 38/98] add todo --- src/pepr/operator/reconciler.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pepr/operator/reconciler.ts b/src/pepr/operator/reconciler.ts index c31514aa0..7b8d99af8 100644 --- a/src/pepr/operator/reconciler.ts +++ b/src/pepr/operator/reconciler.ts @@ -53,6 +53,7 @@ export async function reconciler(pkg: UDSPackage) { }); } catch (e) { Log.error(e, `Error configuring for ${pkg.metadata.namespace}/${pkg.metadata.name}`); + // todo: need to evaluate when it is safe to retry (updating generation now avoids retrying infinitely) void updateStatus(pkg, { phase: Phase.Failed, observedGeneration: pkg.metadata.generation }); } } From 22007fcd7da05251ac1a6fe882d1e1c4eadcd8fe Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 13:46:26 -0600 Subject: [PATCH 39/98] add uds to netpol name --- src/pepr/operator/controllers/network/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/operator/controllers/network/index.ts b/src/pepr/operator/controllers/network/index.ts index 40f568438..553a17854 100644 --- a/src/pepr/operator/controllers/network/index.ts +++ b/src/pepr/operator/controllers/network/index.ts @@ -66,7 +66,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // If not the default deny all policy, add the index to the name if (idx > 0) { - policy.metadata.name = `allow-${pkg.metadata!.name}-${idx}-${policy.metadata.name}`; + policy.metadata.name = `allow-uds-${pkg.metadata!.name}-${idx}-${policy.metadata.name}`; } // Use the CR as the owner ref for each NetworkPolicy From cf3213ecfd4ea4c580ed3540b1d198f244401b37 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 13:47:32 -0600 Subject: [PATCH 40/98] fix var name --- src/pepr/operator/controllers/network/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/operator/controllers/network/index.ts b/src/pepr/operator/controllers/network/index.ts index 553a17854..aafef19f0 100644 --- a/src/pepr/operator/controllers/network/index.ts +++ b/src/pepr/operator/controllers/network/index.ts @@ -84,7 +84,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // Find any orphaned polices (not matching the current generation) const orphanedNetPol = policyList.items.filter( - vs => vs.metadata?.labels?.["uds/generation"] !== generation, + netPol => netPol.metadata?.labels?.["uds/generation"] !== generation, ); // Delete any orphaned policies From e23d72c0ad196147f974c91615f2f705ecea1e01 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 13:52:35 -0600 Subject: [PATCH 41/98] update metrics server UDS Package --- src/metrics-server/chart/templates/uds-package.yaml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/metrics-server/chart/templates/uds-package.yaml b/src/metrics-server/chart/templates/uds-package.yaml index 28299065a..8cd4de0f5 100644 --- a/src/metrics-server/chart/templates/uds-package.yaml +++ b/src/metrics-server/chart/templates/uds-package.yaml @@ -7,12 +7,6 @@ spec: network: allow: - direction: Egress - remoteGenerated: KubeAPI + # todo: evaluate an "all nodes" generated rule podLabels: app.kubernetes.io/name: metrics-server - - direction: Ingress - podLabels: - app.kubernetes.io/name: metrics-server - remoteNamespaceLabels: - kubernetes.io/metadata.name: "istio-system" - port: 443 From 03f212e2bca62eea2a690c9d80eb3db2d01e021b Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 17:37:39 -0600 Subject: [PATCH 42/98] clenaup remoteGenerator things --- src/pepr/istio/index.ts | 5 +- .../operator/controllers/network/generate.ts | 81 +++++++------------ .../network/generators/anywhere.ts | 10 +++ .../network/generators/cloudMetadata.ts | 23 ++++++ .../network/generators/intraNamespace.ts | 8 ++ .../controllers/network/generators/kubeAPI.ts | 44 ++++++++++ .../crd/generated/package-v1alpha1.ts | 2 + src/pepr/operator/crd/sources/v1alpha1.ts | 2 +- 8 files changed, 119 insertions(+), 56 deletions(-) create mode 100644 src/pepr/operator/controllers/network/generators/anywhere.ts create mode 100644 src/pepr/operator/controllers/network/generators/cloudMetadata.ts create mode 100644 src/pepr/operator/controllers/network/generators/intraNamespace.ts create mode 100644 src/pepr/operator/controllers/network/generators/kubeAPI.ts diff --git a/src/pepr/istio/index.ts b/src/pepr/istio/index.ts index a3a5d1fbb..d651e7524 100644 --- a/src/pepr/istio/index.ts +++ b/src/pepr/istio/index.ts @@ -20,7 +20,10 @@ When(a.Pod) .WithLabel("batch.kubernetes.io/job-name") .WithLabel("service.istio.io/canonical-name") .Watch(async pod => { - Log.info(pod, `Processing Pod ${pod.metadata?.namespace}/${pod.metadata?.name} for istio job termination`); + Log.info( + pod, + `Processing Pod ${pod.metadata?.namespace}/${pod.metadata?.name} for istio job termination`, + ); if (!pod.metadata?.name || !pod.metadata.namespace) { Log.error(pod, `Invalid Pod definition`); diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index 74bc46da4..14a37e914 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -1,10 +1,12 @@ import { V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; -import { K8s, Log, kind } from "pepr"; +import { kind } from "pepr"; import { Allow, UDSPackage } from "../../crd"; import { RemoteGenerated } from "../../crd/generated/package-v1alpha1"; - -let apiServerPeers: V1NetworkPolicyPeer[]; +import { anywhere } from "./generators/anywhere"; +import { cloudMetadata } from "./generators/cloudMetadata"; +import { intraNamespace } from "./generators/intraNamespace"; +import { generateKubeAPI } from "./generators/kubeAPI"; export async function generate( namespace: string, @@ -58,21 +60,28 @@ export async function generate( } // Check if remoteGenerated is set - switch (policy.remoteGenerated) { - // KubeAPI maps to the Kubernetes API server - case RemoteGenerated.KubeAPI: - peers = await generateKubeAPI(); - generated.metadata!.labels!["uds/generated"] = "kubeapi"; - break; - - // IntraNamespace maps to the current namespace - case RemoteGenerated.IntraNamespace: - peers.push({ - podSelector: { - matchLabels: {}, - }, - }); - break; + if (policy.remoteGenerated) { + // Add the remoteGenerated label + generated.metadata!.labels!["uds/generated"] = policy.remoteGenerated; + + // Check if remoteGenerated is set + switch (policy.remoteGenerated) { + case RemoteGenerated.KubeAPI: + peers = await generateKubeAPI(); + break; + + case RemoteGenerated.CloudMetadata: + peers = cloudMetadata; + break; + + case RemoteGenerated.IntraNamespace: + peers.push(intraNamespace); + break; + + case RemoteGenerated.Anywhere: + peers = [anywhere]; + break; + } } // Create the port to match against @@ -96,39 +105,3 @@ export async function generate( return generated; } - -async function generateKubeAPI(): Promise { - // Return the cached value if it exists - // @todo: evaluate if this ever changes with node autoscaling - if (apiServerPeers) { - return apiServerPeers; - } - - try { - // Read the API server endpoints from the cluster - const { endpoints } = await K8s(kind.EndpointSlice).InNamespace("default").Get("kubernetes"); - - const peers = endpoints?.flatMap(e => e.addresses); - - // If the peers are found, cache and return them - if (peers?.length) { - apiServerPeers = peers.flatMap(ip => ({ - ipBlock: { - cidr: `${ip}/32`, - }, - })); - - return apiServerPeers; - } - } catch (err) { - Log.debug(err); - } - - // Log a warning and default to 0.0.0.0/0 if the IP is not found - Log.warn("Unable to get api-server-cidr, defaulting to 0.0.0.0/0"); - return [ - { - ipBlock: { cidr: "0.0.0.0/0" }, - }, - ]; -} diff --git a/src/pepr/operator/controllers/network/generators/anywhere.ts b/src/pepr/operator/controllers/network/generators/anywhere.ts new file mode 100644 index 000000000..58a982fc2 --- /dev/null +++ b/src/pepr/operator/controllers/network/generators/anywhere.ts @@ -0,0 +1,10 @@ +import { V1NetworkPolicyPeer } from "@kubernetes/client-node"; +import { META_IP } from "./cloudMetadata"; + +/** Matches any endpoint EXCEPT the Cloud Meta endpoint */ +export const anywhere: V1NetworkPolicyPeer = { + ipBlock: { + cidr: "0.0.0.0/0", + except: [META_IP], + }, +}; diff --git a/src/pepr/operator/controllers/network/generators/cloudMetadata.ts b/src/pepr/operator/controllers/network/generators/cloudMetadata.ts new file mode 100644 index 000000000..712cabee3 --- /dev/null +++ b/src/pepr/operator/controllers/network/generators/cloudMetadata.ts @@ -0,0 +1,23 @@ +import { V1NetworkPolicyPeer } from "@kubernetes/client-node"; + +export const META_IP = "169.254.169.254/32"; + +/** + * The cloud metadata endpoint is a common cloud address that can be used to + * access cloud provider metadata. + * + * AWS: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html + * + * GCP: https://cloud.google.com/compute/docs/storing-retrieving-metadata + * + * Azure: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service + * + * DigitalOcean: https://www.digitalocean.com/docs/droplets/resources/metadata/ + * + * @returns A NetworkPolicyPeer that matches the cloud metadata service + */ +export const cloudMetadata: V1NetworkPolicyPeer[] = [ + { + ipBlock: { cidr: META_IP }, + }, +]; diff --git a/src/pepr/operator/controllers/network/generators/intraNamespace.ts b/src/pepr/operator/controllers/network/generators/intraNamespace.ts new file mode 100644 index 000000000..3fb7f17f0 --- /dev/null +++ b/src/pepr/operator/controllers/network/generators/intraNamespace.ts @@ -0,0 +1,8 @@ +import { V1NetworkPolicyPeer } from "@kubernetes/client-node"; + +/** Matches any pod in the namespace */ +export const intraNamespace: V1NetworkPolicyPeer = { + podSelector: { + matchLabels: {}, + }, +}; diff --git a/src/pepr/operator/controllers/network/generators/kubeAPI.ts b/src/pepr/operator/controllers/network/generators/kubeAPI.ts new file mode 100644 index 000000000..02a941d67 --- /dev/null +++ b/src/pepr/operator/controllers/network/generators/kubeAPI.ts @@ -0,0 +1,44 @@ +import { V1NetworkPolicyPeer } from "@kubernetes/client-node"; +import { K8s, Log, kind } from "pepr"; + +import { anywhere } from "./anywhere"; + +let apiServerPeers: V1NetworkPolicyPeer[]; + +/** + * This generates a NetworkPolicyPeer that matches the API server endpoints. + * + * @returns A NetworkPolicyPeer that matches the API server endpoints + */ +export async function generateKubeAPI(): Promise { + // Return the cached value if it exists + // @todo: evaluate if this ever changes with node autoscaling + if (apiServerPeers) { + return apiServerPeers; + } + + try { + // Read the API server endpoints from the cluster + const { endpoints } = await K8s(kind.EndpointSlice).InNamespace("default").Get("kubernetes"); + + // Flatten the endpoints into a list of IPs + const peers = endpoints?.flatMap(e => e.addresses); + + // If the peers are found, cache and return them + if (peers?.length) { + apiServerPeers = peers.flatMap(ip => ({ + ipBlock: { + cidr: `${ip}/32`, + }, + })); + + return apiServerPeers; + } + } catch (err) { + Log.debug(err); + } + + // Log a warning and default to 0.0.0.0/0 if the IP is not found + Log.warn("Unable to get API server CIRD, defaulting to 0.0.0.0/0"); + return [anywhere]; +} diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index 9a6bd14ed..38aa86d23 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -85,6 +85,8 @@ export enum Protocol { * Custom generated remote selector for the policy */ export enum RemoteGenerated { + Anywhere = "Anywhere", + CloudMetadata = "CloudMetadata", IntraNamespace = "IntraNamespace", KubeAPI = "KubeAPI", } diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index a0e46a7aa..6d07940c9 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -157,7 +157,7 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { remoteGenerated: { description: "Custom generated remote selector for the policy", type: "string", - enum: ["KubeAPI", "IntraNamespace"], + enum: ["KubeAPI", "IntraNamespace", "CloudMetadata", "Anywhere"], }, port: { description: "The port to allow", From 8feb914861cbb00a457d43bff7606faffadc358e Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 17:38:26 -0600 Subject: [PATCH 43/98] more networkpolicy migration pain --- .../networkpolicies/egress-grafana.yaml | 18 -------------- .../networkpolicies/egress-tempo.yaml | 20 ---------------- .../networkpolicies/ingress-istio.yaml | 24 ------------------- src/grafana/chart/templates/uds-package.yaml | 21 +++++++++++++--- .../allow-sidecar-scraping.yaml | 20 ---------------- .../egress-external-services.yaml | 15 ------------ src/loki/chart/templates/uds-package.yaml | 10 +++++--- 7 files changed, 25 insertions(+), 103 deletions(-) delete mode 100644 src/grafana/chart/templates/networkpolicies/egress-grafana.yaml delete mode 100644 src/grafana/chart/templates/networkpolicies/egress-tempo.yaml delete mode 100644 src/grafana/chart/templates/networkpolicies/ingress-istio.yaml delete mode 100644 src/loki/chart/templates/networkpolicies/allow-sidecar-scraping.yaml delete mode 100644 src/loki/chart/templates/networkpolicies/egress-external-services.yaml diff --git a/src/grafana/chart/templates/networkpolicies/egress-grafana.yaml b/src/grafana/chart/templates/networkpolicies/egress-grafana.yaml deleted file mode 100644 index f62ab488b..000000000 --- a/src/grafana/chart/templates/networkpolicies/egress-grafana.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-egress-grafana - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app.kubernetes.io/name: grafana - policyTypes: - - Egress - egress: - - to: - - ipBlock: - cidr: 0.0.0.0/0 - # ONLY Block requests to cloud metadata IP - except: - - 169.254.169.254/32 \ No newline at end of file diff --git a/src/grafana/chart/templates/networkpolicies/egress-tempo.yaml b/src/grafana/chart/templates/networkpolicies/egress-tempo.yaml deleted file mode 100644 index be3e3f15e..000000000 --- a/src/grafana/chart/templates/networkpolicies/egress-tempo.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-tempo-egress - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Egress - # Allow access to zipkin - egress: - - to: - - namespaceSelector: - matchLabels: - app.kubernetes.io/name: tempo - podSelector: - matchLabels: - app.kubernetes.io/name: tempo - ports: - - port: 9411 diff --git a/src/grafana/chart/templates/networkpolicies/ingress-istio.yaml b/src/grafana/chart/templates/networkpolicies/ingress-istio.yaml deleted file mode 100644 index b1926a539..000000000 --- a/src/grafana/chart/templates/networkpolicies/ingress-istio.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-from-istio-ingressgateway-grafana - namespace: {{ .Release.Namespace }} -spec: - policyTypes: - - Ingress - ingress: - - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: istio-admin-gateway - podSelector: - matchLabels: - app: admin-ingressgateway - istio: admin-ingressgateway - ports: - - port: 3000 - protocol: TCP - podSelector: - matchLabels: - app.kubernetes.io/name: grafana - app.kubernetes.io/instance: grafana diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index f599287eb..149e15857 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -11,15 +11,30 @@ spec: app.kubernetes.io/name: grafana host: grafana gateway: admin - port: 80 + port: 5000 + ports: + - 80 allow: - direction: Ingress podLabels: - app: grafana + app.kubernetes.io/name: grafana remoteNamespaceLabels: app.kubernetes.io/name: tempo remotePodLabels: app.kubernetes.io/name: tempo port: 9090 - protocol: TCP + + - direction: Egress + podLabels: + app.kubernetes.io/name: grafana + remoteGenerated: anywhere + + - direction: Egress + podLabels: + app.kubernetes.io/name: grafana + remoteNamespaceLabels: + app.kubernetes.io/name: tempo + remotePodLabels: + app.kubernetes.io/name: tempo + port: 9411 diff --git a/src/loki/chart/templates/networkpolicies/allow-sidecar-scraping.yaml b/src/loki/chart/templates/networkpolicies/allow-sidecar-scraping.yaml deleted file mode 100644 index 077cf06f5..000000000 --- a/src/loki/chart/templates/networkpolicies/allow-sidecar-scraping.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-loki-sidecar-scraping - namespace: {{ .Release.Namespace }} -spec: - ingress: - - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: monitoring - podSelector: - matchLabels: - app: prometheus - ports: - - port: 15020 - protocol: TCP - podSelector: {} - policyTypes: - - Ingress diff --git a/src/loki/chart/templates/networkpolicies/egress-external-services.yaml b/src/loki/chart/templates/networkpolicies/egress-external-services.yaml deleted file mode 100644 index a6dd1139a..000000000 --- a/src/loki/chart/templates/networkpolicies/egress-external-services.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: egress-external-services - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app.kubernetes.io/name: loki - policyTypes: - - Egress - egress: - - to: - - ipBlock: - cidr: 0.0.0.0/0 \ No newline at end of file diff --git a/src/loki/chart/templates/uds-package.yaml b/src/loki/chart/templates/uds-package.yaml index 1265e1360..8d211a821 100644 --- a/src/loki/chart/templates/uds-package.yaml +++ b/src/loki/chart/templates/uds-package.yaml @@ -8,10 +8,14 @@ spec: allow: - direction: Ingress podLabels: - app: grafana + app.kubernetes.io/name: loki remoteNamespaceLabels: app.kubernetes.io/name: tempo remotePodLabels: app.kubernetes.io/name: tempo - port: 9090 - protocol: TCP + port: 8080 + + - direction: Egress + podLabels: + app.kubernetes.io/name: loki + remoteGenerated: anywhere From 9d376aeb9337be6c7ba88ee32410e31c6275cf81 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 17:46:48 -0600 Subject: [PATCH 44/98] remove protocol, add ports options for allow rules --- src/grafana/chart/templates/uds-package.yaml | 2 -- .../chart/templates/uds-package.yaml | 1 + src/neuvector/chart/templates/uds-package.yaml | 3 +++ .../operator/controllers/network/generate.ts | 17 +++++++++-------- .../network/generators/cloudMetadata.ts | 6 +++--- src/pepr/operator/controllers/network/index.ts | 6 +++--- .../operator/crd/generated/package-v1alpha1.ts | 15 +++------------ src/pepr/operator/crd/sources/v1alpha1.ts | 14 +++++++++----- 8 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index 149e15857..7d7c3cb06 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -12,8 +12,6 @@ spec: host: grafana gateway: admin port: 5000 - ports: - - 80 allow: - direction: Ingress diff --git a/src/metrics-server/chart/templates/uds-package.yaml b/src/metrics-server/chart/templates/uds-package.yaml index 8cd4de0f5..0f8e57932 100644 --- a/src/metrics-server/chart/templates/uds-package.yaml +++ b/src/metrics-server/chart/templates/uds-package.yaml @@ -10,3 +10,4 @@ spec: # todo: evaluate an "all nodes" generated rule podLabels: app.kubernetes.io/name: metrics-server + remoteGenerated: anywhere diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml index eec9dd809..a80c0957f 100644 --- a/src/neuvector/chart/templates/uds-package.yaml +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -17,6 +17,7 @@ spec: # Permit intra-namespace communication - direction: Ingress remoteGenerated: IntraNamespace + - direction: Egress remoteGenerated: IntraNamespace @@ -24,10 +25,12 @@ spec: remoteGenerated: KubeAPI podLabels: app: neuvector-controller-pod + - direction: Egress remoteGenerated: KubeAPI podLabels: app: neuvector-updater-pod + - direction: Ingress remoteNamespaceLabels: app.kubernetes.io/name: monitoring diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index 14a37e914..8b53edab5 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -1,7 +1,7 @@ import { V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; import { kind } from "pepr"; -import { Allow, UDSPackage } from "../../crd"; +import { Allow } from "../../crd"; import { RemoteGenerated } from "../../crd/generated/package-v1alpha1"; import { anywhere } from "./generators/anywhere"; import { cloudMetadata } from "./generators/cloudMetadata"; @@ -10,7 +10,6 @@ import { generateKubeAPI } from "./generators/kubeAPI"; export async function generate( namespace: string, - pkg: UDSPackage, policy: Allow, ): Promise { const target = Object.values(policy.podLabels || ["all-pods"]).join("-"); @@ -84,13 +83,15 @@ export async function generate( } } - // Create the port to match against - const ports: V1NetworkPolicyPort[] = [ - { + // Define the ports to allow from the ports property + const ports: V1NetworkPolicyPort[] = (policy.ports ?? []).map(port => ({ port })); + + // Add the individual port if it exists + if (policy.port) { + ports.push({ port: policy.port, - protocol: policy.protocol, - }, - ]; + }); + } // Add the ingress or egress rule switch (policy.direction) { diff --git a/src/pepr/operator/controllers/network/generators/cloudMetadata.ts b/src/pepr/operator/controllers/network/generators/cloudMetadata.ts index 712cabee3..8d1f641e2 100644 --- a/src/pepr/operator/controllers/network/generators/cloudMetadata.ts +++ b/src/pepr/operator/controllers/network/generators/cloudMetadata.ts @@ -7,11 +7,11 @@ export const META_IP = "169.254.169.254/32"; * access cloud provider metadata. * * AWS: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html - * + * * GCP: https://cloud.google.com/compute/docs/storing-retrieving-metadata - * + * * Azure: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service - * + * * DigitalOcean: https://www.digitalocean.com/docs/droplets/resources/metadata/ * * @returns A NetworkPolicyPeer that matches the cloud metadata service diff --git a/src/pepr/operator/controllers/network/index.ts b/src/pepr/operator/controllers/network/index.ts index aafef19f0..a34ef6066 100644 --- a/src/pepr/operator/controllers/network/index.ts +++ b/src/pepr/operator/controllers/network/index.ts @@ -29,7 +29,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // Process custom policies for (const policy of customPolicies) { - const generatedPolicy = await generate(namespace, pkg, policy); + const generatedPolicy = await generate(namespace, policy); policies.push(generatedPolicy); } @@ -51,8 +51,8 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { port, }; - // Generate the policy with a base index of 1000 - const generatedPolicy = await generate(namespace, pkg, policy); + // Generate the policy + const generatedPolicy = await generate(namespace, policy); policies.push(generatedPolicy); } diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index 38aa86d23..8ad35a804 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -43,13 +43,13 @@ export interface Allow { */ podLabels?: { [key: string]: string }; /** - * The port to allow + * The port to allow (protocol is always TCP) */ port?: number; /** - * The protocol (TCP, UDP, or SCTP) to allow. Defaults to TCP. + * A list of ports to allow (protocol is always TCP) */ - protocol?: Protocol; + ports?: number[]; /** * Custom generated remote selector for the policy */ @@ -72,15 +72,6 @@ export enum Direction { Ingress = "Ingress", } -/** - * The protocol (TCP, UDP, or SCTP) to allow. Defaults to TCP. - */ -export enum Protocol { - SCTP = "SCTP", - TCP = "TCP", - UDP = "UDP", -} - /** * Custom generated remote selector for the policy */ diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index 6d07940c9..1c3f9b505 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -160,15 +160,19 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { enum: ["KubeAPI", "IntraNamespace", "CloudMetadata", "Anywhere"], }, port: { - description: "The port to allow", + description: "The port to allow (protocol is always TCP)", minimum: 1, maximum: 65535, type: "number", }, - protocol: { - description: "The protocol (TCP, UDP, or SCTP) to allow. Defaults to TCP.", - type: "string", - enum: ["TCP", "UDP", "SCTP"], + ports: { + description: "A list of ports to allow (protocol is always TCP)", + type: "array", + items: { + minimum: 1, + maximum: 65535, + type: "number", + }, }, }, }, From 6e3119784515e6178f1a3b3e7ccd48b962e6c524 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 22:51:09 -0600 Subject: [PATCH 45/98] so those are case sensitive... --- src/grafana/chart/templates/uds-package.yaml | 2 +- src/loki/chart/templates/uds-package.yaml | 2 +- src/metrics-server/chart/templates/uds-package.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index 7d7c3cb06..a4a325761 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -26,7 +26,7 @@ spec: - direction: Egress podLabels: app.kubernetes.io/name: grafana - remoteGenerated: anywhere + remoteGenerated: Anywhere - direction: Egress podLabels: diff --git a/src/loki/chart/templates/uds-package.yaml b/src/loki/chart/templates/uds-package.yaml index 8d211a821..43bfdd143 100644 --- a/src/loki/chart/templates/uds-package.yaml +++ b/src/loki/chart/templates/uds-package.yaml @@ -18,4 +18,4 @@ spec: - direction: Egress podLabels: app.kubernetes.io/name: loki - remoteGenerated: anywhere + remoteGenerated: Anywhere diff --git a/src/metrics-server/chart/templates/uds-package.yaml b/src/metrics-server/chart/templates/uds-package.yaml index 0f8e57932..95ce4f566 100644 --- a/src/metrics-server/chart/templates/uds-package.yaml +++ b/src/metrics-server/chart/templates/uds-package.yaml @@ -10,4 +10,4 @@ spec: # todo: evaluate an "all nodes" generated rule podLabels: app.kubernetes.io/name: metrics-server - remoteGenerated: anywhere + remoteGenerated: Anywhere From 7a74fce3023c2dfce2af9e7cb434c49c6445661b Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 22:51:47 -0600 Subject: [PATCH 46/98] use generator for default policies + remove Promise --- .../controllers/network/allow-egress-dns.ts | 31 -------------- .../network/allow-egress-istiod.ts | 39 ------------------ .../allow-ingress-sidecar-monitoring.ts | 40 ------------------- .../network/defaults/allow-egress-dns.ts | 15 +++++++ .../network/defaults/allow-egress-istiod.ts | 14 +++++++ .../allow-ingress-sidecar-monitoring.ts | 14 +++++++ .../{ => defaults}/default-deny-all.ts | 0 .../operator/controllers/network/generate.ts | 7 +--- .../controllers/network/generators/kubeAPI.ts | 14 ++++--- .../operator/controllers/network/index.ts | 12 +++--- 10 files changed, 59 insertions(+), 127 deletions(-) delete mode 100644 src/pepr/operator/controllers/network/allow-egress-dns.ts delete mode 100644 src/pepr/operator/controllers/network/allow-egress-istiod.ts delete mode 100644 src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts create mode 100644 src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts create mode 100644 src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts create mode 100644 src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts rename src/pepr/operator/controllers/network/{ => defaults}/default-deny-all.ts (100%) diff --git a/src/pepr/operator/controllers/network/allow-egress-dns.ts b/src/pepr/operator/controllers/network/allow-egress-dns.ts deleted file mode 100644 index aa040ecf5..000000000 --- a/src/pepr/operator/controllers/network/allow-egress-dns.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { kind } from "pepr"; - -export function allowEgressDNS(namespace: string): kind.NetworkPolicy { - return { - apiVersion: "networking.k8s.io/v1", - kind: "NetworkPolicy", - metadata: { - name: `egress-dns`, - namespace, - }, - spec: { - podSelector: {}, - policyTypes: ["Egress"], - egress: [ - { - to: [ - { - namespaceSelector: {}, - }, - ], - ports: [ - { - port: 53, - protocol: "UDP", - }, - ], - }, - ], - }, - }; -} diff --git a/src/pepr/operator/controllers/network/allow-egress-istiod.ts b/src/pepr/operator/controllers/network/allow-egress-istiod.ts deleted file mode 100644 index d397d83a9..000000000 --- a/src/pepr/operator/controllers/network/allow-egress-istiod.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { kind } from "pepr"; - -export function allowEgressIstiod(namespace: string): kind.NetworkPolicy { - return { - apiVersion: "networking.k8s.io/v1", - kind: "NetworkPolicy", - metadata: { - name: `egress-istiod`, - namespace, - }, - spec: { - podSelector: {}, - policyTypes: ["Egress"], - egress: [ - { - to: [ - { - namespaceSelector: { - matchLabels: { - "kubernetes.io/metadata.name": "istio-system", - }, - }, - podSelector: { - matchLabels: { - istio: "pilot", - }, - }, - }, - ], - ports: [ - { - port: 15012, - }, - ], - }, - ], - }, - }; -} diff --git a/src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts b/src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts deleted file mode 100644 index 7e99ee508..000000000 --- a/src/pepr/operator/controllers/network/allow-ingress-sidecar-monitoring.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { kind } from "pepr"; - -export function allowIngressSidecarMonitoring(namespace: string): kind.NetworkPolicy { - return { - apiVersion: "networking.k8s.io/v1", - kind: "NetworkPolicy", - metadata: { - name: "ingress-sidecar-monitoring", - namespace, - }, - spec: { - podSelector: {}, - policyTypes: ["Ingress"], - ingress: [ - { - from: [ - { - namespaceSelector: { - matchLabels: { - "kubernetes.io/metadata.name": "monitoring", - }, - }, - podSelector: { - matchLabels: { - app: "prometheus", - }, - }, - }, - ], - ports: [ - { - protocol: "TCP", - port: 15020, - }, - ], - }, - ], - }, - }; -} diff --git a/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts b/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts new file mode 100644 index 000000000..0ae292067 --- /dev/null +++ b/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts @@ -0,0 +1,15 @@ +import { Direction } from "../../../crd"; +import { generate } from "../generate"; + +export const allowEgressDNS = (namespace: string) => { + const netPol = generate(namespace, { + direction: Direction.Egress, + remoteNamespaceLabels: {}, + port: 53, + }); + + // Override the generated policy to use UDP instead of TCP + netPol.spec!.egress![0].ports![0].protocol = "UDP"; + + return netPol; +}; diff --git a/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts b/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts new file mode 100644 index 000000000..61ce71570 --- /dev/null +++ b/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts @@ -0,0 +1,14 @@ +import { Direction } from "../../../crd"; +import { generate } from "../generate"; + +export const allowEgressIstiod = (namespace: string) => + generate(namespace, { + direction: Direction.Egress, + remoteNamespaceLabels: { + "kubernetes.io/metadata.name": "istio-system", + }, + remotePodLabels: { + istio: "pilot", + }, + port: 15012, + }); diff --git a/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts b/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts new file mode 100644 index 000000000..a0273b774 --- /dev/null +++ b/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts @@ -0,0 +1,14 @@ +import { Direction } from "../../../crd"; +import { generate } from "../generate"; + +export const allowIngressSidecarMonitoring = (namespace: string) => + generate(namespace, { + direction: Direction.Ingress, + remoteNamespaceLabels: { + "kubernetes.io/metadata.name": "monitoring", + }, + remotePodLabels: { + app: "prometheus", + }, + port: 15020, + }); diff --git a/src/pepr/operator/controllers/network/default-deny-all.ts b/src/pepr/operator/controllers/network/defaults/default-deny-all.ts similarity index 100% rename from src/pepr/operator/controllers/network/default-deny-all.ts rename to src/pepr/operator/controllers/network/defaults/default-deny-all.ts diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index 8b53edab5..89d63b0ec 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -8,10 +8,7 @@ import { cloudMetadata } from "./generators/cloudMetadata"; import { intraNamespace } from "./generators/intraNamespace"; import { generateKubeAPI } from "./generators/kubeAPI"; -export async function generate( - namespace: string, - policy: Allow, -): Promise { +export function generate(namespace: string, policy: Allow): kind.NetworkPolicy { const target = Object.values(policy.podLabels || ["all-pods"]).join("-"); // Create a unique name for the NetworkPolicy based on the package name, index, direction, pod labels, and port @@ -66,7 +63,7 @@ export async function generate( // Check if remoteGenerated is set switch (policy.remoteGenerated) { case RemoteGenerated.KubeAPI: - peers = await generateKubeAPI(); + peers = generateKubeAPI(); break; case RemoteGenerated.CloudMetadata: diff --git a/src/pepr/operator/controllers/network/generators/kubeAPI.ts b/src/pepr/operator/controllers/network/generators/kubeAPI.ts index 02a941d67..7319b4456 100644 --- a/src/pepr/operator/controllers/network/generators/kubeAPI.ts +++ b/src/pepr/operator/controllers/network/generators/kubeAPI.ts @@ -5,19 +5,21 @@ import { anywhere } from "./anywhere"; let apiServerPeers: V1NetworkPolicyPeer[]; +void getAPIServerCIDR(); + /** * This generates a NetworkPolicyPeer that matches the API server endpoints. * * @returns A NetworkPolicyPeer that matches the API server endpoints */ -export async function generateKubeAPI(): Promise { - // Return the cached value if it exists - // @todo: evaluate if this ever changes with node autoscaling - if (apiServerPeers) { - return apiServerPeers; - } +export function generateKubeAPI(): V1NetworkPolicyPeer[] { + return apiServerPeers; +} +async function getAPIServerCIDR(): Promise { try { + // @todo: evaluate if this ever changes with node autoscaling + // Read the API server endpoints from the cluster const { endpoints } = await K8s(kind.EndpointSlice).InNamespace("default").Get("kubernetes"); diff --git a/src/pepr/operator/controllers/network/index.ts b/src/pepr/operator/controllers/network/index.ts index a34ef6066..17a4e9281 100644 --- a/src/pepr/operator/controllers/network/index.ts +++ b/src/pepr/operator/controllers/network/index.ts @@ -1,10 +1,10 @@ import { K8s, Log, kind } from "pepr"; import { Allow, Direction, Gateway, UDSPackage, getOwnerRef } from "../../crd"; -import { allowEgressDNS } from "./allow-egress-dns"; -import { allowEgressIstiod } from "./allow-egress-istiod"; -import { allowIngressSidecarMonitoring } from "./allow-ingress-sidecar-monitoring"; -import { defaultDenyAll } from "./default-deny-all"; +import { allowEgressDNS } from "./defaults/allow-egress-dns"; +import { allowEgressIstiod } from "./defaults/allow-egress-istiod"; +import { allowIngressSidecarMonitoring } from "./defaults/allow-ingress-sidecar-monitoring"; +import { defaultDenyAll } from "./defaults/default-deny-all"; // Import the NetworkPolicy transforms webhook import { generate } from "./generate"; @@ -29,7 +29,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // Process custom policies for (const policy of customPolicies) { - const generatedPolicy = await generate(namespace, policy); + const generatedPolicy = generate(namespace, policy); policies.push(generatedPolicy); } @@ -52,7 +52,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { }; // Generate the policy - const generatedPolicy = await generate(namespace, policy); + const generatedPolicy = generate(namespace, policy); policies.push(generatedPolicy); } From c40f4b7c9c515310d6642deee6bd2d6d1988460f Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 4 Jan 2024 23:27:10 -0600 Subject: [PATCH 47/98] add uds to default deny policy name --- .../operator/controllers/network/defaults/default-deny-all.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/operator/controllers/network/defaults/default-deny-all.ts b/src/pepr/operator/controllers/network/defaults/default-deny-all.ts index 0e4423c90..f2402e67e 100644 --- a/src/pepr/operator/controllers/network/defaults/default-deny-all.ts +++ b/src/pepr/operator/controllers/network/defaults/default-deny-all.ts @@ -5,7 +5,7 @@ export function defaultDenyAll(namespace: string): kind.NetworkPolicy { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { - name: "default-deny-all", + name: "uds-default-deny-all", namespace, }, spec: { From 22bf462d5203f3fd4355c9d2263db6c44577773a Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 5 Jan 2024 00:04:18 -0600 Subject: [PATCH 48/98] simplify remoteNamespaceLabels to remoteNamespace --- src/grafana/chart/templates/uds-package.yaml | 6 +-- .../networkpolicies/egress-tempo.yaml | 20 --------- .../networkpolicies/ingress-monitoring.yaml | 30 -------------- src/loki/chart/templates/uds-package.yaml | 41 ++++++++++++++++++- .../chart/templates/uds-package.yaml | 3 +- src/pepr/operator/bully.ts | 2 +- .../network/defaults/allow-egress-dns.ts | 2 +- .../network/defaults/allow-egress-istiod.ts | 4 +- .../allow-ingress-sidecar-monitoring.ts | 4 +- .../operator/controllers/network/generate.ts | 22 ++++++---- .../operator/controllers/network/index.ts | 4 +- .../crd/generated/package-v1alpha1.ts | 7 ++-- src/pepr/operator/crd/sources/v1alpha1.ts | 12 +++--- src/pepr/operator/crd/validator.ts | 6 +-- 14 files changed, 72 insertions(+), 91 deletions(-) delete mode 100644 src/loki/chart/templates/networkpolicies/egress-tempo.yaml delete mode 100644 src/loki/chart/templates/networkpolicies/ingress-monitoring.yaml diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index a4a325761..5c685ed84 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -17,8 +17,7 @@ spec: - direction: Ingress podLabels: app.kubernetes.io/name: grafana - remoteNamespaceLabels: - app.kubernetes.io/name: tempo + remoteNamespace: tempo remotePodLabels: app.kubernetes.io/name: tempo port: 9090 @@ -31,8 +30,7 @@ spec: - direction: Egress podLabels: app.kubernetes.io/name: grafana - remoteNamespaceLabels: - app.kubernetes.io/name: tempo + remoteNamespace: tempo remotePodLabels: app.kubernetes.io/name: tempo port: 9411 diff --git a/src/loki/chart/templates/networkpolicies/egress-tempo.yaml b/src/loki/chart/templates/networkpolicies/egress-tempo.yaml deleted file mode 100644 index 653bbca94..000000000 --- a/src/loki/chart/templates/networkpolicies/egress-tempo.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-tempo-egress-{{ .Release.Name }} - namespace: {{ .Release.Namespace }} -spec: - podSelector: {} - policyTypes: - - Egress - # Allow access to zipkin - egress: - - to: - - namespaceSelector: - matchLabels: - app.kubernetes.io/name: tempo - podSelector: - matchLabels: - app.kubernetes.io/name: tempo - ports: - - port: 9411 diff --git a/src/loki/chart/templates/networkpolicies/ingress-monitoring.yaml b/src/loki/chart/templates/networkpolicies/ingress-monitoring.yaml deleted file mode 100644 index f5a963cd7..000000000 --- a/src/loki/chart/templates/networkpolicies/ingress-monitoring.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: ingress-monitoring - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app.kubernetes.io/name: loki - policyTypes: - - Ingress - ingress: - - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: grafana - podSelector: - matchLabels: - app.kubernetes.io/name: grafana - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: monitoring - podSelector: - matchLabels: - app.kubernetes.io/name: prometheus - ports: - - port: 8080 - protocol: TCP - - port: 3100 - protocol: TCP diff --git a/src/loki/chart/templates/uds-package.yaml b/src/loki/chart/templates/uds-package.yaml index 43bfdd143..be9e06b52 100644 --- a/src/loki/chart/templates/uds-package.yaml +++ b/src/loki/chart/templates/uds-package.yaml @@ -9,13 +9,50 @@ spec: - direction: Ingress podLabels: app.kubernetes.io/name: loki - remoteNamespaceLabels: - app.kubernetes.io/name: tempo + remoteNamespace: tempo remotePodLabels: app.kubernetes.io/name: tempo port: 8080 + - direction: Ingress + podLabels: + app.kubernetes.io/name: loki + remoteNamespace: grafana + remotePodLabels: + app.kubernetes.io/name: grafana + ports: + - 3100 + - 8080 + + - direction: Ingress + podLabels: + app.kubernetes.io/name: loki + remoteNamespace: monitoring + remotePodLabels: + app.kubernetes.io/name: prometheus + ports: + - 3100 + - 8080 + + - direction: Ingress + podLabels: + app.kubernetes.io/name: loki + remoteNamespace: promtail + remotePodLabels: + app.kubernetes.io/name: promtail + ports: + - 8080 + + # Todo: wide open for now for pushing to s3 - direction: Egress podLabels: app.kubernetes.io/name: loki remoteGenerated: Anywhere + + - direction: Egress + podLabels: + app.kubernetes.io/name: loki + remoteNamespace: tempo + remotePodLabels: + app.kubernetes.io/name: tempo + port: 9411 diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml index a80c0957f..e122aa1d0 100644 --- a/src/neuvector/chart/templates/uds-package.yaml +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -32,8 +32,7 @@ spec: app: neuvector-updater-pod - direction: Ingress - remoteNamespaceLabels: - app.kubernetes.io/name: monitoring + remoteNamespace: monitoring remotePodLabels: app: prometheus podLabels: diff --git a/src/pepr/operator/bully.ts b/src/pepr/operator/bully.ts index e2762ca40..09273b4b9 100644 --- a/src/pepr/operator/bully.ts +++ b/src/pepr/operator/bully.ts @@ -42,7 +42,7 @@ setInterval(async () => { app: "some-cool-test", }, port: 80, - remoteNamespaceLabels: {}, + remoteNamespace: "", }, ], }, diff --git a/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts b/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts index 0ae292067..d52645149 100644 --- a/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts +++ b/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts @@ -4,7 +4,7 @@ import { generate } from "../generate"; export const allowEgressDNS = (namespace: string) => { const netPol = generate(namespace, { direction: Direction.Egress, - remoteNamespaceLabels: {}, + remoteNamespace: "*", port: 53, }); diff --git a/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts b/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts index 61ce71570..582e1730b 100644 --- a/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts +++ b/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts @@ -4,9 +4,7 @@ import { generate } from "../generate"; export const allowEgressIstiod = (namespace: string) => generate(namespace, { direction: Direction.Egress, - remoteNamespaceLabels: { - "kubernetes.io/metadata.name": "istio-system", - }, + remoteNamespace: "istio-system", remotePodLabels: { istio: "pilot", }, diff --git a/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts b/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts index a0273b774..94e36e965 100644 --- a/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts +++ b/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts @@ -4,9 +4,7 @@ import { generate } from "../generate"; export const allowIngressSidecarMonitoring = (namespace: string) => generate(namespace, { direction: Direction.Ingress, - remoteNamespaceLabels: { - "kubernetes.io/metadata.name": "monitoring", - }, + remoteNamespace: "monitoring", remotePodLabels: { app: "prometheus", }, diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index 89d63b0ec..d95660d80 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -1,4 +1,4 @@ -import { V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; +import { V1NetworkPolicyPeer, V1NetworkPolicyPort, V1LabelSelector } from "@kubernetes/client-node"; import { kind } from "pepr"; import { Allow } from "../../crd"; @@ -37,13 +37,19 @@ export function generate(namespace: string, policy: Allow): kind.NetworkPolicy { // Create the remote (peer) to match against let peers: V1NetworkPolicyPeer[] = []; - // Add the remoteNamespaceLabels if they exist - if (policy.remoteNamespaceLabels) { - peers.push({ - namespaceSelector: { - matchLabels: policy.remoteNamespaceLabels, - }, - }); + // Add the remoteNamespace if they exist + if (policy.remoteNamespace !== undefined) { + const namespaceSelector: V1LabelSelector = {}; + + // Add the remoteNamespace to the namespaceSelector if it exists and is not "*", otherwise match all namespaces + if (policy.remoteNamespace !== "" && policy.remoteNamespace !== "*") { + namespaceSelector.matchLabels = { + "kubernetes.io/metadata.name": policy.remoteNamespace, + }; + } + + // Add the remoteNamespace to the peers + peers.push({ namespaceSelector }); } // Add the remotePodLabels if they exist diff --git a/src/pepr/operator/controllers/network/index.ts b/src/pepr/operator/controllers/network/index.ts index 17a4e9281..3d4e5a8c2 100644 --- a/src/pepr/operator/controllers/network/index.ts +++ b/src/pepr/operator/controllers/network/index.ts @@ -42,12 +42,10 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { const policy: Allow = { direction: Direction.Ingress, podLabels, + remoteNamespace: `istio-${gateway}-gateway`, remotePodLabels: { app: `${gateway}-ingressgateway`, }, - remoteNamespaceLabels: { - "kubernetes.io/metadata.name": `istio-${gateway}-gateway`, - }, port, }; diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index 8ad35a804..266cd9d31 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -55,11 +55,12 @@ export interface Allow { */ remoteGenerated?: RemoteGenerated; /** - * The remote namespace selector labels + * The remote namespace to allow traffic to/from. Use * or empty string to allow all + * namespaces */ - remoteNamespaceLabels?: { [key: string]: string }; + remoteNamespace?: string; /** - * The remote pod selector labels + * The remote pod selector labels to allow traffic to/from */ remotePodLabels?: { [key: string]: string }; } diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index 1c3f9b505..35dbdafef 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -140,15 +140,13 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { type: "string", }, }, - remoteNamespaceLabels: { - description: "The remote namespace selector labels", - type: "object", - additionalProperties: { - type: "string", - }, + remoteNamespace: { + description: + "The remote namespace to allow traffic to/from. Use * or empty string to allow all namespaces", + type: "string", }, remotePodLabels: { - description: "The remote pod selector labels", + description: "The remote pod selector labels to allow traffic to/from", type: "object", additionalProperties: { type: "string", diff --git a/src/pepr/operator/crd/validator.ts b/src/pepr/operator/crd/validator.ts index 9db422e48..c6d88ab92 100644 --- a/src/pepr/operator/crd/validator.ts +++ b/src/pepr/operator/crd/validator.ts @@ -15,10 +15,8 @@ export async function validator(req: PeprValidateRequest) { for (const policy of networkPolicy) { // remoteGenerated cannot be combined with remoteNamespaceLabels or remotePodLabels - if (policy.remoteGenerated && (policy.remoteNamespaceLabels || policy.remotePodLabels)) { - return req.Deny( - "remoteGenerated cannot be combined with remoteNamespaceLabels or remotePodLabels", - ); + if (policy.remoteGenerated && (policy.remotePodLabels || policy.remotePodLabels)) { + return req.Deny("remoteGenerated cannot be combined with remoteNamespace or remotePodLabels"); } } From d0bbb7f60914a45d29fd27204a551234e28cde32 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 5 Jan 2024 02:53:54 -0600 Subject: [PATCH 49/98] make better netpol names --- .../operator/controllers/network/generate.ts | 38 +++++++++++++++---- .../operator/controllers/network/index.ts | 2 +- .../crd/generated/package-v1alpha1.ts | 4 ++ src/pepr/operator/crd/sources/v1alpha1.ts | 5 +++ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index d95660d80..da95b30c8 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -9,10 +9,8 @@ import { intraNamespace } from "./generators/intraNamespace"; import { generateKubeAPI } from "./generators/kubeAPI"; export function generate(namespace: string, policy: Allow): kind.NetworkPolicy { - const target = Object.values(policy.podLabels || ["all-pods"]).join("-"); - // Create a unique name for the NetworkPolicy based on the package name, index, direction, pod labels, and port - const name = `${policy.direction}-${target}`.toLowerCase(); + const name = generateName(policy); // Create the NetworkPolicy const generated: kind.NetworkPolicy = { @@ -21,10 +19,7 @@ export function generate(namespace: string, policy: Allow): kind.NetworkPolicy { metadata: { name, namespace, - labels: { - "uds/generator": "true", - ...policy.labels, - }, + labels: { ...policy.labels }, }, spec: { policyTypes: [policy.direction], @@ -109,3 +104,32 @@ export function generate(namespace: string, policy: Allow): kind.NetworkPolicy { return generated; } + +function generateName(policy: Allow) { + const name = + // Use the description if it exists + policy.description || + // Otherwise use the direction, and combination of remote properties + [ + Object.values(policy.podLabels || ["all pods"]), + policy.remoteGenerated || [ + policy.remoteNamespace, + Object.values(policy.remotePodLabels || ["all pods"]), + ], + ] + // Flatten the array + .flat(1) + .join("-"); + + return ( + `${policy.direction}-${name}` + // The name must be lowercase + .toLowerCase() + // Replace sequences of non-alphanumeric characters with a single '-' + .replace(/[^a-z0-9]+/g, "-") + // Truncate the name 245 characters + .slice(0, 245) + // Remove leading and trailing '-' + .replace(/^-|-$/g, "") + ); +} diff --git a/src/pepr/operator/controllers/network/index.ts b/src/pepr/operator/controllers/network/index.ts index 3d4e5a8c2..37e704eed 100644 --- a/src/pepr/operator/controllers/network/index.ts +++ b/src/pepr/operator/controllers/network/index.ts @@ -64,7 +64,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // If not the default deny all policy, add the index to the name if (idx > 0) { - policy.metadata.name = `allow-uds-${pkg.metadata!.name}-${idx}-${policy.metadata.name}`; + policy.metadata.name = `allow-uds-${policy.metadata.name}`; } // Use the CR as the owner ref for each NetworkPolicy diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index 266cd9d31..702ee505d 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -29,6 +29,10 @@ export interface Network { } export interface Allow { + /** + * A description of the policy, this will become part of the policy name + */ + description?: string; /** * The direction of the traffic */ diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index 35dbdafef..9076933e0 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -127,6 +127,11 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { type: "string", }, }, + description: { + type: "string", + description: + "A description of the policy, this will become part of the policy name", + }, direction: { description: "The direction of the traffic", enum: ["Ingress", "Egress"], From db38f100396a7a908df24e654c735df8fe8f50a2 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 5 Jan 2024 12:12:37 -0600 Subject: [PATCH 50/98] add netpol descriptions --- .../operator/controllers/network/defaults/allow-egress-dns.ts | 1 + .../operator/controllers/network/defaults/allow-egress-istiod.ts | 1 + .../network/defaults/allow-ingress-sidecar-monitoring.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts b/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts index d52645149..cb15c239a 100644 --- a/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts +++ b/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts @@ -4,6 +4,7 @@ import { generate } from "../generate"; export const allowEgressDNS = (namespace: string) => { const netPol = generate(namespace, { direction: Direction.Egress, + description: "DNS lookup to any DNS server", remoteNamespace: "*", port: 53, }); diff --git a/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts b/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts index 582e1730b..01a77c2ef 100644 --- a/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts +++ b/src/pepr/operator/controllers/network/defaults/allow-egress-istiod.ts @@ -4,6 +4,7 @@ import { generate } from "../generate"; export const allowEgressIstiod = (namespace: string) => generate(namespace, { direction: Direction.Egress, + description: "Istiod communication", remoteNamespace: "istio-system", remotePodLabels: { istio: "pilot", diff --git a/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts b/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts index 94e36e965..e3d232cd1 100644 --- a/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts +++ b/src/pepr/operator/controllers/network/defaults/allow-ingress-sidecar-monitoring.ts @@ -4,6 +4,7 @@ import { generate } from "../generate"; export const allowIngressSidecarMonitoring = (namespace: string) => generate(namespace, { direction: Direction.Ingress, + description: "Sidecar monitoring", remoteNamespace: "monitoring", remotePodLabels: { app: "prometheus", From 45f97bb6d951a6c65d9cbd77ea73147e1a79f5ea Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Sun, 7 Jan 2024 23:31:11 -0600 Subject: [PATCH 51/98] add targetPort to accomdate port difference between svc/pod (VS and NetPol) --- src/grafana/chart/templates/uds-package.yaml | 3 ++- .../networkpolicies/ingress-promtail.yaml | 22 ------------------- src/loki/zarf.yaml | 8 +++---- .../operator/controllers/network/index.ts | 5 +++-- .../crd/generated/package-v1alpha1.ts | 6 +++++ src/pepr/operator/crd/sources/v1alpha1.ts | 7 ++++++ src/test/app-admin.yaml | 1 + src/test/app-tenant.yaml | 1 + 8 files changed, 24 insertions(+), 29 deletions(-) delete mode 100644 src/loki/chart/templates/networkpolicies/ingress-promtail.yaml diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index 5c685ed84..e398d5f3f 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -11,7 +11,8 @@ spec: app.kubernetes.io/name: grafana host: grafana gateway: admin - port: 5000 + port: 80 + targetPort: 3000 allow: - direction: Ingress diff --git a/src/loki/chart/templates/networkpolicies/ingress-promtail.yaml b/src/loki/chart/templates/networkpolicies/ingress-promtail.yaml deleted file mode 100644 index 1a63e60e3..000000000 --- a/src/loki/chart/templates/networkpolicies/ingress-promtail.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-promtail-ingress-{{ .Release.Name }} - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app.kubernetes.io/name: loki - policyTypes: - - Ingress - ingress: - - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: promtail - podSelector: - matchLabels: - app.kubernetes.io/name: promtail - ports: - - port: 8080 - protocol: TCP diff --git a/src/loki/zarf.yaml b/src/loki/zarf.yaml index fd55a43df..f650b2506 100644 --- a/src/loki/zarf.yaml +++ b/src/loki/zarf.yaml @@ -7,16 +7,16 @@ components: - name: loki required: true charts: + - name: uds-loki-config + namespace: loki + version: 0.2.0 + localPath: chart - name: loki url: https://grafana.github.io/helm-charts/ version: 5.36.3 namespace: loki valuesFiles: - ./values/values.yaml - - name: uds-loki-config - namespace: loki - version: 0.2.0 - localPath: chart images: - docker.io/grafana/loki:2.9.2 - docker.io/nginxinc/nginx-unprivileged:1.24-alpine diff --git a/src/pepr/operator/controllers/network/index.ts b/src/pepr/operator/controllers/network/index.ts index 37e704eed..3ea210d5c 100644 --- a/src/pepr/operator/controllers/network/index.ts +++ b/src/pepr/operator/controllers/network/index.ts @@ -36,7 +36,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // Generate NetworkPolicies for any VirtualServices that are generated const exposeList = pkg.spec?.network?.expose ?? []; for (const expose of exposeList) { - const { gateway = Gateway.Tenant, port, podLabels } = expose; + const { gateway = Gateway.Tenant, port, podLabels, targetPort } = expose; // Create the NetworkPolicy for the VirtualService const policy: Allow = { @@ -46,7 +46,8 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { remotePodLabels: { app: `${gateway}-ingressgateway`, }, - port, + // Use the same port as the VirtualService if targetPort is not set + port: targetPort ?? port, }; // Generate the policy diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index 702ee505d..e21962666 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -113,6 +113,12 @@ export interface Expose { * The name of the service to expose */ service: string; + /** + * The service targetPort (pod port). This defaults to port and is only required if the + * service port is different from the pod port (so the NetworkPolicy can be generated + * correctly). + */ + targetPort?: number; } /** diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index 9076933e0..df19067f6 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -93,6 +93,13 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { maximum: 65535, type: "number", }, + targetPort: { + description: + "The service targetPort (pod port). This defaults to port and is only required if the service port is different from the pod port (so the NetworkPolicy can be generated correctly).", + minimum: 1, + maximum: 65535, + type: "number", + }, gateway: { description: "The name of the gateway to expose the service on (default: tenant)", diff --git a/src/test/app-admin.yaml b/src/test/app-admin.yaml index 57bcc5a26..2caa2b7e7 100644 --- a/src/test/app-admin.yaml +++ b/src/test/app-admin.yaml @@ -19,6 +19,7 @@ spec: gateway: admin host: demo port: 8000 + targetPort: 80 --- apiVersion: v1 kind: ServiceAccount diff --git a/src/test/app-tenant.yaml b/src/test/app-tenant.yaml index ad5509527..637af1659 100644 --- a/src/test/app-tenant.yaml +++ b/src/test/app-tenant.yaml @@ -19,6 +19,7 @@ spec: gateway: tenant host: demo port: 8000 + targetPort: 80 --- apiVersion: v1 kind: ServiceAccount From aa8e94bd4f2bb4c801bbeb7aee702edc310a5338 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 8 Jan 2024 01:30:25 -0600 Subject: [PATCH 52/98] only deal with ns label if istio is enabled --- .../operator/controllers/namespace/index.ts | 3 --- src/pepr/operator/reconciler.ts | 18 +++++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/pepr/operator/controllers/namespace/index.ts b/src/pepr/operator/controllers/namespace/index.ts index 88b981575..bd777f094 100644 --- a/src/pepr/operator/controllers/namespace/index.ts +++ b/src/pepr/operator/controllers/namespace/index.ts @@ -5,7 +5,6 @@ import { UDSPackage } from "../../crd"; * Syncs the package namespace istio-injection label and adds a label for the package name * * @param pkg - * @returns the namespace if successful, otherwise an empty string */ export async function syncNamespace(pkg: UDSPackage) { if (!pkg.metadata?.namespace || !pkg.metadata.name) { @@ -35,6 +34,4 @@ export async function syncNamespace(pkg: UDSPackage) { // @todo: Add a finalizer to remove the label when the package is deleted // @todo: Check for pods without sidecars and address them } - - return pkg.metadata.namespace; } diff --git a/src/pepr/operator/reconciler.ts b/src/pepr/operator/reconciler.ts index 7b8d99af8..b60a2bc35 100644 --- a/src/pepr/operator/reconciler.ts +++ b/src/pepr/operator/reconciler.ts @@ -27,24 +27,28 @@ export async function reconciler(pkg: UDSPackage) { return; } - Log.debug(pkg, `Processing Package ${pkg.metadata.namespace}/${pkg.metadata.name}`); + const { namespace, name } = pkg.metadata; + + Log.debug(pkg, `Processing Package ${namespace}/${name}`); // Configure the namespace and namespace-wide network policies try { void updateStatus(pkg, { phase: Phase.Pending }); - const namespace = await syncNamespace(pkg); - - const netPol = await networkPolicies(pkg, namespace); - // Only configure the VirtualService if Istio is installed let vs: VirtualService[] = []; if (UDSConfig.istioInstalled) { + // Update the namespace to ensure the istio-injection label is set + await syncNamespace(pkg); + + // Create the VirtualService for each exposed service vs = await virtualService(pkg, namespace); } else { - Log.warn(`Istio is not installed, skipping ${pkg.metadata.name} VirtualService.`); + Log.warn(`Istio is not installed, skipping ${name} VirtualService.`); } + const netPol = await networkPolicies(pkg, namespace); + await updateStatus(pkg, { phase: Phase.Ready, endpoints: vs.map(v => v.spec!.hosts!.join(",")), @@ -52,7 +56,7 @@ export async function reconciler(pkg: UDSPackage) { observedGeneration: pkg.metadata.generation, }); } catch (e) { - Log.error(e, `Error configuring for ${pkg.metadata.namespace}/${pkg.metadata.name}`); + Log.error(e, `Error configuring for ${namespace}/${name}`); // todo: need to evaluate when it is safe to retry (updating generation now avoids retrying infinitely) void updateStatus(pkg, { phase: Phase.Failed, observedGeneration: pkg.metadata.generation }); } From 1e649d8e901bbe2f6952fb7de7e10b5ea92803b3 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 8 Jan 2024 01:41:43 -0600 Subject: [PATCH 53/98] cleanup crd imports --- src/pepr/operator/controllers/istio/index.ts | 19 +++++++------------ .../operator/controllers/network/generate.ts | 5 ++--- src/pepr/operator/crd/index.ts | 3 +++ src/pepr/operator/crd/validator.ts | 1 + src/pepr/policies/security.ts | 12 ++++++------ 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/pepr/operator/controllers/istio/index.ts b/src/pepr/operator/controllers/istio/index.ts index b917f4cd4..e3c1c91ad 100644 --- a/src/pepr/operator/controllers/istio/index.ts +++ b/src/pepr/operator/controllers/istio/index.ts @@ -1,12 +1,7 @@ import { K8s, Log } from "pepr"; import { UDSConfig } from "../../../config"; -import { Gateway, UDSPackage, getOwnerRef } from "../../crd"; -import { - HTTPRoute, - TCPRoute, - VirtualService, -} from "../../crd/generated/istio/virtualservice-v1beta1"; +import { Gateway, Istio, UDSPackage, getOwnerRef } from "../../crd"; /** * Creates a VirtualService for each exposed service in the package @@ -21,7 +16,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { // Get the list of exposed services const exposeList = pkg.spec?.network?.expose ?? []; - const payloads: VirtualService[] = []; + const payloads: Istio.VirtualService[] = []; // Iterate over each exposed service for (const expose of exposeList) { @@ -30,7 +25,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { const name = `${pkgName}-${gateway}-${host}`.toLowerCase(); // Create the route to the service - const route: TCPRoute[] | HTTPRoute[] = [ + const route: Istio.TCPRoute[] | Istio.HTTPRoute[] = [ { destination: { // Use the service name as the host @@ -44,7 +39,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { // For the admin gateway, we need to add the path prefix const domain = (gateway === Gateway.Admin ? "admin." : "") + UDSConfig.domain; - const payload: VirtualService = { + const payload: Istio.VirtualService = { metadata: { name, namespace, @@ -69,13 +64,13 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { Log.debug(payload, `Applying VirtualService ${name}`); // Apply the VirtualService and force overwrite any existing policy - await K8s(VirtualService).Apply(payload, { force: true }); + await K8s(Istio.VirtualService).Apply(payload, { force: true }); payloads.push(payload); } // Get all related VirtualServices in the namespace - const virtualServices = await K8s(VirtualService) + const virtualServices = await K8s(Istio.VirtualService) .InNamespace(namespace) .WithLabel("uds/package", pkgName) .Get(); @@ -88,7 +83,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { // Delete any orphaned VirtualServices for (const vs of orphanedVS) { Log.debug(vs, `Deleting orphaned VirtualService ${vs.metadata!.name}`); - await K8s(VirtualService).Delete(vs); + await K8s(Istio.VirtualService).Delete(vs); } // Return the list of generated VirtualServices diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index da95b30c8..208ea2786 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -1,8 +1,7 @@ -import { V1NetworkPolicyPeer, V1NetworkPolicyPort, V1LabelSelector } from "@kubernetes/client-node"; +import { V1LabelSelector, V1NetworkPolicyPeer, V1NetworkPolicyPort } from "@kubernetes/client-node"; import { kind } from "pepr"; -import { Allow } from "../../crd"; -import { RemoteGenerated } from "../../crd/generated/package-v1alpha1"; +import { Allow, RemoteGenerated } from "../../crd"; import { anywhere } from "./generators/anywhere"; import { cloudMetadata } from "./generators/cloudMetadata"; import { intraNamespace } from "./generators/intraNamespace"; diff --git a/src/pepr/operator/crd/index.ts b/src/pepr/operator/crd/index.ts index a7c6320a8..ad58256dc 100644 --- a/src/pepr/operator/crd/index.ts +++ b/src/pepr/operator/crd/index.ts @@ -9,8 +9,11 @@ export { Phase, Status, Package as UDSPackage, + RemoteGenerated, } from "./generated/package-v1alpha1"; +export * as Istio from "./generated/istio/virtualservice-v1beta1"; + export function getOwnerRef(pkg: UDSPackage): V1OwnerReference[] { const { name, uid } = pkg.metadata!; diff --git a/src/pepr/operator/crd/validator.ts b/src/pepr/operator/crd/validator.ts index c6d88ab92..3427ac754 100644 --- a/src/pepr/operator/crd/validator.ts +++ b/src/pepr/operator/crd/validator.ts @@ -1,4 +1,5 @@ import { PeprValidateRequest } from "pepr"; + import { UDSPackage } from "."; const invalidNamespaces = ["kube-system", "kube-public", "_unknown_", "pepr-system"]; diff --git a/src/pepr/policies/security.ts b/src/pepr/policies/security.ts index 036a3a0bb..637b67748 100644 --- a/src/pepr/policies/security.ts +++ b/src/pepr/policies/security.ts @@ -67,21 +67,21 @@ When(a.Pod) pod.securityContext = pod.securityContext || {}; // Set the runAsUser field if it is defined in a label - const runAsUser = metadata.labels?.["uds/user"] + const runAsUser = metadata.labels?.["uds/user"]; if (runAsUser) { - pod.securityContext.runAsUser = parseInt(runAsUser) + pod.securityContext.runAsUser = parseInt(runAsUser); } // Set the runAsGroup field if it is defined in a label - const runAsGroup = metadata.labels?.["uds/group"] + const runAsGroup = metadata.labels?.["uds/group"]; if (runAsGroup) { - pod.securityContext.runAsGroup = parseInt(runAsGroup) + pod.securityContext.runAsGroup = parseInt(runAsGroup); } // Set the fsGroup field if it is defined in a label - const fsGroup = metadata.labels?.["uds/fsgroup"] + const fsGroup = metadata.labels?.["uds/fsgroup"]; if (fsGroup) { - pod.securityContext.fsGroup = parseInt(fsGroup) + pod.securityContext.fsGroup = parseInt(fsGroup); } // Set the runAsNonRoot field to true if it is undefined From b3741433ec79ba7726a0533167937f475a7f71be Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 8 Jan 2024 01:43:35 -0600 Subject: [PATCH 54/98] drop the stress test file --- src/pepr/operator/bully.ts | 53 -------------------------------------- 1 file changed, 53 deletions(-) delete mode 100644 src/pepr/operator/bully.ts diff --git a/src/pepr/operator/bully.ts b/src/pepr/operator/bully.ts deleted file mode 100644 index 09273b4b9..000000000 --- a/src/pepr/operator/bully.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { K8s, kind } from "pepr"; -import { UDSPackage } from "./crd"; -import { Direction, Gateway } from "./crd/generated/package-v1alpha1"; - -const intervalMS = 50; -let inc = 0; - -setInterval(async () => { - const namespace = `bully-${inc++}`; - - await K8s(kind.Namespace).Apply({ - metadata: { - name: namespace, - }, - }); - - const pkg = await K8s(UDSPackage).Apply({ - metadata: { - name: `random-${Math.random() * 1000}`, - namespace, - }, - spec: { - network: { - expose: [ - { - gateway: Gateway.Tenant, - service: "test", - port: 80, - host: `test-${Math.random() * 1000}`, - podLabels: { - app: "some-cool-test", - }, - }, - ], - allow: [ - { - direction: Direction.Ingress, - labels: { - demo: "test", - }, - podLabels: { - app: "some-cool-test", - }, - port: 80, - remoteNamespace: "", - }, - ], - }, - }, - }); - - console.log(pkg); -}, intervalMS); From 1e405545e9b51cd99a24e61f99036356bae78832 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 8 Jan 2024 02:05:41 -0600 Subject: [PATCH 55/98] convert promtail to udspackage --- .../allow-loki-egress-promtail.yaml | 23 ------------ .../allow-to-istiod-promtail.yaml | 23 ------------ .../default-deny-promtail.yaml | 13 ------- .../templates/networkpolicies/egress-api.yaml | 18 ---------- .../networkpolicies/egress-dns-promtail.yaml | 18 ---------- .../egress-tempo-promtail.yaml | 23 ------------ .../ingress-egress-namespace-promtail.yaml | 19 ---------- .../ingress-scraping-promtail.yaml | 23 ------------ .../ingress-sidecar-scraping-promtail.yaml | 23 ------------ src/promtail/chart/templates/uds-package.yaml | 36 +++++++++++++++++++ 10 files changed, 36 insertions(+), 183 deletions(-) delete mode 100644 src/promtail/chart/templates/networkpolicies/allow-loki-egress-promtail.yaml delete mode 100644 src/promtail/chart/templates/networkpolicies/allow-to-istiod-promtail.yaml delete mode 100644 src/promtail/chart/templates/networkpolicies/default-deny-promtail.yaml delete mode 100644 src/promtail/chart/templates/networkpolicies/egress-api.yaml delete mode 100644 src/promtail/chart/templates/networkpolicies/egress-dns-promtail.yaml delete mode 100644 src/promtail/chart/templates/networkpolicies/egress-tempo-promtail.yaml delete mode 100644 src/promtail/chart/templates/networkpolicies/ingress-egress-namespace-promtail.yaml delete mode 100644 src/promtail/chart/templates/networkpolicies/ingress-scraping-promtail.yaml delete mode 100644 src/promtail/chart/templates/networkpolicies/ingress-sidecar-scraping-promtail.yaml create mode 100644 src/promtail/chart/templates/uds-package.yaml diff --git a/src/promtail/chart/templates/networkpolicies/allow-loki-egress-promtail.yaml b/src/promtail/chart/templates/networkpolicies/allow-loki-egress-promtail.yaml deleted file mode 100644 index 14970f839..000000000 --- a/src/promtail/chart/templates/networkpolicies/allow-loki-egress-promtail.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-loki-egress-promtail - namespace: {{ .Release.Namespace }} -spec: - egress: - - ports: - - port: 8080 - protocol: TCP - to: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: loki - podSelector: - matchLabels: - app.kubernetes.io/name: loki - podSelector: - matchLabels: - app.kubernetes.io/name: promtail - app.kubernetes.io/instance: promtail - policyTypes: - - Egress \ No newline at end of file diff --git a/src/promtail/chart/templates/networkpolicies/allow-to-istiod-promtail.yaml b/src/promtail/chart/templates/networkpolicies/allow-to-istiod-promtail.yaml deleted file mode 100644 index 0ca6a1195..000000000 --- a/src/promtail/chart/templates/networkpolicies/allow-to-istiod-promtail.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-to-istiod-promtail - namespace: {{ .Release.Namespace }} -spec: - egress: - - ports: - - port: 15012 - protocol: TCP - to: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: istio-system - podSelector: - matchLabels: - app: istiod - podSelector: - matchLabels: - app.kubernetes.io/instance: promtail - app.kubernetes.io/name: promtail - policyTypes: - - Egress \ No newline at end of file diff --git a/src/promtail/chart/templates/networkpolicies/default-deny-promtail.yaml b/src/promtail/chart/templates/networkpolicies/default-deny-promtail.yaml deleted file mode 100644 index a15cc8907..000000000 --- a/src/promtail/chart/templates/networkpolicies/default-deny-promtail.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: default-deny-promtail - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - app.kubernetes.io/instance: promtail - app.kubernetes.io/name: promtail - policyTypes: - - Ingress - - Egress \ No newline at end of file diff --git a/src/promtail/chart/templates/networkpolicies/egress-api.yaml b/src/promtail/chart/templates/networkpolicies/egress-api.yaml deleted file mode 100644 index 9185fe6c7..000000000 --- a/src/promtail/chart/templates/networkpolicies/egress-api.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: egress-api - namespace: {{ .Release.Namespace }} -spec: - egress: - - to: - - ipBlock: - cidr: 0.0.0.0/0 - except: - - 169.254.169.254/32 - podSelector: - matchLabels: - app.kubernetes.io/instance: promtail - app.kubernetes.io/name: promtail - policyTypes: - - Egress \ No newline at end of file diff --git a/src/promtail/chart/templates/networkpolicies/egress-dns-promtail.yaml b/src/promtail/chart/templates/networkpolicies/egress-dns-promtail.yaml deleted file mode 100644 index 971a3ed76..000000000 --- a/src/promtail/chart/templates/networkpolicies/egress-dns-promtail.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: egress-dns-promtail - namespace: {{ .Release.Namespace }} -spec: - egress: - - ports: - - port: 53 - protocol: UDP - to: - - namespaceSelector: {} - podSelector: - matchLabels: - app.kubernetes.io/instance: promtail - app.kubernetes.io/name: promtail - policyTypes: - - Egress \ No newline at end of file diff --git a/src/promtail/chart/templates/networkpolicies/egress-tempo-promtail.yaml b/src/promtail/chart/templates/networkpolicies/egress-tempo-promtail.yaml deleted file mode 100644 index bbe22b32e..000000000 --- a/src/promtail/chart/templates/networkpolicies/egress-tempo-promtail.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: egress-tempo-promtail - namespace: {{ .Release.Namespace }} -spec: - egress: - - ports: - - port: 9411 - protocol: TCP - to: - - namespaceSelector: - matchLabels: - app.kubernetes.io/name: tempo - podSelector: - matchLabels: - app.kubernetes.io/name: tempo - podSelector: - matchLabels: - app.kubernetes.io/instance: promtail - app.kubernetes.io/name: promtail - policyTypes: - - Egress \ No newline at end of file diff --git a/src/promtail/chart/templates/networkpolicies/ingress-egress-namespace-promtail.yaml b/src/promtail/chart/templates/networkpolicies/ingress-egress-namespace-promtail.yaml deleted file mode 100644 index 046af9477..000000000 --- a/src/promtail/chart/templates/networkpolicies/ingress-egress-namespace-promtail.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: ingress-egress-namespace-promtail - namespace: {{ .Release.Namespace }} - spec: - egress: - - to: - - podSelector: {} - ingress: - - from: - - podSelector: {} - podSelector: - matchLabels: - app.kubernetes.io/instance: promtail - app.kubernetes.io/name: promtail - policyTypes: - - Ingress - - Egress \ No newline at end of file diff --git a/src/promtail/chart/templates/networkpolicies/ingress-scraping-promtail.yaml b/src/promtail/chart/templates/networkpolicies/ingress-scraping-promtail.yaml deleted file mode 100644 index a7fa89be1..000000000 --- a/src/promtail/chart/templates/networkpolicies/ingress-scraping-promtail.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: ingress-scraping-promtail - namespace: {{ .Release.Namespace }} -spec: - ingress: - - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: monitoring - podSelector: - matchLabels: - app: prometheus - ports: - - port: 3101 - protocol: TCP - podSelector: - matchLabels: - app.kubernetes.io/instance: promtail - app.kubernetes.io/name: promtail - policyTypes: - - Ingress \ No newline at end of file diff --git a/src/promtail/chart/templates/networkpolicies/ingress-sidecar-scraping-promtail.yaml b/src/promtail/chart/templates/networkpolicies/ingress-sidecar-scraping-promtail.yaml deleted file mode 100644 index 77f34d376..000000000 --- a/src/promtail/chart/templates/networkpolicies/ingress-sidecar-scraping-promtail.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: ingress-sidecar-scraping-promtail - namespace: {{ .Release.Namespace }} -spec: - ingress: - - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: monitoring - podSelector: - matchLabels: - app: prometheus - ports: - - port: 15020 - protocol: TCP - podSelector: - matchLabels: - app.kubernetes.io/instance: promtail - app.kubernetes.io/name: promtail - policyTypes: - - Ingress \ No newline at end of file diff --git a/src/promtail/chart/templates/uds-package.yaml b/src/promtail/chart/templates/uds-package.yaml new file mode 100644 index 000000000..c7838174f --- /dev/null +++ b/src/promtail/chart/templates/uds-package.yaml @@ -0,0 +1,36 @@ +apiVersion: uds.dev/v1alpha1 +kind: Package +metadata: + name: promtail + namespace: {{ .Release.Namespace }} +spec: + network: + allow: + - direction: Ingress + podSelector: + app.kubernetes.io/name: promtail + remoteNamespace: monitoring + remotePodLabels: + app.kubernetes.io/name: prometheus + port: 3101 + + - direction: Egress + podSelector: + app.kubernetes.io/name: promtail + remoteGenerated: KubeAPI + + - direction: Egress + podLabels: + app.kubernetes.io/name: promtail + remoteNamespace: tempo + remotePodLabels: + app.kubernetes.io/name: tempo + port: 9411 + + - direction: Egress + podLabels: + app.kubernetes.io/name: promtail + remoteNamespace: loki + remotePodLabels: + app.kubernetes.io/name: loki + port: 8080 From 76e80a3a2ae93930309a1e2cfb726195205a1324 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 8 Jan 2024 10:29:50 -0600 Subject: [PATCH 56/98] Readme, unit test updates --- src/pepr/README.md | 7 ++ src/pepr/istio/README.md | 3 + src/pepr/operator/README.md | 18 +++++ .../index.ts => istio/injection.ts} | 3 +- .../istio/{index.ts => virtual-service.ts} | 0 .../network/{index.ts => policies.ts} | 0 src/pepr/operator/enque.spec.ts | 74 +++++++++++++++++++ src/pepr/operator/reconciler.spec.ts | 52 +++++++++++++ src/pepr/operator/reconciler.ts | 8 +- 9 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 src/pepr/README.md create mode 100644 src/pepr/istio/README.md create mode 100644 src/pepr/operator/README.md rename src/pepr/operator/controllers/{namespace/index.ts => istio/injection.ts} (94%) rename src/pepr/operator/controllers/istio/{index.ts => virtual-service.ts} (100%) rename src/pepr/operator/controllers/network/{index.ts => policies.ts} (100%) create mode 100644 src/pepr/operator/enque.spec.ts create mode 100644 src/pepr/operator/reconciler.spec.ts diff --git a/src/pepr/README.md b/src/pepr/README.md new file mode 100644 index 000000000..82a264cb7 --- /dev/null +++ b/src/pepr/README.md @@ -0,0 +1,7 @@ +## UDS Pepr Module + +This module consolidates all the UDS Core Pepr related functionality: + +- [istio](istio/README.md) - Custom Istio behavior to support Job termination +- [operator](operator/README.md) - The UDS Operator manages the lifecycle of UDS Package CRs and their corresponding resources +- [policies](policies/README.md) - A policy engine (like Kyverno or OPA) to enforce security best practices diff --git a/src/pepr/istio/README.md b/src/pepr/istio/README.md new file mode 100644 index 000000000..0015288a1 --- /dev/null +++ b/src/pepr/istio/README.md @@ -0,0 +1,3 @@ +## Istio Pepr Capability + +This single capability manages the lifecycle of jobs have Istio sidecars injected into them. diff --git a/src/pepr/operator/README.md b/src/pepr/operator/README.md new file mode 100644 index 000000000..495ea8551 --- /dev/null +++ b/src/pepr/operator/README.md @@ -0,0 +1,18 @@ +## UDS Operator + +### Key Files and Folders + +```bash +. +├── controllers # Core business logic called by the reconciler +│   ├── istio # Manages Istio VirtualServices and sidecar injection for UDS Packages/Namespace +│   └── network # Manages default and generated NetworkPolicies for UDS Packages/Namespace +├── crd +│   ├── generated # Type files generated by `uds run -f src/pepr/tasks.yaml gen-crds` +│   ├── sources # CRD source files +│   ├── register.ts # Registers the UDS Package CRD with the Kubernetes API +│   └── validator.ts # Validates UDS Package CRs with Pepr +├── enque.ts # Serializes UDS Package CRs for processing by the reconciler +├── index.ts # Entrypoint for the UDS Operator +└── reconciler.ts # Reconciles UDS Package CRs via the controllers +``` diff --git a/src/pepr/operator/controllers/namespace/index.ts b/src/pepr/operator/controllers/istio/injection.ts similarity index 94% rename from src/pepr/operator/controllers/namespace/index.ts rename to src/pepr/operator/controllers/istio/injection.ts index bd777f094..8b38ab300 100644 --- a/src/pepr/operator/controllers/namespace/index.ts +++ b/src/pepr/operator/controllers/istio/injection.ts @@ -1,4 +1,5 @@ import { K8s, kind } from "pepr"; + import { UDSPackage } from "../../crd"; /** @@ -6,7 +7,7 @@ import { UDSPackage } from "../../crd"; * * @param pkg */ -export async function syncNamespace(pkg: UDSPackage) { +export async function enableInjection(pkg: UDSPackage) { if (!pkg.metadata?.namespace || !pkg.metadata.name) { throw new Error(`Invalid Package definition, missing namespace or name`); } diff --git a/src/pepr/operator/controllers/istio/index.ts b/src/pepr/operator/controllers/istio/virtual-service.ts similarity index 100% rename from src/pepr/operator/controllers/istio/index.ts rename to src/pepr/operator/controllers/istio/virtual-service.ts diff --git a/src/pepr/operator/controllers/network/index.ts b/src/pepr/operator/controllers/network/policies.ts similarity index 100% rename from src/pepr/operator/controllers/network/index.ts rename to src/pepr/operator/controllers/network/policies.ts diff --git a/src/pepr/operator/enque.spec.ts b/src/pepr/operator/enque.spec.ts new file mode 100644 index 000000000..e1b4c8c04 --- /dev/null +++ b/src/pepr/operator/enque.spec.ts @@ -0,0 +1,74 @@ +import { beforeEach, expect, jest, describe, test } from "@jest/globals"; +import { Log } from "pepr"; + +import { UDSPackage } from "./crd"; +import { Queue } from "./enque"; +import { reconciler } from "./reconciler"; + +jest.mock("pepr", () => ({ + Log: { + debug: jest.fn(), + }, +})); + +jest.mock("./reconciler", () => ({ + reconciler: jest.fn(), +})); + +describe("Queue", () => { + let queue: Queue; + let mockPackage: UDSPackage; + + beforeEach(() => { + jest.resetAllMocks(); + + queue = new Queue(); + mockPackage = { + metadata: { name: "test-package", namespace: "test-namespace" }, + }; + }); + + test("enqueue should add a package to the queue and return a promise", async () => { + const promise = queue.enqueue(mockPackage); + expect(promise).toBeInstanceOf(Promise); + await promise; // Wait for the promise to resolve + expect(Log.debug).toHaveBeenCalledWith(`Enqueueing test-namespace/test-package`); + expect(reconciler).toHaveBeenCalledWith(mockPackage); + }); + + test("dequeue should process packages in FIFO order", async () => { + const mockPackage2 = { + metadata: { name: "test-package-2", namespace: "test-namespace-2" }, + }; + + // Enqueue two packages + const promise1 = queue.enqueue(mockPackage); + const promise2 = queue.enqueue(mockPackage2); + + // Wait for both promises to resolve + await promise1; + await promise2; + + // Check that reconciler was called with both packages in the correct order + expect(reconciler).toHaveBeenNthCalledWith(1, mockPackage); + expect(reconciler).toHaveBeenNthCalledWith(2, mockPackage2); + }); + + test("dequeue should handle errors in package processing", async () => { + const error = new Error("reconciliation failed"); + (reconciler as jest.Mock<() => Promise>).mockRejectedValueOnce(error); + + try { + await queue.enqueue(mockPackage); + } catch (e) { + expect(e).toBe(error); + } + + // Ensure that the queue is ready to process the next package + const mockPackage2 = { + metadata: { name: "test-package-2", namespace: "test-namespace-2" }, + }; + await queue.enqueue(mockPackage2); + expect(reconciler).toHaveBeenCalledWith(mockPackage2); + }); +}); diff --git a/src/pepr/operator/reconciler.spec.ts b/src/pepr/operator/reconciler.spec.ts new file mode 100644 index 000000000..cc652aebc --- /dev/null +++ b/src/pepr/operator/reconciler.spec.ts @@ -0,0 +1,52 @@ +import { beforeEach, describe, expect, jest, test } from "@jest/globals"; + +import { K8s, Log } from "pepr"; +import { Phase, UDSPackage } from "./crd"; +import { reconciler } from "./reconciler"; + +jest.mock("kubernetes-fluent-client"); +jest.mock("pepr"); +jest.mock("../config"); +jest.mock("./controllers/istio/injection"); +jest.mock("./controllers/istio/virtual-service"); +jest.mock("./controllers/network/policies"); + +describe("reconciler", () => { + let mockPackage: UDSPackage; + + beforeEach(() => { + jest.clearAllMocks(); + + mockPackage = { + metadata: { name: "test-package", namespace: "test-namespace", generation: 1 }, + status: { phase: Phase.Pending, observedGeneration: 0 }, + }; + + (K8s as jest.Mock).mockImplementation(() => ({ + PatchStatus: jest.fn(), + })); + }); + + test("should log an error for invalid package definitions", async () => { + delete mockPackage.metadata!.namespace; + await reconciler(mockPackage); + expect(Log.error).toHaveBeenCalled(); + }); + + test("should skip processing for pending or completed packages", async () => { + mockPackage.status!.phase = Phase.Pending; + await reconciler(mockPackage); + expect(Log.debug).toHaveBeenCalledWith( + expect.anything(), + "Skipping pending or completed package", + ); + + mockPackage.status!.phase = Phase.Ready; + mockPackage.status!.observedGeneration = mockPackage.metadata!.generation; + await reconciler(mockPackage); + expect(Log.debug).toHaveBeenCalledWith( + expect.anything(), + "Skipping pending or completed package", + ); + }); +}); diff --git a/src/pepr/operator/reconciler.ts b/src/pepr/operator/reconciler.ts index b60a2bc35..41d273c93 100644 --- a/src/pepr/operator/reconciler.ts +++ b/src/pepr/operator/reconciler.ts @@ -1,9 +1,9 @@ import { K8s, Log } from "pepr"; import { UDSConfig } from "../config"; -import { virtualService } from "./controllers/istio"; -import { syncNamespace } from "./controllers/namespace"; -import { networkPolicies } from "./controllers/network"; +import { enableInjection } from "./controllers/istio/injection"; +import { virtualService } from "./controllers/istio/virtual-service"; +import { networkPolicies } from "./controllers/network/policies"; import { Phase, Status, UDSPackage } from "./crd"; import { VirtualService } from "./crd/generated/istio/virtualservice-v1beta1"; @@ -39,7 +39,7 @@ export async function reconciler(pkg: UDSPackage) { let vs: VirtualService[] = []; if (UDSConfig.istioInstalled) { // Update the namespace to ensure the istio-injection label is set - await syncNamespace(pkg); + await enableInjection(pkg); // Create the VirtualService for each exposed service vs = await virtualService(pkg, namespace); From f38366f4921d46e646fa060b0aae1f0a719e2d2f Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 8 Jan 2024 10:43:13 -0600 Subject: [PATCH 57/98] add another note about uds operator --- src/pepr/operator/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pepr/operator/README.md b/src/pepr/operator/README.md index 495ea8551..534ec18ea 100644 --- a/src/pepr/operator/README.md +++ b/src/pepr/operator/README.md @@ -1,5 +1,7 @@ ## UDS Operator +The UDS Operator manages the lifecycle of UDS Package CRs and their corresponding resources (e.g. NetworkPolicies, Istio VirtualServices, etc.). The operator uses [Pepr](https://pepr.dev) to bind the watch operations to the enque and reconciler. + ### Key Files and Folders ```bash From 6149efd4df9cdb12d2c98277ffc2323346f055cd Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 8 Jan 2024 11:25:38 -0600 Subject: [PATCH 58/98] add diagram --- src/pepr/operator/README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/pepr/operator/README.md b/src/pepr/operator/README.md index 534ec18ea..ba49b8fe3 100644 --- a/src/pepr/operator/README.md +++ b/src/pepr/operator/README.md @@ -1,6 +1,12 @@ ## UDS Operator -The UDS Operator manages the lifecycle of UDS Package CRs and their corresponding resources (e.g. NetworkPolicies, Istio VirtualServices, etc.). The operator uses [Pepr](https://pepr.dev) to bind the watch operations to the enque and reconciler. +The UDS Operator manages the lifecycle of UDS Package CRs and their corresponding resources (e.g. NetworkPolicies, Istio VirtualServices, etc.). The operator uses [Pepr](https://pepr.dev) to bind the watch operations to the enque and reconciler. The operator is responsible for: + +- enabling Istio sidecar injection in namespaces where the CR is deployed +- establishing default-deny ingress/egress network policies +- creating a layered allow-list based approach on top of the default deny network policies including some basic defaults such as Istio requirements and DNS egress +- providing targeted remote endpoints network policies such as `KubeAPI` and `CloudMetadata` to make policies more DRY and provide dynamic bindings where a static definition is not possible +- creating Istio Virtual Services & related ingress gateway network policies ### Key Files and Folders @@ -18,3 +24,30 @@ The UDS Operator manages the lifecycle of UDS Package CRs and their correspondin ├── index.ts # Entrypoint for the UDS Operator └── reconciler.ts # Reconciles UDS Package CRs via the controllers ``` + + +### Flow + +The UDS Operator leverages a Pepr Watch. The following diagram shows the flow of the UDS Operator: + +```mermaid +graph TD + A["New UDS Package (pkg) received from Pepr"] -->|Watch Action| B["Queue: queue.enqueue(pkg)"] + B --> C{"Check if pkg is next on Queue"} + C -->|Yes| D["queue.dequeue()"] + C -->|No| E["Wait in Queue"] + D --> F["reconciler(pkg)"] + F --> G{"Check if pkg is pending or on current generation"} + G -->|Yes| H["Log: Skipping pkg"] + G -->|No| I["Update pkg status to Phase.Pending"] + I --> J{"Check if Istio is installed"} + J -->|Yes| K["Add injection label, process expose CRs for Virtual Services"] + J -->|No| L["Skip Virtual Service Creation"] + K --> M["Create default network policies in namespace"] + L --> M + M --> N["Process allow CRs for network policies"] + N --> O["Process expose CRs for network policies for VS/Istio ingress routes"] + O --> P["Update status: Phase.Ready, observedGeneration, etc."] + H --> Q["End of process"] + P --> Q +``` From 99b00353a0fee519fc036d8bba7889c720fba8b8 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 8 Jan 2024 11:35:59 -0600 Subject: [PATCH 59/98] shame --- src/pepr/config.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pepr/config.ts b/src/pepr/config.ts index b8b2eac40..ffcc70b8d 100644 --- a/src/pepr/config.ts +++ b/src/pepr/config.ts @@ -1,6 +1,4 @@ export const UDSConfig = { domain: process.env.UDS_DOMAIN || "uds.dev", istioInstalled: process.env.UDS_WITH_ISTIO === "true", - // domain: "uds.dev", - // istioInstalled: true, }; From 2d6919cc2f356c6dc0539c923c19a0c2494cfb0c Mon Sep 17 00:00:00 2001 From: Megamind <882485+jeff-mccoy@users.noreply.github.com> Date: Mon, 8 Jan 2024 15:33:38 -0600 Subject: [PATCH 60/98] Update src/pepr/operator/crd/validator.ts Co-authored-by: Rob Ferguson --- src/pepr/operator/crd/validator.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pepr/operator/crd/validator.ts b/src/pepr/operator/crd/validator.ts index 3427ac754..1f4d42aec 100644 --- a/src/pepr/operator/crd/validator.ts +++ b/src/pepr/operator/crd/validator.ts @@ -15,8 +15,8 @@ export async function validator(req: PeprValidateRequest) { const networkPolicy = req.Raw.spec?.network?.allow ?? []; for (const policy of networkPolicy) { - // remoteGenerated cannot be combined with remoteNamespaceLabels or remotePodLabels - if (policy.remoteGenerated && (policy.remotePodLabels || policy.remotePodLabels)) { + // remoteGenerated cannot be combined with remoteNamespace or remotePodLabels + if (policy.remoteGenerated && (policy.remoteNamespace || policy.remotePodLabels)) { return req.Deny("remoteGenerated cannot be combined with remoteNamespace or remotePodLabels"); } } From eac1d6f8eedf30f9082a666dc8a174fee63f5913 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Mon, 8 Jan 2024 17:19:31 -0600 Subject: [PATCH 61/98] I cant spell --- src/pepr/operator/README.md | 4 ++-- src/pepr/operator/{enque.spec.ts => enqueue.spec.ts} | 2 +- src/pepr/operator/{enque.ts => enqueue.ts} | 0 src/pepr/operator/index.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/pepr/operator/{enque.spec.ts => enqueue.spec.ts} (98%) rename src/pepr/operator/{enque.ts => enqueue.ts} (100%) diff --git a/src/pepr/operator/README.md b/src/pepr/operator/README.md index ba49b8fe3..92c1b794a 100644 --- a/src/pepr/operator/README.md +++ b/src/pepr/operator/README.md @@ -1,6 +1,6 @@ ## UDS Operator -The UDS Operator manages the lifecycle of UDS Package CRs and their corresponding resources (e.g. NetworkPolicies, Istio VirtualServices, etc.). The operator uses [Pepr](https://pepr.dev) to bind the watch operations to the enque and reconciler. The operator is responsible for: +The UDS Operator manages the lifecycle of UDS Package CRs and their corresponding resources (e.g. NetworkPolicies, Istio VirtualServices, etc.). The operator uses [Pepr](https://pepr.dev) to bind the watch operations to the enqueue and reconciler. The operator is responsible for: - enabling Istio sidecar injection in namespaces where the CR is deployed - establishing default-deny ingress/egress network policies @@ -20,7 +20,7 @@ The UDS Operator manages the lifecycle of UDS Package CRs and their correspondin │   ├── sources # CRD source files │   ├── register.ts # Registers the UDS Package CRD with the Kubernetes API │   └── validator.ts # Validates UDS Package CRs with Pepr -├── enque.ts # Serializes UDS Package CRs for processing by the reconciler +├── enqueue.ts # Serializes UDS Package CRs for processing by the reconciler ├── index.ts # Entrypoint for the UDS Operator └── reconciler.ts # Reconciles UDS Package CRs via the controllers ``` diff --git a/src/pepr/operator/enque.spec.ts b/src/pepr/operator/enqueue.spec.ts similarity index 98% rename from src/pepr/operator/enque.spec.ts rename to src/pepr/operator/enqueue.spec.ts index e1b4c8c04..f483627c6 100644 --- a/src/pepr/operator/enque.spec.ts +++ b/src/pepr/operator/enqueue.spec.ts @@ -2,7 +2,7 @@ import { beforeEach, expect, jest, describe, test } from "@jest/globals"; import { Log } from "pepr"; import { UDSPackage } from "./crd"; -import { Queue } from "./enque"; +import { Queue } from "./enqueue"; import { reconciler } from "./reconciler"; jest.mock("pepr", () => ({ diff --git a/src/pepr/operator/enque.ts b/src/pepr/operator/enqueue.ts similarity index 100% rename from src/pepr/operator/enque.ts rename to src/pepr/operator/enqueue.ts diff --git a/src/pepr/operator/index.ts b/src/pepr/operator/index.ts index 13be13f4f..82c817211 100644 --- a/src/pepr/operator/index.ts +++ b/src/pepr/operator/index.ts @@ -3,7 +3,7 @@ import { Capability } from "pepr"; import { UDSPackage } from "./crd"; import "./crd/register"; import { validator } from "./crd/validator"; -import { Queue } from "./enque"; +import { Queue } from "./enqueue"; export const operator = new Capability({ name: "uds-core-operator", From 4ea5290ccc5cbd73afb9b2b34820c4366d9af04f Mon Sep 17 00:00:00 2001 From: Megamind <882485+jeff-mccoy@users.noreply.github.com> Date: Mon, 8 Jan 2024 21:18:06 -0600 Subject: [PATCH 62/98] Update src/pepr/istio/README.md Co-authored-by: razzle --- src/pepr/istio/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/istio/README.md b/src/pepr/istio/README.md index 0015288a1..db284df76 100644 --- a/src/pepr/istio/README.md +++ b/src/pepr/istio/README.md @@ -1,3 +1,3 @@ ## Istio Pepr Capability -This single capability manages the lifecycle of jobs have Istio sidecars injected into them. +This capability manages the lifecycle of jobs that have Istio sidecars injected into them. From 2e1d3555b5ecbb7d190b1a576d8a0ac02783ffea Mon Sep 17 00:00:00 2001 From: Megamind <882485+jeff-mccoy@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:04:47 -0600 Subject: [PATCH 63/98] Update src/pepr/operator/README.md Co-authored-by: Wayne Starr --- src/pepr/operator/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/operator/README.md b/src/pepr/operator/README.md index 92c1b794a..a84744b88 100644 --- a/src/pepr/operator/README.md +++ b/src/pepr/operator/README.md @@ -20,7 +20,7 @@ The UDS Operator manages the lifecycle of UDS Package CRs and their correspondin │   ├── sources # CRD source files │   ├── register.ts # Registers the UDS Package CRD with the Kubernetes API │   └── validator.ts # Validates UDS Package CRs with Pepr -├── enqueue.ts # Serializes UDS Package CRs for processing by the reconciler +├── enqueue.ts # Serializes UDS Package CRs for processing by the reconciler ├── index.ts # Entrypoint for the UDS Operator └── reconciler.ts # Reconciles UDS Package CRs via the controllers ``` From 719ffbe855ae42e932cf4429518982db8d0a734b Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Tue, 9 Jan 2024 13:22:19 -0600 Subject: [PATCH 64/98] ensure default-deny is unique per pkg --- .../controllers/network/defaults/default-deny-all.ts | 2 +- src/pepr/operator/controllers/network/policies.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pepr/operator/controllers/network/defaults/default-deny-all.ts b/src/pepr/operator/controllers/network/defaults/default-deny-all.ts index f2402e67e..9382b5c69 100644 --- a/src/pepr/operator/controllers/network/defaults/default-deny-all.ts +++ b/src/pepr/operator/controllers/network/defaults/default-deny-all.ts @@ -5,7 +5,7 @@ export function defaultDenyAll(namespace: string): kind.NetworkPolicy { apiVersion: "networking.k8s.io/v1", kind: "NetworkPolicy", metadata: { - name: "uds-default-deny-all", + name: "default", namespace, }, spec: { diff --git a/src/pepr/operator/controllers/network/policies.ts b/src/pepr/operator/controllers/network/policies.ts index 3ea210d5c..ae8f10f2a 100644 --- a/src/pepr/operator/controllers/network/policies.ts +++ b/src/pepr/operator/controllers/network/policies.ts @@ -63,8 +63,10 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { policy.metadata.labels["uds/package"] = pkg.metadata!.name!; policy.metadata.labels["uds/generation"] = generation; - // If not the default deny all policy, add the index to the name - if (idx > 0) { + // Add the package name to the name of the policy to ensure uniqueness + if (idx < 1) { + policy.metadata.name = `deny-uds-${policy.metadata.name}`; + } else { policy.metadata.name = `allow-uds-${policy.metadata.name}`; } From 73704fe226e748bff1d90f7539bf2b45a5330313 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Tue, 9 Jan 2024 13:32:45 -0600 Subject: [PATCH 65/98] Canine Infectious Respiratory Disease --- src/pepr/operator/controllers/network/generators/kubeAPI.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/operator/controllers/network/generators/kubeAPI.ts b/src/pepr/operator/controllers/network/generators/kubeAPI.ts index 7319b4456..8e80414bb 100644 --- a/src/pepr/operator/controllers/network/generators/kubeAPI.ts +++ b/src/pepr/operator/controllers/network/generators/kubeAPI.ts @@ -41,6 +41,6 @@ async function getAPIServerCIDR(): Promise { } // Log a warning and default to 0.0.0.0/0 if the IP is not found - Log.warn("Unable to get API server CIRD, defaulting to 0.0.0.0/0"); + Log.warn("Unable to get API server CIDR, defaulting to 0.0.0.0/0"); return [anywhere]; } From 90a570938ac59d3a3980a077e6b3909eac04b2a8 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Tue, 9 Jan 2024 15:17:00 -0600 Subject: [PATCH 66/98] add policy description to annotations --- src/pepr/operator/controllers/network/generate.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index 208ea2786..794fe8a73 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -28,6 +28,13 @@ export function generate(namespace: string, policy: Allow): kind.NetworkPolicy { }, }; + // Add the description if it exists to the annotations in case of truncation of the name + if (policy.description) { + generated.metadata!.annotations = { + "uds/description": policy.description, + }; + } + // Create the remote (peer) to match against let peers: V1NetworkPolicyPeer[] = []; From c67502eb11c9cfaa04420373d07deeb587781620 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Tue, 9 Jan 2024 15:17:20 -0600 Subject: [PATCH 67/98] include uds pkg name in netpol name --- src/pepr/operator/controllers/network/policies.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pepr/operator/controllers/network/policies.ts b/src/pepr/operator/controllers/network/policies.ts index ae8f10f2a..51411f0ee 100644 --- a/src/pepr/operator/controllers/network/policies.ts +++ b/src/pepr/operator/controllers/network/policies.ts @@ -11,6 +11,7 @@ import { generate } from "./generate"; export async function networkPolicies(pkg: UDSPackage, namespace: string) { const customPolicies = pkg.spec?.network?.allow ?? []; + const pkgName = pkg.metadata!.name!; // Get the current generation of the package const generation = (pkg.metadata?.generation ?? 0).toString(); @@ -60,14 +61,14 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // Add the package name and generation to the labels policy.metadata = policy.metadata ?? {}; policy.metadata.labels = policy.metadata?.labels ?? {}; - policy.metadata.labels["uds/package"] = pkg.metadata!.name!; + policy.metadata.labels["uds/package"] = pkgName; policy.metadata.labels["uds/generation"] = generation; // Add the package name to the name of the policy to ensure uniqueness if (idx < 1) { - policy.metadata.name = `deny-uds-${policy.metadata.name}`; + policy.metadata.name = `deny-${pkgName}-${policy.metadata.name}`; } else { - policy.metadata.name = `allow-uds-${policy.metadata.name}`; + policy.metadata.name = `allow-${pkgName}-${policy.metadata.name}`; } // Use the CR as the owner ref for each NetworkPolicy @@ -80,7 +81,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // Delete any policies that are no longer needed const policyList = await K8s(kind.NetworkPolicy) .InNamespace(namespace) - .WithLabel("uds/package", pkg.metadata!.name!) + .WithLabel("uds/package", pkgName) .Get(); // Find any orphaned polices (not matching the current generation) From 5411421cc0aa4079525380a323c88d1e6972f86e Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Tue, 9 Jan 2024 19:15:40 -0600 Subject: [PATCH 68/98] move truncate netpol name function --- src/pepr/operator/controllers/network/generate.ts | 4 ---- src/pepr/operator/controllers/network/policies.ts | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index 794fe8a73..c3007f93a 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -133,9 +133,5 @@ function generateName(policy: Allow) { .toLowerCase() // Replace sequences of non-alphanumeric characters with a single '-' .replace(/[^a-z0-9]+/g, "-") - // Truncate the name 245 characters - .slice(0, 245) - // Remove leading and trailing '-' - .replace(/^-|-$/g, "") ); } diff --git a/src/pepr/operator/controllers/network/policies.ts b/src/pepr/operator/controllers/network/policies.ts index 51411f0ee..f5135ef62 100644 --- a/src/pepr/operator/controllers/network/policies.ts +++ b/src/pepr/operator/controllers/network/policies.ts @@ -71,6 +71,9 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { policy.metadata.name = `allow-${pkgName}-${policy.metadata.name}`; } + // Truncate the name 250 characters and remove leading and trailing '-' + policy.metadata.name = policy.metadata.name.slice(0, 250).replace(/^-|-$/g, ""); + // Use the CR as the owner ref for each NetworkPolicy policy.metadata.ownerReferences = getOwnerRef(pkg); From 31c36d6d4d506d0554d63750055916e95e62d710 Mon Sep 17 00:00:00 2001 From: Megamind <882485+jeff-mccoy@users.noreply.github.com> Date: Tue, 9 Jan 2024 19:23:56 -0600 Subject: [PATCH 69/98] Update src/pepr/operator/controllers/network/policies.ts Co-authored-by: Micah Nagel --- src/pepr/operator/controllers/network/policies.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/operator/controllers/network/policies.ts b/src/pepr/operator/controllers/network/policies.ts index f5135ef62..54521203b 100644 --- a/src/pepr/operator/controllers/network/policies.ts +++ b/src/pepr/operator/controllers/network/policies.ts @@ -94,7 +94,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { // Delete any orphaned policies for (const netPol of orphanedNetPol) { - Log.debug(netPol, `Deleting orphaned VirtualService ${netPol.metadata!.name}`); + Log.debug(netPol, `Deleting orphaned NetworkPolicy ${netPol.metadata!.name}`); await K8s(kind.NetworkPolicy).Delete(netPol); } From ba02db78cb527084c0849f408e5665da95d31498 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Tue, 9 Jan 2024 19:28:30 -0600 Subject: [PATCH 70/98] more DRY dequeue --- src/pepr/operator/enqueue.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pepr/operator/enqueue.ts b/src/pepr/operator/enqueue.ts index 4b37edc8b..b8161c5d6 100644 --- a/src/pepr/operator/enqueue.ts +++ b/src/pepr/operator/enqueue.ts @@ -53,14 +53,13 @@ export class Queue { // Reconcile the package await reconciler(item.pkg); - // Reset the pending promise flag and resolve the promise - this.#pendingPromise = false; item.resolve(); } catch (e) { - // Reset the pending promise flag and reject the promise on error - this.#pendingPromise = false; item.reject(e); } finally { + // Reset the pending promise flag + this.#pendingPromise = false; + // After the package is reconciled, dequeue the next package await this.#dequeue(); } From b8c071412500e5ce6d01b7432c50641edaf69068 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Tue, 9 Jan 2024 19:35:44 -0600 Subject: [PATCH 71/98] remove test file --- test.yaml | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 test.yaml diff --git a/test.yaml b/test.yaml deleted file mode 100644 index c85be07e9..000000000 --- a/test.yaml +++ /dev/null @@ -1,27 +0,0 @@ - -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - creationTimestamp: "2023-12-19T08:16:38Z" - generation: 2 - labels: - uds/package: metrics-server - name: metrics-server-istio-ingress - namespace: metrics-server - resourceVersion: "3588" - uid: 6fb67791-280d-404d-9251-22f4d3e38a16 -spec: - ingress: - - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: istio-system - podSelector: {} - ports: - - port: 443 - protocol: TCP - podSelector: - matchLabels: - app.kubernetes.io/name: metrics-server - policyTypes: - - Ingress From 04b6a1dcc84980527096af9dadcd5efc0635b82c Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Tue, 9 Jan 2024 19:44:46 -0600 Subject: [PATCH 72/98] consolidate resource name sanitization --- .../controllers/istio/virtual-service.ts | 4 +++- .../operator/controllers/network/generate.ts | 8 +------- .../operator/controllers/network/policies.ts | 7 +++---- src/pepr/operator/controllers/utils.ts | 19 +++++++++++++++++++ 4 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 src/pepr/operator/controllers/utils.ts diff --git a/src/pepr/operator/controllers/istio/virtual-service.ts b/src/pepr/operator/controllers/istio/virtual-service.ts index e3c1c91ad..df1adbe69 100644 --- a/src/pepr/operator/controllers/istio/virtual-service.ts +++ b/src/pepr/operator/controllers/istio/virtual-service.ts @@ -2,6 +2,7 @@ import { K8s, Log } from "pepr"; import { UDSConfig } from "../../../config"; import { Gateway, Istio, UDSPackage, getOwnerRef } from "../../crd"; +import { sanitizeResourceName } from "../utils"; /** * Creates a VirtualService for each exposed service in the package @@ -22,7 +23,8 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { for (const expose of exposeList) { const { gateway = Gateway.Tenant, host, port, service, mode } = expose; - const name = `${pkgName}-${gateway}-${host}`.toLowerCase(); + // Ensure the resource name is valid + const name = sanitizeResourceName(`${pkgName}-${gateway}-${host}`); // Create the route to the service const route: Istio.TCPRoute[] | Istio.HTTPRoute[] = [ diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index c3007f93a..3385263ac 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -127,11 +127,5 @@ function generateName(policy: Allow) { .flat(1) .join("-"); - return ( - `${policy.direction}-${name}` - // The name must be lowercase - .toLowerCase() - // Replace sequences of non-alphanumeric characters with a single '-' - .replace(/[^a-z0-9]+/g, "-") - ); + return `${policy.direction}-${name}`; } diff --git a/src/pepr/operator/controllers/network/policies.ts b/src/pepr/operator/controllers/network/policies.ts index 54521203b..f15458777 100644 --- a/src/pepr/operator/controllers/network/policies.ts +++ b/src/pepr/operator/controllers/network/policies.ts @@ -1,12 +1,11 @@ import { K8s, Log, kind } from "pepr"; import { Allow, Direction, Gateway, UDSPackage, getOwnerRef } from "../../crd"; +import { sanitizeResourceName } from "../utils"; import { allowEgressDNS } from "./defaults/allow-egress-dns"; import { allowEgressIstiod } from "./defaults/allow-egress-istiod"; import { allowIngressSidecarMonitoring } from "./defaults/allow-ingress-sidecar-monitoring"; import { defaultDenyAll } from "./defaults/default-deny-all"; - -// Import the NetworkPolicy transforms webhook import { generate } from "./generate"; export async function networkPolicies(pkg: UDSPackage, namespace: string) { @@ -71,8 +70,8 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { policy.metadata.name = `allow-${pkgName}-${policy.metadata.name}`; } - // Truncate the name 250 characters and remove leading and trailing '-' - policy.metadata.name = policy.metadata.name.slice(0, 250).replace(/^-|-$/g, ""); + // Ensure the name is a valid resource name + policy.metadata.name = sanitizeResourceName(policy.metadata.name); // Use the CR as the owner ref for each NetworkPolicy policy.metadata.ownerReferences = getOwnerRef(pkg); diff --git a/src/pepr/operator/controllers/utils.ts b/src/pepr/operator/controllers/utils.ts new file mode 100644 index 000000000..65fe25ea3 --- /dev/null +++ b/src/pepr/operator/controllers/utils.ts @@ -0,0 +1,19 @@ +/** + * Sanitize a resource name to make it a valid Kubernetes resource name. + * + * @param name the name of the resource to sanitize + * @returns the sanitized resource name + */ +export function sanitizeResourceName(name: string) { + return ( + name + // The name must be lowercase + .toLowerCase() + // Replace sequences of non-alphanumeric characters with a single '-' + .replace(/[^a-z0-9]+/g, "-") + // Truncate the name to 250 characters + .slice(0, 250) + // Remove leading and trailing non-letter characters + .replace(/^[^a-z]+|[^a-z]+$/g, "") + ); +} From 3c3a698a51743914c980bd127797ec9b55b0600a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 03:11:46 +0000 Subject: [PATCH 73/98] chore(deps): update uds to v0.5.3 | datasource | package | from | to | | ----------- | ----------------------- | ----- | ----- | | github-tags | defenseunicorns/uds-cli | 0.5.2 | 0.5.3 | --- .github/actions/setup/action.yaml | 2 +- .vscode/settings.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/setup/action.yaml b/.github/actions/setup/action.yaml index 4f97160c7..13c9644a0 100644 --- a/.github/actions/setup/action.yaml +++ b/.github/actions/setup/action.yaml @@ -27,4 +27,4 @@ runs: - name: Install UDS CLI shell: bash # renovate: datasource=github-tags depName=defenseunicorns/uds-cli versioning=semver - run: brew install defenseunicorns/tap/uds@0.5.2 + run: brew install defenseunicorns/tap/uds@0.5.3 diff --git a/.vscode/settings.json b/.vscode/settings.json index e1295d6c3..f4942a9f0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,12 +8,12 @@ }, "yaml.schemas": { // renovate: datasource=github-tags depName=defenseunicorns/uds-cli versioning=semver - "https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.5.2/uds.schema.json": [ + "https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.5.3/uds.schema.json": [ "uds-bundle.yaml" ], // renovate: datasource=github-tags depName=defenseunicorns/uds-cli versioning=semver - "https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.5.2/tasks.schema.json": [ + "https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.5.3/tasks.schema.json": [ "tasks.yaml", "tasks/**/*.yaml", "src/**/validate.yaml" From 35e3eef7b42fb4dcb1fa1af861465d13b926e766 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 10 Jan 2024 23:34:16 -0600 Subject: [PATCH 74/98] properly wire passthrough tls for VirtualServices --- .../controllers/istio/virtual-service.ts | 29 ++++++++++++++----- .../crd/generated/package-v1alpha1.ts | 12 -------- src/pepr/operator/crd/sources/v1alpha1.ts | 6 ---- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/pepr/operator/controllers/istio/virtual-service.ts b/src/pepr/operator/controllers/istio/virtual-service.ts index df1adbe69..57f67a844 100644 --- a/src/pepr/operator/controllers/istio/virtual-service.ts +++ b/src/pepr/operator/controllers/istio/virtual-service.ts @@ -17,17 +17,24 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { // Get the list of exposed services const exposeList = pkg.spec?.network?.expose ?? []; + // Create a list of generated VirtualServices const payloads: Istio.VirtualService[] = []; // Iterate over each exposed service for (const expose of exposeList) { - const { gateway = Gateway.Tenant, host, port, service, mode } = expose; + const { gateway = Gateway.Tenant, host, port, service } = expose; // Ensure the resource name is valid const name = sanitizeResourceName(`${pkgName}-${gateway}-${host}`); + // For the admin gateway, we need to add the path prefix + const domain = (gateway === Gateway.Admin ? "admin." : "") + UDSConfig.domain; + + // Append the domain to the host + const fqdn = `${host}.${domain}`; + // Create the route to the service - const route: Istio.TCPRoute[] | Istio.HTTPRoute[] = [ + const httpRoute: Istio.HTTPRoute[] = [ { destination: { // Use the service name as the host @@ -38,9 +45,6 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { }, ]; - // For the admin gateway, we need to add the path prefix - const domain = (gateway === Gateway.Admin ? "admin." : "") + UDSConfig.domain; - const payload: Istio.VirtualService = { metadata: { name, @@ -54,14 +58,23 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { }, spec: { // Append the UDS Domain to the host - hosts: [`${host}.${domain}`], + hosts: [fqdn], // Map the gateway (admin, passthrough or tenant) to the VirtualService gateways: [`istio-${gateway}-gateway/${gateway}-gateway`], + // Apply the route to the VirtualService + http: [{ route: httpRoute }], }, }; - // Add the route to the spec based on the mode - payload.spec![mode ?? "http"] = [{ route }]; + // If the gateway is the passthrough gateway, apply the TLS match + if (gateway === Gateway.Passthrough) { + payload.spec!.tls = [ + { + match: [{ port, sniHosts: [fqdn] }], + route: httpRoute, + }, + ]; + } Log.debug(payload, `Applying VirtualService ${name}`); diff --git a/src/pepr/operator/crd/generated/package-v1alpha1.ts b/src/pepr/operator/crd/generated/package-v1alpha1.ts index e21962666..3472d8268 100644 --- a/src/pepr/operator/crd/generated/package-v1alpha1.ts +++ b/src/pepr/operator/crd/generated/package-v1alpha1.ts @@ -96,10 +96,6 @@ export interface Expose { * The hostname to expose the service on */ host: string; - /** - * The mode to use when exposing the service - */ - mode?: Mode; /** * Labels to match pods in the namespace to apply the policy to. Leave empty to apply to all * pods in the namespace @@ -130,14 +126,6 @@ export enum Gateway { Tenant = "tenant", } -/** - * The mode to use when exposing the service - */ -export enum Mode { - HTTP = "http", - TCP = "tcp", -} - export interface Status { endpoints?: string[]; networkPolicyCount?: number; diff --git a/src/pepr/operator/crd/sources/v1alpha1.ts b/src/pepr/operator/crd/sources/v1alpha1.ts index df19067f6..52b7c4522 100644 --- a/src/pepr/operator/crd/sources/v1alpha1.ts +++ b/src/pepr/operator/crd/sources/v1alpha1.ts @@ -111,12 +111,6 @@ export const v1alpha1: V1CustomResourceDefinitionVersion = { description: "The hostname to expose the service on", type: "string", }, - mode: { - description: "The mode to use when exposing the service", - enum: ["http", "tcp"], - type: "string", - default: "http", - }, }, }, }, From 3d3739510e0b16e268ad1cf6520ce2c47e2ec44b Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 10 Jan 2024 23:40:41 -0600 Subject: [PATCH 75/98] update UDS CLI min version in READMEs --- README.md | 4 ++-- bundles/k3d-istio/README.md | 4 ++-- bundles/k3d-standard/README.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f67805665..a64fcd4ee 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ > [!WARNING] > UDS Core is in early alpha and is not ready for general use. -UDS Core groups foundational Unicorn Delivery Service applications that are heavily influenced [Big Bang](https://repo1.dso.mil/big-bang/bigbang). +UDS Core groups foundational Unicorn Delivery Service applications inspired by [Big Bang](https://repo1.dso.mil/big-bang/bigbang). The core applications are: @@ -28,7 +28,7 @@ The core applications are: | Dependency | Minimum Version | | -------------------------------------------------------------- | --------------- | | [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.31.1 | -| [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.4.1 | +| [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.5.3 | | [NodeJS](https://nodejs.org/en/download/) | LTS or Current | diff --git a/bundles/k3d-istio/README.md b/bundles/k3d-istio/README.md index 2c07c4389..97880aefa 100644 --- a/bundles/k3d-istio/README.md +++ b/bundles/k3d-istio/README.md @@ -3,7 +3,7 @@ > [!WARNING] > UDS Core is in early alpha and is not ready for general use. -UDS Core groups foundational Unicorn Delivery Service applications that are heavily influenced [Big Bang](https://repo1.dso.mil/big-bang/bigbang). +UDS Core groups foundational Unicorn Delivery Service applications inspired by [Big Bang](https://repo1.dso.mil/big-bang/bigbang). The core applications are: @@ -25,7 +25,7 @@ The k3d uds-dev-stack provides: | Dependency | Minimum Version | | -------------------------------------------------------------- | --------------- | | [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.31.1 | -| [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.4.1 | +| [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.5.3 | | [NodeJS](https://nodejs.org/en/download/) | LTS or Current | diff --git a/bundles/k3d-standard/README.md b/bundles/k3d-standard/README.md index 832698aa4..2e56478e3 100644 --- a/bundles/k3d-standard/README.md +++ b/bundles/k3d-standard/README.md @@ -3,7 +3,7 @@ > [!WARNING] > UDS Core is in early alpha and is not ready for general use. -UDS Core groups foundational Unicorn Delivery Service applications that are heavily influenced [Big Bang](https://repo1.dso.mil/big-bang/bigbang). +UDS Core groups foundational Unicorn Delivery Service applications inspired by [Big Bang](https://repo1.dso.mil/big-bang/bigbang). The core applications are: @@ -36,7 +36,7 @@ The k3d uds-dev-stack provides: | Dependency | Minimum Version | | -------------------------------------------------------------- | --------------- | | [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.31.1 | -| [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.4.1 | +| [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.5.3 | | [NodeJS](https://nodejs.org/en/download/) | LTS or Current | From fee2c558e38588a71cdcbb0cfda2bc78a4171781 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:22:33 +0000 Subject: [PATCH 76/98] chore(deps): update uds-k3d to v0.3.0 | datasource | package | from | to | | ----------- | ----------------------- | ----- | ----- | | github-tags | defenseunicorns/uds-k3d | 0.2.1 | 0.3.0 | --- bundles/k3d-istio/uds-bundle.yaml | 2 +- bundles/k3d-standard/uds-bundle.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/k3d-istio/uds-bundle.yaml b/bundles/k3d-istio/uds-bundle.yaml index af8f7b3f5..733f3c153 100644 --- a/bundles/k3d-istio/uds-bundle.yaml +++ b/bundles/k3d-istio/uds-bundle.yaml @@ -10,7 +10,7 @@ packages: - name: uds-k3d-dev repository: ghcr.io/defenseunicorns/packages/uds-k3d # renovate: datasource=github-tags depName=defenseunicorns/uds-k3d versioning=semver - ref: 0.2.1 + ref: 0.3.0 overrides: uds-dev-stack: minio: diff --git a/bundles/k3d-standard/uds-bundle.yaml b/bundles/k3d-standard/uds-bundle.yaml index 5b3b8acad..8b096bd2c 100644 --- a/bundles/k3d-standard/uds-bundle.yaml +++ b/bundles/k3d-standard/uds-bundle.yaml @@ -10,7 +10,7 @@ packages: - name: uds-k3d-dev repository: ghcr.io/defenseunicorns/packages/uds-k3d # renovate: datasource=github-tags depName=defenseunicorns/uds-k3d versioning=semver - ref: 0.2.1 + ref: 0.3.0 overrides: uds-dev-stack: minio: From 8fb20af95b4f04a7833aef342bc2f572ac270753 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 08:34:22 +0000 Subject: [PATCH 77/98] chore(deps): update zarf to v0.32.1 | datasource | package | from | to | | ----------- | -------------------- | ------- | ------- | | github-tags | defenseunicorns/zarf | v0.31.1 | v0.32.1 | --- .github/actions/setup/action.yaml | 2 +- .vscode/settings.json | 2 +- bundles/k3d-istio/uds-bundle.yaml | 2 +- bundles/k3d-standard/uds-bundle.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/setup/action.yaml b/.github/actions/setup/action.yaml index 13c9644a0..ecead8906 100644 --- a/.github/actions/setup/action.yaml +++ b/.github/actions/setup/action.yaml @@ -9,7 +9,7 @@ runs: uses: defenseunicorns/setup-zarf@main with: # renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver - version: v0.31.1 + version: v0.32.1 download-init-package: true - name: Use Node.js latest diff --git a/.vscode/settings.json b/.vscode/settings.json index f4942a9f0..200f2c1a3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,7 +19,7 @@ "src/**/validate.yaml" ], // renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver - "https://raw.githubusercontent.com/defenseunicorns/zarf/v0.31.1/zarf.schema.json": [ + "https://raw.githubusercontent.com/defenseunicorns/zarf/v0.32.1/zarf.schema.json": [ "zarf.yaml" ] }, diff --git a/bundles/k3d-istio/uds-bundle.yaml b/bundles/k3d-istio/uds-bundle.yaml index 733f3c153..2bec24546 100644 --- a/bundles/k3d-istio/uds-bundle.yaml +++ b/bundles/k3d-istio/uds-bundle.yaml @@ -31,7 +31,7 @@ packages: - name: init repository: ghcr.io/defenseunicorns/packages/init # renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver - ref: v0.31.1 + ref: v0.32.1 - name: core-istio path: ../../build/ diff --git a/bundles/k3d-standard/uds-bundle.yaml b/bundles/k3d-standard/uds-bundle.yaml index 8b096bd2c..0886ad2df 100644 --- a/bundles/k3d-standard/uds-bundle.yaml +++ b/bundles/k3d-standard/uds-bundle.yaml @@ -31,7 +31,7 @@ packages: - name: init repository: ghcr.io/defenseunicorns/packages/init # renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver - ref: v0.31.1 + ref: v0.32.1 - name: core path: ../../build/ From 826b28a784b5ba9659575fd0f4f6d53118015202 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 10 Jan 2024 23:45:59 -0600 Subject: [PATCH 78/98] fix zarf & uds-k3d versions --- README.md | 2 +- bundles/k3d-istio/README.md | 2 +- bundles/k3d-standard/README.md | 2 +- tasks/setup.yaml | 5 +++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a64fcd4ee..a0eec3bc6 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ The core applications are: | Dependency | Minimum Version | | -------------------------------------------------------------- | --------------- | -| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.31.1 | +| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.32.1 | | [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.5.3 | | [NodeJS](https://nodejs.org/en/download/) | LTS or Current | diff --git a/bundles/k3d-istio/README.md b/bundles/k3d-istio/README.md index 97880aefa..e94ddd466 100644 --- a/bundles/k3d-istio/README.md +++ b/bundles/k3d-istio/README.md @@ -24,7 +24,7 @@ The k3d uds-dev-stack provides: | Dependency | Minimum Version | | -------------------------------------------------------------- | --------------- | -| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.31.1 | +| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.32.1 | | [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.5.3 | | [NodeJS](https://nodejs.org/en/download/) | LTS or Current | diff --git a/bundles/k3d-standard/README.md b/bundles/k3d-standard/README.md index 2e56478e3..e07024dff 100644 --- a/bundles/k3d-standard/README.md +++ b/bundles/k3d-standard/README.md @@ -35,7 +35,7 @@ The k3d uds-dev-stack provides: | Dependency | Minimum Version | | -------------------------------------------------------------- | --------------- | -| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.31.1 | +| [Zarf](https://github.com/defenseunicorns/zarf/releases) | 0.32.1 | | [UDS CLI](https://github.com/defenseunicorns/uds-cli/releases) | 0.5.3 | | [NodeJS](https://nodejs.org/en/download/) | LTS or Current | diff --git a/tasks/setup.yaml b/tasks/setup.yaml index 392ceaa08..075cea925 100644 --- a/tasks/setup.yaml +++ b/tasks/setup.yaml @@ -3,8 +3,9 @@ tasks: actions: - description: "Create the K3d cluster" # renovate: datasource=github-tags depName=defenseunicorns/uds-k3d versioning=semver - cmd: "zarf package deploy oci://defenseunicorns/uds-k3d:0.2.1-multi --confirm" + # renovate: datasource=github-tags depName=defenseunicorns/uds-k3d versioning=semver + cmd: "zarf package deploy oci://defenseunicorns/uds-k3d:0.3.0 --confirm" - description: "Initialize the cluster with Zarf" # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver - cmd: "zarf package deploy oci://defenseunicorns/init:v0.31.1-${UDS_ARCH} --confirm" + cmd: "zarf package deploy oci://defenseunicorns/init:v0.32.1-${UDS_ARCH} --confirm" From fa00eb07c3fae5e9f5314af46eac1939fc8624db Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Wed, 10 Jan 2024 23:46:11 -0600 Subject: [PATCH 79/98] package.json cleanup --- package-lock.json | 175 +++++++++++++++++++++++++--------------------- package.json | 3 +- 2 files changed, 96 insertions(+), 82 deletions(-) diff --git a/package-lock.json b/package-lock.json index 33fc1046e..f6ed93de6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,8 +13,7 @@ "devDependencies": { "@jest/globals": "29.7.0", "jest": "29.7.0", - "ts-jest": "29.1.1", - "typescript": "5.3.3" + "ts-jest": "29.1.1" }, "engines": { "node": ">=18.0.0" @@ -136,21 +135,21 @@ } }, "node_modules/@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -175,12 +174,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.23.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -190,14 +189,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -340,14 +339,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", + "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" @@ -439,9 +438,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -642,20 +641,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -672,9 +671,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -1121,13 +1120,13 @@ "integrity": "sha512-q9U8v/n9qbkd2zDYjuX3qtlbl+OIyI9zF+zQhZjfYOE9VMDH7tfcUSJ9p0lXoY3lxmGFne09yi4iiNeQUwV7AA==" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "peer": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -1148,9 +1147,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "peer": true }, "node_modules/@istanbuljs/load-nyc-config": { @@ -1697,9 +1696,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.7", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", - "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" @@ -1716,9 +1715,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", - "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" @@ -1769,9 +1768,9 @@ "peer": true }, "node_modules/@types/node": { - "version": "20.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", - "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", + "version": "20.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", "dependencies": { "undici-types": "~5.26.4" } @@ -2074,9 +2073,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "peer": true, "bin": { "acorn": "bin/acorn" @@ -2539,9 +2538,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001566", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", - "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", + "version": "1.0.30001576", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz", + "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==", "dev": true, "funding": [ { @@ -2910,9 +2909,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.603", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.603.tgz", - "integrity": "sha512-Dvo5OGjnl7AZTU632dFJtWj0uJK835eeOVQIuRcmBmsFsTNn3cL05FqOyHAfGQDIoHfLhyJ1Tya3PJ0ceMz54g==", + "version": "1.4.628", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.628.tgz", + "integrity": "sha512-2k7t5PHvLsufpP6Zwk0nof62yLOsCf032wZx7/q0mv8gwlXjhcxI3lz6f0jBr0GrnWKcm3burXzI3t5IrcdUxw==", "dev": true }, "node_modules/emittery": { @@ -3370,9 +3369,9 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "peer": true, "dependencies": { "reusify": "^1.0.4" @@ -3643,9 +3642,9 @@ } }, "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "peer": true, "dependencies": { "type-fest": "^0.20.2" @@ -5161,9 +5160,9 @@ } }, "node_modules/openid-client": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.2.tgz", - "integrity": "sha512-TIVimoK/fAvpiISLcoGZyNJx2TOfd5AE6TXn58FFj6Y8qbU/jqky54Aws7sYKuCph1bLPWSRUa1r/Rd6K21bhg==", + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.4.tgz", + "integrity": "sha512-T1h3B10BRPKfcObdBklX639tVz+xh34O7GjofqrqiAQdm7eHsQ00ih18x6wuJ/E6FxdtS2u3FmUGPDeEcMwzNA==", "dependencies": { "jose": "^4.15.4", "lru-cache": "^6.0.0", @@ -5721,6 +5720,21 @@ "yaml": "^2.3.1" } }, + "node_modules/quicktype-core/node_modules/readable-stream": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/ramda": { "version": "0.29.1", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.1.tgz", @@ -5759,9 +5773,9 @@ "dev": true }, "node_modules/readable-stream": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", - "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -6095,9 +6109,9 @@ } }, "node_modules/sonic-boom": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz", - "integrity": "sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.0.tgz", + "integrity": "sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA==", "dependencies": { "atomic-sleep": "^1.0.0" } @@ -6519,6 +6533,7 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 52956b07a..43b4e8663 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,7 @@ "devDependencies": { "@jest/globals": "29.7.0", "jest": "29.7.0", - "ts-jest": "29.1.1", - "typescript": "5.3.3" + "ts-jest": "29.1.1" }, "jest": { "preset": "ts-jest", From 78a7fb40c796eca1be8485ca063747194a3443e7 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 11 Jan 2024 01:10:23 -0600 Subject: [PATCH 80/98] add `uds run dev` task --- tasks.yaml | 15 +++++++++++++++ tasks/setup.yaml | 6 +++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tasks.yaml b/tasks.yaml index 6e76798ff..63e098a73 100644 --- a/tasks.yaml +++ b/tasks.yaml @@ -5,6 +5,21 @@ includes: - test: ./tasks/test.yaml tasks: + - name: dev + actions: + - description: "Create the dev cluster" + task: setup:create-k3d-cluster + + - description: "Deploy the Istio source package with Zarf Dev" + cmd: "zarf dev deploy src/istio" + + - description: "Dev instructions" + cmd: | + echo "Next steps:" + echo " - To test & develop the Pepr module, run 'npx pepr dev' from a Javascript debug terminal" + echo " - Otherwise run 'npx pepr deploy' to deploy the Pepr module to the cluster" + echo " - Additional source packages can be deployed with 'zarf dev deploy src/'" + - name: setup-cluster actions: - task: setup:k3d-test-cluster diff --git a/tasks/setup.yaml b/tasks/setup.yaml index 075cea925..fac9c7d7c 100644 --- a/tasks/setup.yaml +++ b/tasks/setup.yaml @@ -1,11 +1,15 @@ tasks: - - name: k3d-test-cluster + - name: create-k3d-cluster actions: - description: "Create the K3d cluster" # renovate: datasource=github-tags depName=defenseunicorns/uds-k3d versioning=semver # renovate: datasource=github-tags depName=defenseunicorns/uds-k3d versioning=semver cmd: "zarf package deploy oci://defenseunicorns/uds-k3d:0.3.0 --confirm" + - name: k3d-test-cluster + actions: + - task: create-k3d-cluster + - description: "Initialize the cluster with Zarf" # renovate: datasource=github-tags depName=defenseunicorns/init versioning=semver cmd: "zarf package deploy oci://defenseunicorns/init:v0.32.1-${UDS_ARCH} --confirm" From edf68fa42b1febf3c5c2674c83bd5bca9e383aab Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 11 Jan 2024 19:03:54 -0600 Subject: [PATCH 81/98] allow login host for passtrhough gw --- src/istio/values/config-passthrough.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/istio/values/config-passthrough.yaml b/src/istio/values/config-passthrough.yaml index 30f3f878d..c2d273535 100644 --- a/src/istio/values/config-passthrough.yaml +++ b/src/istio/values/config-passthrough.yaml @@ -2,6 +2,7 @@ name: passthrough hosts: - "keycloak" + - "login" tls: enablePassthrough: true From b9dbd20358c4b91c2b5dbecf3903411bc1479fa4 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 11 Jan 2024 19:04:08 -0600 Subject: [PATCH 82/98] fix passthrough gw config --- src/pepr/operator/controllers/istio/virtual-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/operator/controllers/istio/virtual-service.ts b/src/pepr/operator/controllers/istio/virtual-service.ts index 57f67a844..dcdcce594 100644 --- a/src/pepr/operator/controllers/istio/virtual-service.ts +++ b/src/pepr/operator/controllers/istio/virtual-service.ts @@ -70,7 +70,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) { if (gateway === Gateway.Passthrough) { payload.spec!.tls = [ { - match: [{ port, sniHosts: [fqdn] }], + match: [{ port: 443, sniHosts: [fqdn] }], route: httpRoute, }, ]; From 792c78586ae7f8a1f96204d9f10830cc99fe0e84 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 11 Jan 2024 19:04:33 -0600 Subject: [PATCH 83/98] cleanup ns labels on pkg delete --- .../operator/controllers/istio/injection.ts | 64 +++++++++++++++++-- src/pepr/operator/index.ts | 5 ++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/pepr/operator/controllers/istio/injection.ts b/src/pepr/operator/controllers/istio/injection.ts index 8b38ab300..15a152f5e 100644 --- a/src/pepr/operator/controllers/istio/injection.ts +++ b/src/pepr/operator/controllers/istio/injection.ts @@ -2,6 +2,9 @@ import { K8s, kind } from "pepr"; import { UDSPackage } from "../../crd"; +const injectionLabel = "istio-injection"; +const injectionAnnotation = "uds.dev/original-istio-injection"; + /** * Syncs the package namespace istio-injection label and adds a label for the package name * @@ -12,14 +15,23 @@ export async function enableInjection(pkg: UDSPackage) { throw new Error(`Invalid Package definition, missing namespace or name`); } - const pkgLabel = `uds/${pkg.metadata.name}`; const sourceNS = await K8s(kind.Namespace).Get(pkg.metadata.namespace); const labels = sourceNS.metadata?.labels || {}; + const annotations = sourceNS.metadata?.annotations || {}; + const pkgKey = `uds.dev/${pkg.metadata.name}`; + + // Save the original value of the istio-injection label only if it's not already set + if (!annotations[injectionLabel]) { + annotations[injectionAnnotation] = labels[injectionLabel] || "non-existent"; + } - // Ensure Istio injection is enabled and the package label is present - if (labels["istio-injection"] !== "enabled" || !labels[pkgLabel]) { - labels["istio-injection"] = "enabled"; - labels[pkgLabel] = pkg.metadata.name; + // Ensure the namespace is configured + if (!annotations[pkgKey] || labels[injectionLabel] !== "enabled") { + // Ensure Istio injection is enabled + labels[injectionLabel] = "enabled"; + + // Add the package annotation + annotations[pkgKey] = "true"; // Apply the updated Namespace await K8s(kind.Namespace).Apply( @@ -27,12 +39,52 @@ export async function enableInjection(pkg: UDSPackage) { metadata: { name: pkg.metadata.namespace, labels, + annotations, }, }, { force: true }, ); - // @todo: Add a finalizer to remove the label when the package is deleted // @todo: Check for pods without sidecars and address them } } + +/** + * Restores the namespace + * + * @param pkg the package to cleanup + */ +export async function namespaceFinalizer(pkg: UDSPackage) { + if (!pkg.metadata?.namespace || !pkg.metadata.name) { + throw new Error(`Invalid Package definition, missing namespace or name`); + } + + const sourceNS = await K8s(kind.Namespace).Get(pkg.metadata.namespace); + const labels = sourceNS.metadata?.labels || {}; + const annotations = sourceNS.metadata?.annotations || {}; + + // Remove the package annotation + delete annotations[`uds.dev/${pkg.metadata.name}`]; + + // If there are no more UDS Package annotations, restore the original value of the istio-injection label + if (Object.keys(annotations).find(key => key.startsWith("uds.dev/"))) { + labels[injectionLabel] = annotations[injectionAnnotation]; + // If the original value was non-existent, remove the label + if (labels[injectionLabel] === "non-existent") { + delete labels[injectionLabel]; + } + delete annotations[injectionAnnotation]; + } + + // Apply the updated Namespace + await K8s(kind.Namespace).Apply( + { + metadata: { + name: pkg.metadata.namespace, + labels, + annotations, + }, + }, + { force: true }, + ); +} diff --git a/src/pepr/operator/index.ts b/src/pepr/operator/index.ts index 82c817211..b50f0a8f0 100644 --- a/src/pepr/operator/index.ts +++ b/src/pepr/operator/index.ts @@ -1,5 +1,6 @@ import { Capability } from "pepr"; +import { namespaceFinalizer } from "./controllers/istio/injection"; import { UDSPackage } from "./crd"; import "./crd/register"; import { validator } from "./crd/validator"; @@ -14,6 +15,10 @@ export const { Store, When } = operator; const queue = new Queue(); +// Watch for changes to the UDSPackage CRD to remove the finalizer +When(UDSPackage).IsDeleted().Watch(namespaceFinalizer); + +// Watch for changes to the UDSPackage CRD to enqueue a package for processing When(UDSPackage) .IsCreatedOrUpdated() // Advanced CR validation From 85ca6735929accae8a3f52937caf24226714f182 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Thu, 11 Jan 2024 19:08:40 -0600 Subject: [PATCH 84/98] readme update --- README.md | 2 +- bundles/k3d-standard/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6cb59ae62..f6449cf93 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ The core applications are: - [Istio](https://istio.io/) - Service Mesh - [KeyCloak](https://www.keycloak.org/) - Identity & Access Management - [Kiali](https://kiali.io/) - Service Mesh Observability -- [Kyverno](https://kyverno.io/) - Policy Engine - [Loki](https://grafana.com/oss/loki/) - Log Aggregation - [Metrics Server](https://github.com/kubernetes-sigs/metrics-server) - Metrics - [Neuvector](https://open-docs.neuvector.com/) - Container Security +- [Pepr](https://pepr.dev) - UDS policy engine & operator - [Prometheus Stack](https://github.com/prometheus-operator/kube-prometheus) - Monitoring - [Promtail](https://grafana.com/docs/loki/latest/send-data/promtail/) - Log Aggregation - [Tempo](https://grafana.com/docs/tempo/latest/getting-started/) - Tracing diff --git a/bundles/k3d-standard/README.md b/bundles/k3d-standard/README.md index e07024dff..f7180ac8e 100644 --- a/bundles/k3d-standard/README.md +++ b/bundles/k3d-standard/README.md @@ -12,10 +12,10 @@ The core applications are: - [Istio](https://istio.io/) - Service Mesh - [KeyCloak](https://www.keycloak.org/) - Identity & Access Management - [Kiali](https://kiali.io/) - Service Mesh Observability -- [Kyverno](https://kyverno.io/) - Policy Engine - [Loki](https://grafana.com/oss/loki/) - Log Aggregation - [Metrics Server](https://github.com/kubernetes-sigs/metrics-server) - Metrics - [Neuvector](https://open-docs.neuvector.com/) - Container Security +- [Pepr](https://pepr.dev) - UDS policy engine & operator - [Prometheus Stack](https://github.com/prometheus-operator/kube-prometheus) - Monitoring - [Promtail](https://grafana.com/docs/loki/latest/send-data/promtail/) - Log Aggregation - [Tempo](https://grafana.com/docs/tempo/latest/getting-started/) - Tracing From e19e50a5dae23ddf682e69de8246dad90a449678 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 12 Jan 2024 03:39:18 -0600 Subject: [PATCH 85/98] handle pod restart with istio injection --- .../operator/controllers/istio/injection.ts | 62 +++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/src/pepr/operator/controllers/istio/injection.ts b/src/pepr/operator/controllers/istio/injection.ts index 15a152f5e..c145ba3c7 100644 --- a/src/pepr/operator/controllers/istio/injection.ts +++ b/src/pepr/operator/controllers/istio/injection.ts @@ -1,4 +1,4 @@ -import { K8s, kind } from "pepr"; +import { K8s, Log, kind } from "pepr"; import { UDSPackage } from "../../crd"; @@ -18,7 +18,7 @@ export async function enableInjection(pkg: UDSPackage) { const sourceNS = await K8s(kind.Namespace).Get(pkg.metadata.namespace); const labels = sourceNS.metadata?.labels || {}; const annotations = sourceNS.metadata?.annotations || {}; - const pkgKey = `uds.dev/${pkg.metadata.name}`; + const pkgKey = `uds.dev/pkg-${pkg.metadata.name}`; // Save the original value of the istio-injection label only if it's not already set if (!annotations[injectionLabel]) { @@ -45,7 +45,7 @@ export async function enableInjection(pkg: UDSPackage) { { force: true }, ); - // @todo: Check for pods without sidecars and address them + await killPods(pkg.metadata.namespace, true); } } @@ -64,10 +64,10 @@ export async function namespaceFinalizer(pkg: UDSPackage) { const annotations = sourceNS.metadata?.annotations || {}; // Remove the package annotation - delete annotations[`uds.dev/${pkg.metadata.name}`]; + delete annotations[`uds.dev/pkg-${pkg.metadata.name}`]; // If there are no more UDS Package annotations, restore the original value of the istio-injection label - if (Object.keys(annotations).find(key => key.startsWith("uds.dev/"))) { + if (!Object.keys(annotations).find(key => key.startsWith("uds.dev/pkg-"))) { labels[injectionLabel] = annotations[injectionAnnotation]; // If the original value was non-existent, remove the label if (labels[injectionLabel] === "non-existent") { @@ -87,4 +87,56 @@ export async function namespaceFinalizer(pkg: UDSPackage) { }, { force: true }, ); + + await killPods(pkg.metadata.namespace, false); +} + +/** + * Forces deletion of pods with the incorrect istio sidecar state + * + * @param ns + * @param enableInjection + */ +async function killPods(ns: string, enableInjection: boolean) { + // Get all pods in the namespace + const pods = await K8s(kind.Pod).InNamespace(ns).Get(); + const groups: Record = {}; + + // Group the pods by owner UID + for (const pod of pods.items) { + // Ignore pods that already have a deletion timestamp + if (pod.metadata?.deletionTimestamp) { + continue; + } + + const foundSidecar = pod.spec?.containers?.find(c => c.name === "istio-proxy"); + + // If enabling injection, ignore pods that already have the istio sidecar + if (enableInjection && foundSidecar) { + continue; + } + + // If disabling injection, ignore pods that don't have the istio sidecar + if (!enableInjection && !foundSidecar) { + continue; + } + + // Get the UID of the owner of the pod or default to "other" (shouldn't happen) + const controlledBy = pod.metadata?.ownerReferences?.find(ref => ref.controller)?.uid || "other"; + groups[controlledBy] = groups[controlledBy] || []; + groups[controlledBy].push(pod); + } + + // Delete each group of pods + for (const group of Object.values(groups)) { + // If this is a daemonset, delete the pods in reverse name order + if (group[0].metadata?.ownerReferences?.find(ref => ref.kind === "DaemonSet")) { + group.sort((a, b) => (b.metadata?.name || "").localeCompare(a.metadata?.name || "")); + } + + for (const pod of group) { + Log.info(`Deleting pod ${ns}/${pod.metadata?.name} to enable the istio sidecar`); + await K8s(kind.Pod).Delete(pod); + } + } } From 4486c6ab931fe817e2fa536ba605fa8329999726 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 12 Jan 2024 04:03:49 -0600 Subject: [PATCH 86/98] prevent netpol name colissions --- .../operator/controllers/network/generate.ts | 7 ++++++- src/pepr/operator/crd/validator.ts | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index 3385263ac..49ae970e6 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -111,7 +111,12 @@ export function generate(namespace: string, policy: Allow): kind.NetworkPolicy { return generated; } -function generateName(policy: Allow) { +/** + * Generates a unique name for the NetworkPolicy based on the description, direction, and combination of remote properties + * + * @param policy the name of the policy + */ +export function generateName(policy: Allow) { const name = // Use the description if it exists policy.description || diff --git a/src/pepr/operator/crd/validator.ts b/src/pepr/operator/crd/validator.ts index 1f4d42aec..632aa5b93 100644 --- a/src/pepr/operator/crd/validator.ts +++ b/src/pepr/operator/crd/validator.ts @@ -1,6 +1,8 @@ import { PeprValidateRequest } from "pepr"; import { UDSPackage } from "."; +import { generateName } from "../controllers/network/generate"; +import { sanitizeResourceName } from "../controllers/utils"; const invalidNamespaces = ["kube-system", "kube-public", "_unknown_", "pepr-system"]; @@ -11,14 +13,28 @@ export async function validator(req: PeprValidateRequest) { return req.Deny("invalid namespace"); } - // Ensure the name of each network policy is unique const networkPolicy = req.Raw.spec?.network?.allow ?? []; + // Track the names of the network policies to ensure they are unique + const networkPolicyNames = new Set(); + for (const policy of networkPolicy) { // remoteGenerated cannot be combined with remoteNamespace or remotePodLabels if (policy.remoteGenerated && (policy.remoteNamespace || policy.remotePodLabels)) { return req.Deny("remoteGenerated cannot be combined with remoteNamespace or remotePodLabels"); } + + // Ensure the policy name is unique + const name = sanitizeResourceName(`allow-${req.Raw.metadata?.name}-${generateName(policy)}`); + if (networkPolicyNames.has(name)) { + return req.Deny( + `The combination of characteristics of this network allow rule would create a duplicate NetworkPolicy. ` + + `Verify you do not have duplicate allow rules, or add a unique "description" field for this rule. ` + + `The duplicate rule would be named "${name}".`, + ); + } + // Add the name to the set to track it + networkPolicyNames.add(name); } return req.Approve(); From 95e51151396c349e029b67be485fbfacd949f3ba Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 12 Jan 2024 04:04:23 -0600 Subject: [PATCH 87/98] run npx pepr format --- src/pepr/policies/security.spec.ts | 18 ++++++++++-------- src/pepr/policies/security.ts | 23 +++++++++-------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/pepr/policies/security.spec.ts b/src/pepr/policies/security.spec.ts index d96d24638..c047e6976 100644 --- a/src/pepr/policies/security.spec.ts +++ b/src/pepr/policies/security.spec.ts @@ -239,17 +239,19 @@ describe("security policies", () => { ]); }); - - it("should disallow seLinuxOptions", async() => { + it("should disallow seLinuxOptions", async () => { const expected = (e: Error) => expect(e).toMatchObject({ ok: false, data: { - message: expect.stringContaining("SELinux Options. Authorized: [user: undefined | role: undefined]"), + message: expect.stringContaining( + "SELinux Options. Authorized: [user: undefined | role: undefined]", + ), }, }); - return Promise.all([ K8s(kind.Pod) + return Promise.all([ + K8s(kind.Pod) .Apply({ metadata: { name: "security-selinux-pod", @@ -287,7 +289,7 @@ describe("security policies", () => { securityContext: { seLinuxOptions: { user: "bad", - role: "bad" + role: "bad", }, }, }, @@ -295,9 +297,9 @@ describe("security policies", () => { }, }) .then(failIfReached) - .catch(expected) - ]) - }) + .catch(expected), + ]); + }); it("should restrict seLinuxTypes", async () => { const expected = (e: Error) => diff --git a/src/pepr/policies/security.ts b/src/pepr/policies/security.ts index 7b1c02576..879421119 100644 --- a/src/pepr/policies/security.ts +++ b/src/pepr/policies/security.ts @@ -213,30 +213,25 @@ When(a.Pod) .IsCreatedOrUpdated() .Validate(request => { const seLinuxOptions = request.Raw.spec?.securityContext?.seLinuxOptions; - const authorized = ['user: undefined', 'role: undefined'] + const authorized = ["user: undefined", "role: undefined"]; // Check Pod level security context - if(seLinuxOptions?.user || seLinuxOptions?.role) { - return request.Deny( - securityContextMessage(`Unauthorized pod SELinux Options`, authorized, [ - { ctx: request.Raw.spec?.securityContext as V1SecurityContext }, - ]), - ); + if (seLinuxOptions?.user || seLinuxOptions?.role) { + return request.Deny( + securityContextMessage(`Unauthorized pod SELinux Options`, authorized, [ + { ctx: request.Raw.spec?.securityContext as V1SecurityContext }, + ]), + ); } // Check Container level security context const violations = securityContextContainers(request).filter( - c => c.ctx.seLinuxOptions?.user || c.ctx.seLinuxOptions?.role + c => c.ctx.seLinuxOptions?.user || c.ctx.seLinuxOptions?.role, ); - if (violations.length) { return request.Deny( - securityContextMessage( - "Unauthorized container SELinux Options", - authorized, - violations, - ), + securityContextMessage("Unauthorized container SELinux Options", authorized, violations), ); } From 88951c0c2eddd4474b272a05c729f4e5a0d967ac Mon Sep 17 00:00:00 2001 From: Micah Nagel Date: Fri, 12 Jan 2024 10:38:32 -0700 Subject: [PATCH 88/98] Update src/pepr/operator/controllers/network/policies.ts --- src/pepr/operator/controllers/network/policies.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pepr/operator/controllers/network/policies.ts b/src/pepr/operator/controllers/network/policies.ts index f15458777..1c6461efb 100644 --- a/src/pepr/operator/controllers/network/policies.ts +++ b/src/pepr/operator/controllers/network/policies.ts @@ -48,6 +48,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { }, // Use the same port as the VirtualService if targetPort is not set port: targetPort ?? port, + description: `${Object.values(podLabels)} Istio ${gateway} gateway`, }; // Generate the policy From 16765b4f702ff3e092f71983a857969117799e45 Mon Sep 17 00:00:00 2001 From: Micah Nagel Date: Fri, 12 Jan 2024 11:57:49 -0700 Subject: [PATCH 89/98] chore: add descriptions to nps --- src/grafana/chart/templates/uds-package.yaml | 4 ++-- src/loki/chart/templates/uds-package.yaml | 15 ++++----------- src/neuvector/chart/templates/uds-package.yaml | 8 ++++++++ src/promtail/chart/templates/uds-package.yaml | 5 +++-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/grafana/chart/templates/uds-package.yaml b/src/grafana/chart/templates/uds-package.yaml index e398d5f3f..504c79b7d 100644 --- a/src/grafana/chart/templates/uds-package.yaml +++ b/src/grafana/chart/templates/uds-package.yaml @@ -22,6 +22,7 @@ spec: remotePodLabels: app.kubernetes.io/name: tempo port: 9090 + description: "Tempo Datasource" - direction: Egress podLabels: @@ -29,9 +30,8 @@ spec: remoteGenerated: Anywhere - direction: Egress - podLabels: - app.kubernetes.io/name: grafana remoteNamespace: tempo remotePodLabels: app.kubernetes.io/name: tempo port: 9411 + description: "Tempo" diff --git a/src/loki/chart/templates/uds-package.yaml b/src/loki/chart/templates/uds-package.yaml index be9e06b52..206fed2b4 100644 --- a/src/loki/chart/templates/uds-package.yaml +++ b/src/loki/chart/templates/uds-package.yaml @@ -6,14 +6,6 @@ metadata: spec: network: allow: - - direction: Ingress - podLabels: - app.kubernetes.io/name: loki - remoteNamespace: tempo - remotePodLabels: - app.kubernetes.io/name: tempo - port: 8080 - - direction: Ingress podLabels: app.kubernetes.io/name: loki @@ -21,8 +13,8 @@ spec: remotePodLabels: app.kubernetes.io/name: grafana ports: - - 3100 - 8080 + description: "Grafana Log Queries" - direction: Ingress podLabels: @@ -33,6 +25,7 @@ spec: ports: - 3100 - 8080 + description: "Prometheus Metrics" - direction: Ingress podLabels: @@ -42,6 +35,7 @@ spec: app.kubernetes.io/name: promtail ports: - 8080 + description: "Promtail Log Storage" # Todo: wide open for now for pushing to s3 - direction: Egress @@ -50,9 +44,8 @@ spec: remoteGenerated: Anywhere - direction: Egress - podLabels: - app.kubernetes.io/name: loki remoteNamespace: tempo remotePodLabels: app.kubernetes.io/name: tempo port: 9411 + description: "Tempo" diff --git a/src/neuvector/chart/templates/uds-package.yaml b/src/neuvector/chart/templates/uds-package.yaml index e122aa1d0..510222177 100644 --- a/src/neuvector/chart/templates/uds-package.yaml +++ b/src/neuvector/chart/templates/uds-package.yaml @@ -38,3 +38,11 @@ spec: podLabels: app: neuvector-prometheus-exporter-pod port: 8068 + description: "Prometheus Metrics" + + - direction: Egress + remoteNamespace: tempo + remotePodLabels: + app.kubernetes.io/name: tempo + port: 9411 + description: "Tempo" diff --git a/src/promtail/chart/templates/uds-package.yaml b/src/promtail/chart/templates/uds-package.yaml index c7838174f..a9932829a 100644 --- a/src/promtail/chart/templates/uds-package.yaml +++ b/src/promtail/chart/templates/uds-package.yaml @@ -13,6 +13,7 @@ spec: remotePodLabels: app.kubernetes.io/name: prometheus port: 3101 + description: "Prometheus Metrics" - direction: Egress podSelector: @@ -20,12 +21,11 @@ spec: remoteGenerated: KubeAPI - direction: Egress - podLabels: - app.kubernetes.io/name: promtail remoteNamespace: tempo remotePodLabels: app.kubernetes.io/name: tempo port: 9411 + description: "Tempo" - direction: Egress podLabels: @@ -34,3 +34,4 @@ spec: remotePodLabels: app.kubernetes.io/name: loki port: 8080 + description: "Write Logs to Loki" From 1bcd80a62f7a85e11a59dc195bf0b89ab794c109 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 12 Jan 2024 14:46:04 -0600 Subject: [PATCH 90/98] rename ns cleanup function --- src/pepr/operator/controllers/istio/injection.ts | 2 +- src/pepr/operator/index.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pepr/operator/controllers/istio/injection.ts b/src/pepr/operator/controllers/istio/injection.ts index c145ba3c7..e3a465619 100644 --- a/src/pepr/operator/controllers/istio/injection.ts +++ b/src/pepr/operator/controllers/istio/injection.ts @@ -54,7 +54,7 @@ export async function enableInjection(pkg: UDSPackage) { * * @param pkg the package to cleanup */ -export async function namespaceFinalizer(pkg: UDSPackage) { +export async function cleanupNamespace(pkg: UDSPackage) { if (!pkg.metadata?.namespace || !pkg.metadata.name) { throw new Error(`Invalid Package definition, missing namespace or name`); } diff --git a/src/pepr/operator/index.ts b/src/pepr/operator/index.ts index b50f0a8f0..f4c2cd800 100644 --- a/src/pepr/operator/index.ts +++ b/src/pepr/operator/index.ts @@ -1,6 +1,6 @@ import { Capability } from "pepr"; -import { namespaceFinalizer } from "./controllers/istio/injection"; +import { cleanupNamespace } from "./controllers/istio/injection"; import { UDSPackage } from "./crd"; import "./crd/register"; import { validator } from "./crd/validator"; @@ -16,7 +16,7 @@ export const { Store, When } = operator; const queue = new Queue(); // Watch for changes to the UDSPackage CRD to remove the finalizer -When(UDSPackage).IsDeleted().Watch(namespaceFinalizer); +When(UDSPackage).IsDeleted().Watch(cleanupNamespace); // Watch for changes to the UDSPackage CRD to enqueue a package for processing When(UDSPackage) From 2f422c0d7a0eadb91bba5b875e408dc8ed683960 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 12 Jan 2024 19:25:07 -0600 Subject: [PATCH 91/98] pepr 0.22.0 --- package-lock.json | 20 ++++++++++---------- package.json | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index f6ed93de6..86a50ec70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "uds-core", "version": "0.2.0", "dependencies": { - "pepr": "0.21.1" + "pepr": "0.22.0" }, "devDependencies": { "@jest/globals": "29.7.0", @@ -1577,9 +1577,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz", + "integrity": "sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -2909,9 +2909,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.628", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.628.tgz", - "integrity": "sha512-2k7t5PHvLsufpP6Zwk0nof62yLOsCf032wZx7/q0mv8gwlXjhcxI3lz6f0jBr0GrnWKcm3burXzI3t5IrcdUxw==", + "version": "1.4.630", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.630.tgz", + "integrity": "sha512-osHqhtjojpCsACVnuD11xO5g9xaCyw7Qqn/C2KParkMv42i8jrJJgx3g7mkHfpxwhy9MnOJr8+pKOdZ7qzgizg==", "dev": true }, "node_modules/emittery": { @@ -5332,9 +5332,9 @@ } }, "node_modules/pepr": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.21.1.tgz", - "integrity": "sha512-H5VDQAOiOv7GjnrLKHU8FTx7V6W2ke2VuGGtWewbSBjvts8tgm/Qq5yzf3Sm8J4yR5J8h/qg7GXNRPwiUqHP1g==", + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/pepr/-/pepr-0.22.0.tgz", + "integrity": "sha512-v9ijKkHm/3KcN9lCuueR3W6cH2eFVNPy/wBIRfxjGzNwzJROCCPtYFZX75w2KzJT7B1RvQxTzfDIbg/LGokdtA==", "dependencies": { "@types/ramda": "0.29.9", "express": "4.18.2", diff --git a/package.json b/package.json index 306a0a273..2a11435fa 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "k3d-setup": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'" }, "dependencies": { - "pepr": "0.21.1" + "pepr": "0.22.0" }, "devDependencies": { "@jest/globals": "29.7.0", From 05e96558760eb9c6599a1f2f41064b041ab556a1 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 12 Jan 2024 19:25:33 -0600 Subject: [PATCH 92/98] make netpols run before istio things --- src/pepr/operator/index.ts | 2 +- src/pepr/operator/reconciler.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pepr/operator/index.ts b/src/pepr/operator/index.ts index f4c2cd800..3cf2e3e3e 100644 --- a/src/pepr/operator/index.ts +++ b/src/pepr/operator/index.ts @@ -15,7 +15,7 @@ export const { Store, When } = operator; const queue = new Queue(); -// Watch for changes to the UDSPackage CRD to remove the finalizer +// Watch for changes to the UDSPackage CRD and cleanup the namespace mutations When(UDSPackage).IsDeleted().Watch(cleanupNamespace); // Watch for changes to the UDSPackage CRD to enqueue a package for processing diff --git a/src/pepr/operator/reconciler.ts b/src/pepr/operator/reconciler.ts index 41d273c93..545179627 100644 --- a/src/pepr/operator/reconciler.ts +++ b/src/pepr/operator/reconciler.ts @@ -35,6 +35,8 @@ export async function reconciler(pkg: UDSPackage) { try { void updateStatus(pkg, { phase: Phase.Pending }); + const netPol = await networkPolicies(pkg, namespace); + // Only configure the VirtualService if Istio is installed let vs: VirtualService[] = []; if (UDSConfig.istioInstalled) { @@ -47,8 +49,6 @@ export async function reconciler(pkg: UDSPackage) { Log.warn(`Istio is not installed, skipping ${name} VirtualService.`); } - const netPol = await networkPolicies(pkg, namespace); - await updateStatus(pkg, { phase: Phase.Ready, endpoints: vs.map(v => v.spec!.hosts!.join(",")), From 3f0829b1d2570231fd2ee525db51fb9c9498ab9f Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 12 Jan 2024 19:25:58 -0600 Subject: [PATCH 93/98] bind to kube-dns for dns egress --- .../controllers/network/defaults/allow-egress-dns.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts b/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts index cb15c239a..83f3d1e68 100644 --- a/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts +++ b/src/pepr/operator/controllers/network/defaults/allow-egress-dns.ts @@ -4,8 +4,11 @@ import { generate } from "../generate"; export const allowEgressDNS = (namespace: string) => { const netPol = generate(namespace, { direction: Direction.Egress, - description: "DNS lookup to any DNS server", - remoteNamespace: "*", + description: "DNS lookup via CoreDNS", + remoteNamespace: "kube-system", + remotePodLabels: { + "k8s-app": "kube-dns", + }, port: 53, }); From c0b452033bacc08289a0a29785a817e9b661b3e1 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 12 Jan 2024 20:31:17 -0600 Subject: [PATCH 94/98] properly handle apiserver endpointslice updates --- .../operator/controllers/network/generate.ts | 4 +- .../controllers/network/generators/kubeAPI.ts | 82 ++++++++++++------- src/pepr/operator/index.ts | 17 +++- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/pepr/operator/controllers/network/generate.ts b/src/pepr/operator/controllers/network/generate.ts index 49ae970e6..582336e60 100644 --- a/src/pepr/operator/controllers/network/generate.ts +++ b/src/pepr/operator/controllers/network/generate.ts @@ -5,7 +5,7 @@ import { Allow, RemoteGenerated } from "../../crd"; import { anywhere } from "./generators/anywhere"; import { cloudMetadata } from "./generators/cloudMetadata"; import { intraNamespace } from "./generators/intraNamespace"; -import { generateKubeAPI } from "./generators/kubeAPI"; +import { kubeAPI } from "./generators/kubeAPI"; export function generate(namespace: string, policy: Allow): kind.NetworkPolicy { // Create a unique name for the NetworkPolicy based on the package name, index, direction, pod labels, and port @@ -70,7 +70,7 @@ export function generate(namespace: string, policy: Allow): kind.NetworkPolicy { // Check if remoteGenerated is set switch (policy.remoteGenerated) { case RemoteGenerated.KubeAPI: - peers = generateKubeAPI(); + peers = kubeAPI(); break; case RemoteGenerated.CloudMetadata: diff --git a/src/pepr/operator/controllers/network/generators/kubeAPI.ts b/src/pepr/operator/controllers/network/generators/kubeAPI.ts index 8e80414bb..646c12d41 100644 --- a/src/pepr/operator/controllers/network/generators/kubeAPI.ts +++ b/src/pepr/operator/controllers/network/generators/kubeAPI.ts @@ -1,46 +1,72 @@ import { V1NetworkPolicyPeer } from "@kubernetes/client-node"; -import { K8s, Log, kind } from "pepr"; +import { K8s, Log, R, kind } from "pepr"; +import { RemoteGenerated } from "../../../crd"; import { anywhere } from "./anywhere"; +// This is an in-memory cache of the API server CIDR let apiServerPeers: V1NetworkPolicyPeer[]; -void getAPIServerCIDR(); +/** + * Initialize the API server CIDR by getting the EndpointSlice for the API server + */ +export async function initAPIServerCIDR() { + const slice = await K8s(kind.EndpointSlice).InNamespace("default").Get("kubernetes"); + await updateAPIServerCIDR(slice); +} /** - * This generates a NetworkPolicyPeer that matches the API server endpoints. - * - * @returns A NetworkPolicyPeer that matches the API server endpoints + * Get the API server CIDR + * @returns The API server CIDR */ -export function generateKubeAPI(): V1NetworkPolicyPeer[] { - return apiServerPeers; +export function kubeAPI() { + // If the API server peers are already cached, return them + if (apiServerPeers) { + return apiServerPeers; + } + + // Otherwise, log a warning and default to 0.0.0.0/0 until the EndpointSlice is updated + Log.warn("Unable to get API server CIDR, defaulting to 0.0.0.0/0"); + return [anywhere]; } -async function getAPIServerCIDR(): Promise { - try { - // @todo: evaluate if this ever changes with node autoscaling +/** + * Update the API server CIDR and update the NetworkPolicies + * + * @param slice The EndpointSlice for the API server + */ +export async function updateAPIServerCIDR(slice: kind.EndpointSlice) { + const { endpoints } = slice; + + // Flatten the endpoints into a list of IPs + const peers = endpoints?.flatMap(e => e.addresses); - // Read the API server endpoints from the cluster - const { endpoints } = await K8s(kind.EndpointSlice).InNamespace("default").Get("kubernetes"); + // If the peers are found, cache and process them + if (peers?.length) { + apiServerPeers = peers.flatMap(ip => ({ + ipBlock: { + cidr: `${ip}/32`, + }, + })); - // Flatten the endpoints into a list of IPs - const peers = endpoints?.flatMap(e => e.addresses); + // Get all the KubeAPI NetworkPolicies + const netPols = await K8s(kind.NetworkPolicy) + .WithLabel("uds.dev/generated", RemoteGenerated.KubeAPI) + .Get(); - // If the peers are found, cache and return them - if (peers?.length) { - apiServerPeers = peers.flatMap(ip => ({ - ipBlock: { - cidr: `${ip}/32`, - }, - })); + for (const netPol of netPols.items) { + // Get the old peers + const oldPeers = netPol.spec?.egress?.[0].to; - return apiServerPeers; + // Update the NetworkPolicy if the peers have changed + if (!R.equals(oldPeers, apiServerPeers)) { + // Note using the apiServerPeers variable here instead of the oldPeers variable + // in case another EndpointSlice is updated before this one + netPol.spec!.egress![0].to = apiServerPeers; + + Log.debug(`Updating ${netPol.metadata!.namespace}/${netPol.metadata!.name}`); + await K8s(kind.NetworkPolicy).Apply(netPol); + } } - } catch (err) { - Log.debug(err); } - - // Log a warning and default to 0.0.0.0/0 if the IP is not found - Log.warn("Unable to get API server CIDR, defaulting to 0.0.0.0/0"); - return [anywhere]; } diff --git a/src/pepr/operator/index.ts b/src/pepr/operator/index.ts index 3cf2e3e3e..a9a75cc92 100644 --- a/src/pepr/operator/index.ts +++ b/src/pepr/operator/index.ts @@ -1,6 +1,7 @@ -import { Capability } from "pepr"; +import { Capability, a } from "pepr"; -import { cleanupNamespace } from "./controllers/istio/injection"; +import { cleanupNamespace } from "./controllers/istio/injection"; +import { initAPIServerCIDR, updateAPIServerCIDR } from "./controllers/network/generators/kubeAPI"; import { UDSPackage } from "./crd"; import "./crd/register"; import { validator } from "./crd/validator"; @@ -13,8 +14,20 @@ export const operator = new Capability({ export const { Store, When } = operator; +// Create a queue to process the packages in serial order const queue = new Queue(); +// Pre-populate the API server CIDR since we are not persisting the EndpointSlice +// Note ignore any errors since the watch will still be running hereafter +void initAPIServerCIDR(); + +// Watch for changes to the API server EndpointSlice and update the API server CIDR +When(a.EndpointSlice) + .IsCreatedOrUpdated() + .InNamespace("default") + .WithName("kubernetes") + .Watch(updateAPIServerCIDR); + // Watch for changes to the UDSPackage CRD and cleanup the namespace mutations When(UDSPackage).IsDeleted().Watch(cleanupNamespace); From 0f71619809e2a9b92a4ef7ed2343e82db7214dd0 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 12 Jan 2024 20:33:22 -0600 Subject: [PATCH 95/98] allow try/catch on `pending` statud bump --- src/pepr/operator/reconciler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pepr/operator/reconciler.ts b/src/pepr/operator/reconciler.ts index 545179627..adf6b2fa3 100644 --- a/src/pepr/operator/reconciler.ts +++ b/src/pepr/operator/reconciler.ts @@ -33,7 +33,7 @@ export async function reconciler(pkg: UDSPackage) { // Configure the namespace and namespace-wide network policies try { - void updateStatus(pkg, { phase: Phase.Pending }); + await updateStatus(pkg, { phase: Phase.Pending }); const netPol = await networkPolicies(pkg, namespace); From 91551e8442cc54bfb10d3339a871fbafa927543e Mon Sep 17 00:00:00 2001 From: Micah Nagel Date: Tue, 16 Jan 2024 10:11:54 -0700 Subject: [PATCH 96/98] fix: intra namespace for loki gateway comms --- src/loki/chart/templates/uds-package.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/loki/chart/templates/uds-package.yaml b/src/loki/chart/templates/uds-package.yaml index 206fed2b4..ee96b55cd 100644 --- a/src/loki/chart/templates/uds-package.yaml +++ b/src/loki/chart/templates/uds-package.yaml @@ -6,6 +6,13 @@ metadata: spec: network: allow: + # Permit intra-namespace communication for gateway -> loki read/write + - direction: Ingress + remoteGenerated: IntraNamespace + + - direction: Egress + remoteGenerated: IntraNamespace + - direction: Ingress podLabels: app.kubernetes.io/name: loki From bf68e87962a5ea2289547ee59bf804152e323020 Mon Sep 17 00:00:00 2001 From: Micah Nagel Date: Tue, 16 Jan 2024 10:54:54 -0700 Subject: [PATCH 97/98] add uds package for prometheus stack --- src/prometheus-stack/chart/.helmignore | 23 +++++++ src/prometheus-stack/chart/Chart.yaml | 18 ++++++ .../chart/templates/_helpers.tpl | 62 +++++++++++++++++++ .../chart/templates/uds-package.yaml | 48 ++++++++++++++ src/prometheus-stack/chart/values.yaml | 0 src/prometheus-stack/zarf.yaml | 4 ++ 6 files changed, 155 insertions(+) create mode 100644 src/prometheus-stack/chart/.helmignore create mode 100644 src/prometheus-stack/chart/Chart.yaml create mode 100644 src/prometheus-stack/chart/templates/_helpers.tpl create mode 100644 src/prometheus-stack/chart/templates/uds-package.yaml create mode 100644 src/prometheus-stack/chart/values.yaml diff --git a/src/prometheus-stack/chart/.helmignore b/src/prometheus-stack/chart/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/src/prometheus-stack/chart/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/src/prometheus-stack/chart/Chart.yaml b/src/prometheus-stack/chart/Chart.yaml new file mode 100644 index 000000000..032e81126 --- /dev/null +++ b/src/prometheus-stack/chart/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +name: uds-prometheus-config +description: Prometheus stack configuration for UDS + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 diff --git a/src/prometheus-stack/chart/templates/_helpers.tpl b/src/prometheus-stack/chart/templates/_helpers.tpl new file mode 100644 index 000000000..52f6fe3d0 --- /dev/null +++ b/src/prometheus-stack/chart/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "uds-prometheus-config.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "uds-prometheus-config.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "uds-prometheus-config.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "uds-prometheus-config.labels" -}} +helm.sh/chart: {{ include "uds-prometheus-config.chart" . }} +{{ include "uds-prometheus-config.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "uds-prometheus-config.selectorLabels" -}} +app.kubernetes.io/name: {{ include "uds-prometheus-config.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "uds-prometheus-config.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "uds-prometheus-config.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/src/prometheus-stack/chart/templates/uds-package.yaml b/src/prometheus-stack/chart/templates/uds-package.yaml new file mode 100644 index 000000000..12fdac2cd --- /dev/null +++ b/src/prometheus-stack/chart/templates/uds-package.yaml @@ -0,0 +1,48 @@ +apiVersion: uds.dev/v1alpha1 +kind: Package +metadata: + name: prometheus-stack + namespace: {{ .Release.Namespace }} +spec: + network: + allow: + # Permit intra-namespace communication + - direction: Ingress + remoteGenerated: IntraNamespace + + - direction: Egress + remoteGenerated: IntraNamespace + + - direction: Egress + remoteGenerated: KubeAPI + podLabels: + app: kube-prometheus-stack-operator + + - direction: Egress + remoteGenerated: KubeAPI + podLabels: + app.kubernetes.io/name: kube-state-metrics + + - direction: Egress + remoteGenerated: KubeAPI + podLabels: + app: kube-prometheus-stack-admission-create + + - direction: Egress + remoteGenerated: KubeAPI + podLabels: + app: kube-prometheus-stack-admission-patch + + # todo: lockdown egress to scrape targets + - direction: Egress + remoteNamespace: "" + podLabels: + app.kubernetes.io/name: prometheus + description: "Metrics Scraping" + + - direction: Egress + remoteNamespace: tempo + remotePodLabels: + app.kubernetes.io/name: tempo + port: 9411 + description: "Tempo" diff --git a/src/prometheus-stack/chart/values.yaml b/src/prometheus-stack/chart/values.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/src/prometheus-stack/zarf.yaml b/src/prometheus-stack/zarf.yaml index e3f49acdd..8f06dbb85 100644 --- a/src/prometheus-stack/zarf.yaml +++ b/src/prometheus-stack/zarf.yaml @@ -19,6 +19,10 @@ components: required: true description: "Install kube-prometheus-stack using the helm chart https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack" charts: + - name: uds-prometheus-config + namespace: monitoring + version: 0.1.0 + localPath: chart - name: kube-prometheus-stack url: https://prometheus-community.github.io/helm-charts version: 54.0.1 From f13cf9958634dba2336bef6f6e9e8cfb48e2a926 Mon Sep 17 00:00:00 2001 From: Micah Nagel Date: Tue, 16 Jan 2024 10:58:23 -0700 Subject: [PATCH 98/98] fix: missing grafana np for prom --- src/prometheus-stack/chart/templates/uds-package.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/prometheus-stack/chart/templates/uds-package.yaml b/src/prometheus-stack/chart/templates/uds-package.yaml index 12fdac2cd..99ddc3338 100644 --- a/src/prometheus-stack/chart/templates/uds-package.yaml +++ b/src/prometheus-stack/chart/templates/uds-package.yaml @@ -40,6 +40,15 @@ spec: app.kubernetes.io/name: prometheus description: "Metrics Scraping" + - direction: Ingress + remoteNamespace: grafana + remotePodLabels: + app.kubernetes.io/name: grafana + podLabels: + app.kubernetes.io/name: prometheus + port: 9090 + description: "Grafana Metrics Queries" + - direction: Egress remoteNamespace: tempo remotePodLabels: