@kyverno/backstage-plugin-policy-reporter-backend 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
10
10
  var express__default = /*#__PURE__*/_interopDefaultCompat(express);
11
11
  var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
12
12
 
13
+ const ensureTrailingSlash = (url) => url.endsWith("/") ? url : `${url}/`;
13
14
  async function createRouter(options) {
14
15
  const { logger, config, catalogService, authService } = options;
15
16
  const router = Router__default.default();
@@ -37,7 +38,9 @@ async function createRouter(options) {
37
38
  if (!kyvernoEndpoint)
38
39
  return response.status(400).json({ error: `Entity missing 'kyverno.io/endpoint' annotation` });
39
40
  const policyResponse = await fetch(
40
- `${kyvernoEndpoint}v1/namespaced-resources/results?${urlParams.toString()}`
41
+ `${ensureTrailingSlash(
42
+ kyvernoEndpoint
43
+ )}v1/namespaced-resources/results?${urlParams.toString()}`
41
44
  );
42
45
  if (!policyResponse.ok) {
43
46
  return response.status(500).json({
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["import { AuthService, RootConfigService } from '@backstage/backend-plugin-api';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport {\n KYVERNO_ENDPOINT_ANNOTATION,\n Severity,\n Status,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\n\nexport interface RouterOptions {\n logger: LoggerService;\n config: RootConfigService;\n catalogService: CatalogService;\n authService: AuthService;\n}\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { logger, config, catalogService, authService } = options;\n\n const router = Router();\n router.use(express.json());\n\n router.get(\n '/namespaced-resources/:environment/results',\n async (request, response) => {\n // Decided to inline for now\n // Could be refactored to use a generated typed express router from OpenAPI spec\n type QueryParams = {\n sources?: string[] | string; // Filter by a list of sources\n namespaces?: string[] | string; // Filter by a list of namespaces\n kinds?: string[] | string; // Filter by a list of kinds\n resources?: string[] | string; // Filter by a list of resources\n categories?: string[] | string; // Filter by a list of categories\n policies?: string[] | string; // Filter by a list of policies\n status?: Status[] | Status; // Filter by a list of status (fail, pass, warn, error, skip)\n severities?: Severity[] | Severity; // Filter by a list of severities (low, medium, high)\n search?: string; // Filter by search string\n labels?: string[] | string; // Filter by polr label-value pairs\n page?: string; // Requested List Page\n offset?: string; // Results per Page\n direction?: 'asc' | 'desc'; // Order of the results\n };\n\n const query: QueryParams = request.query;\n\n // Append query parameters from the request to the external API call\n const urlParams = new URLSearchParams();\n\n // Iterate over the query parameters\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n // If the value is an array, append each item as a string\n value.forEach(val => urlParams.append(key, val));\n } else if (value) {\n urlParams.append(key, value);\n }\n }\n\n // Get entityRef from params.\n const entityRef = decodeURIComponent(request.params.environment);\n\n const credentials = await authService.getOwnServiceCredentials();\n\n const entity = await catalogService.getEntityByRef(entityRef, {\n credentials,\n });\n\n if (!entity)\n return response.status(400).json({ error: 'Invalid entityRef' });\n\n const kyvernoEndpoint =\n entity?.metadata.annotations?.[KYVERNO_ENDPOINT_ANNOTATION];\n\n if (!kyvernoEndpoint)\n return response\n .status(400)\n .json({ error: `Entity missing 'kyverno.io/endpoint' annotation` });\n\n const policyResponse = await fetch(\n `${kyvernoEndpoint}v1/namespaced-resources/results?${urlParams.toString()}`,\n );\n\n if (!policyResponse.ok) {\n return response.status(500).json({\n error: `Failed to fetch policies: ${policyResponse.statusText}`,\n });\n }\n\n const result = await policyResponse.json();\n\n return response.status(200).json(result);\n },\n );\n\n const middleware = MiddlewareFactory.create({ logger, config });\n\n router.use(middleware.error());\n return router;\n}\n"],"names":["Router","express","KYVERNO_ENDPOINT_ANNOTATION","MiddlewareFactory"],"mappings":";;;;;;;;;;;;AAmBA,eAAsB,aACpB,OACyB,EAAA;AACzB,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAQ,EAAA,cAAA,EAAgB,aAAgB,GAAA,OAAA;AAExD,EAAA,MAAM,SAASA,uBAAO,EAAA;AACtB,EAAO,MAAA,CAAA,GAAA,CAAIC,wBAAQ,CAAA,IAAA,EAAM,CAAA;AAEzB,EAAO,MAAA,CAAA,GAAA;AAAA,IACL,4CAAA;AAAA,IACA,OAAO,SAAS,QAAa,KAAA;AAmB3B,MAAA,MAAM,QAAqB,OAAQ,CAAA,KAAA;AAGnC,MAAM,MAAA,SAAA,GAAY,IAAI,eAAgB,EAAA;AAGtC,MAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,KAAK,CAAG,EAAA;AAChD,QAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AAExB,UAAA,KAAA,CAAM,QAAQ,CAAO,GAAA,KAAA,SAAA,CAAU,MAAO,CAAA,GAAA,EAAK,GAAG,CAAC,CAAA;AAAA,mBACtC,KAAO,EAAA;AAChB,UAAU,SAAA,CAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA;AAC7B;AAIF,MAAA,MAAM,SAAY,GAAA,kBAAA,CAAmB,OAAQ,CAAA,MAAA,CAAO,WAAW,CAAA;AAE/D,MAAM,MAAA,WAAA,GAAc,MAAM,WAAA,CAAY,wBAAyB,EAAA;AAE/D,MAAA,MAAM,MAAS,GAAA,MAAM,cAAe,CAAA,cAAA,CAAe,SAAW,EAAA;AAAA,QAC5D;AAAA,OACD,CAAA;AAED,MAAA,IAAI,CAAC,MAAA;AACH,QAAO,OAAA,QAAA,CAAS,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,qBAAqB,CAAA;AAEjE,MAAA,MAAM,eACJ,GAAA,MAAA,EAAQ,QAAS,CAAA,WAAA,GAAcC,+DAA2B,CAAA;AAE5D,MAAA,IAAI,CAAC,eAAA;AACH,QAAO,OAAA,QAAA,CACJ,OAAO,GAAG,CAAA,CACV,KAAK,EAAE,KAAA,EAAO,mDAAmD,CAAA;AAEtE,MAAA,MAAM,iBAAiB,MAAM,KAAA;AAAA,QAC3B,CAAG,EAAA,eAAe,CAAmC,gCAAA,EAAA,SAAA,CAAU,UAAU,CAAA;AAAA,OAC3E;AAEA,MAAI,IAAA,CAAC,eAAe,EAAI,EAAA;AACtB,QAAA,OAAO,QAAS,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,UAC/B,KAAA,EAAO,CAA6B,0BAAA,EAAA,cAAA,CAAe,UAAU,CAAA;AAAA,SAC9D,CAAA;AAAA;AAGH,MAAM,MAAA,MAAA,GAAS,MAAM,cAAA,CAAe,IAAK,EAAA;AAEzC,MAAA,OAAO,QAAS,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,MAAM,CAAA;AAAA;AACzC,GACF;AAEA,EAAA,MAAM,aAAaC,gCAAkB,CAAA,MAAA,CAAO,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAE9D,EAAO,MAAA,CAAA,GAAA,CAAI,UAAW,CAAA,KAAA,EAAO,CAAA;AAC7B,EAAO,OAAA,MAAA;AACT;;;;"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["import { AuthService, RootConfigService } from '@backstage/backend-plugin-api';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport {\n KYVERNO_ENDPOINT_ANNOTATION,\n Severity,\n Status,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\n\nexport interface RouterOptions {\n logger: LoggerService;\n config: RootConfigService;\n catalogService: CatalogService;\n authService: AuthService;\n}\n\nconst ensureTrailingSlash = (url: string) =>\n url.endsWith('/') ? url : `${url}/`;\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { logger, config, catalogService, authService } = options;\n\n const router = Router();\n router.use(express.json());\n\n router.get(\n '/namespaced-resources/:environment/results',\n async (request, response) => {\n // Decided to inline for now\n // Could be refactored to use a generated typed express router from OpenAPI spec\n type QueryParams = {\n sources?: string[] | string; // Filter by a list of sources\n namespaces?: string[] | string; // Filter by a list of namespaces\n kinds?: string[] | string; // Filter by a list of kinds\n resources?: string[] | string; // Filter by a list of resources\n categories?: string[] | string; // Filter by a list of categories\n policies?: string[] | string; // Filter by a list of policies\n status?: Status[] | Status; // Filter by a list of status (fail, pass, warn, error, skip)\n severities?: Severity[] | Severity; // Filter by a list of severities (low, medium, high)\n search?: string; // Filter by search string\n labels?: string[] | string; // Filter by polr label-value pairs\n page?: string; // Requested List Page\n offset?: string; // Results per Page\n direction?: 'asc' | 'desc'; // Order of the results\n };\n\n const query: QueryParams = request.query;\n\n // Append query parameters from the request to the external API call\n const urlParams = new URLSearchParams();\n\n // Iterate over the query parameters\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n // If the value is an array, append each item as a string\n value.forEach(val => urlParams.append(key, val));\n } else if (value) {\n urlParams.append(key, value);\n }\n }\n\n // Get entityRef from params.\n const entityRef = decodeURIComponent(request.params.environment);\n\n const credentials = await authService.getOwnServiceCredentials();\n\n const entity = await catalogService.getEntityByRef(entityRef, {\n credentials,\n });\n\n if (!entity)\n return response.status(400).json({ error: 'Invalid entityRef' });\n\n const kyvernoEndpoint =\n entity?.metadata.annotations?.[KYVERNO_ENDPOINT_ANNOTATION];\n\n if (!kyvernoEndpoint)\n return response\n .status(400)\n .json({ error: `Entity missing 'kyverno.io/endpoint' annotation` });\n\n const policyResponse = await fetch(\n `${ensureTrailingSlash(\n kyvernoEndpoint,\n )}v1/namespaced-resources/results?${urlParams.toString()}`,\n );\n\n if (!policyResponse.ok) {\n return response.status(500).json({\n error: `Failed to fetch policies: ${policyResponse.statusText}`,\n });\n }\n\n const result = await policyResponse.json();\n\n return response.status(200).json(result);\n },\n );\n\n const middleware = MiddlewareFactory.create({ logger, config });\n\n router.use(middleware.error());\n return router;\n}\n"],"names":["Router","express","KYVERNO_ENDPOINT_ANNOTATION","MiddlewareFactory"],"mappings":";;;;;;;;;;;;AAmBA,MAAM,mBAAA,GAAsB,CAAC,GAC3B,KAAA,GAAA,CAAI,SAAS,GAAG,CAAA,GAAI,GAAM,GAAA,CAAA,EAAG,GAAG,CAAA,CAAA,CAAA;AAElC,eAAsB,aACpB,OACyB,EAAA;AACzB,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAQ,EAAA,cAAA,EAAgB,aAAgB,GAAA,OAAA;AAExD,EAAA,MAAM,SAASA,uBAAO,EAAA;AACtB,EAAO,MAAA,CAAA,GAAA,CAAIC,wBAAQ,CAAA,IAAA,EAAM,CAAA;AAEzB,EAAO,MAAA,CAAA,GAAA;AAAA,IACL,4CAAA;AAAA,IACA,OAAO,SAAS,QAAa,KAAA;AAmB3B,MAAA,MAAM,QAAqB,OAAQ,CAAA,KAAA;AAGnC,MAAM,MAAA,SAAA,GAAY,IAAI,eAAgB,EAAA;AAGtC,MAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,KAAK,CAAG,EAAA;AAChD,QAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AAExB,UAAA,KAAA,CAAM,QAAQ,CAAO,GAAA,KAAA,SAAA,CAAU,MAAO,CAAA,GAAA,EAAK,GAAG,CAAC,CAAA;AAAA,mBACtC,KAAO,EAAA;AAChB,UAAU,SAAA,CAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA;AAC7B;AAIF,MAAA,MAAM,SAAY,GAAA,kBAAA,CAAmB,OAAQ,CAAA,MAAA,CAAO,WAAW,CAAA;AAE/D,MAAM,MAAA,WAAA,GAAc,MAAM,WAAA,CAAY,wBAAyB,EAAA;AAE/D,MAAA,MAAM,MAAS,GAAA,MAAM,cAAe,CAAA,cAAA,CAAe,SAAW,EAAA;AAAA,QAC5D;AAAA,OACD,CAAA;AAED,MAAA,IAAI,CAAC,MAAA;AACH,QAAO,OAAA,QAAA,CAAS,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,qBAAqB,CAAA;AAEjE,MAAA,MAAM,eACJ,GAAA,MAAA,EAAQ,QAAS,CAAA,WAAA,GAAcC,+DAA2B,CAAA;AAE5D,MAAA,IAAI,CAAC,eAAA;AACH,QAAO,OAAA,QAAA,CACJ,OAAO,GAAG,CAAA,CACV,KAAK,EAAE,KAAA,EAAO,mDAAmD,CAAA;AAEtE,MAAA,MAAM,iBAAiB,MAAM,KAAA;AAAA,QAC3B,CAAG,EAAA,mBAAA;AAAA,UACD;AAAA,SACD,CAAA,gCAAA,EAAmC,SAAU,CAAA,QAAA,EAAU,CAAA;AAAA,OAC1D;AAEA,MAAI,IAAA,CAAC,eAAe,EAAI,EAAA;AACtB,QAAA,OAAO,QAAS,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,UAC/B,KAAA,EAAO,CAA6B,0BAAA,EAAA,cAAA,CAAe,UAAU,CAAA;AAAA,SAC9D,CAAA;AAAA;AAGH,MAAM,MAAA,MAAA,GAAS,MAAM,cAAA,CAAe,IAAK,EAAA;AAEzC,MAAA,OAAO,QAAS,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,MAAM,CAAA;AAAA;AACzC,GACF;AAEA,EAAA,MAAM,aAAaC,gCAAkB,CAAA,MAAA,CAAO,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAE9D,EAAO,MAAA,CAAA,GAAA,CAAI,UAAW,CAAA,KAAA,EAAO,CAAA;AAC7B,EAAO,OAAA,MAAA;AACT;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kyverno/backstage-plugin-policy-reporter-backend",
3
- "version": "2.0.3",
3
+ "version": "2.1.0",
4
4
  "main": "dist/index.cjs.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -16,7 +16,10 @@
16
16
  "@kyverno/backstage-plugin-policy-reporter",
17
17
  "@kyverno/backstage-plugin-policy-reporter-backend",
18
18
  "@kyverno/backstage-plugin-policy-reporter-common"
19
- ]
19
+ ],
20
+ "features": {
21
+ ".": "@backstage/BackendFeature"
22
+ }
20
23
  },
21
24
  "publishConfig": {
22
25
  "access": "public",
@@ -38,10 +41,10 @@
38
41
  "postpack": "backstage-cli package postpack"
39
42
  },
40
43
  "dependencies": {
41
- "@backstage/backend-defaults": "^0.7.0",
42
- "@backstage/backend-plugin-api": "^1.1.1",
44
+ "@backstage/backend-defaults": "^0.8.1",
45
+ "@backstage/backend-plugin-api": "^1.2.0",
43
46
  "@backstage/config": "^1.3.2",
44
- "@backstage/plugin-catalog-node": "^1.15.1",
47
+ "@backstage/plugin-catalog-node": "^1.16.0",
45
48
  "@kyverno/backstage-plugin-policy-reporter-common": "^2.0.3",
46
49
  "@types/express": "*",
47
50
  "express": "^4.17.1",
@@ -50,12 +53,12 @@
50
53
  "yn": "^4.0.0"
51
54
  },
52
55
  "devDependencies": {
53
- "@backstage/backend-test-utils": "^1.2.1",
56
+ "@backstage/backend-test-utils": "^1.3.0",
54
57
  "@backstage/catalog-model": "^1.7.3",
55
- "@backstage/cli": "^0.29.5",
56
- "@backstage/plugin-auth-backend": "^0.24.2",
57
- "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.4",
58
- "@backstage/plugin-catalog-backend": "^1.30.0",
58
+ "@backstage/cli": "^0.30.0",
59
+ "@backstage/plugin-auth-backend": "^0.24.3",
60
+ "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.5",
61
+ "@backstage/plugin-catalog-backend": "^1.31.0",
59
62
  "@types/supertest": "^2.0.12",
60
63
  "better-sqlite3": "^9.0.0",
61
64
  "msw": "^1.0.0",
@@ -64,7 +67,7 @@
64
67
  "files": [
65
68
  "dist"
66
69
  ],
67
- "gitHead": "7f58ee0972f1b7af2fc88723e00d1472bf20ffc1",
70
+ "gitHead": "f16449996db64192842fa919e25dd9439258fab6",
68
71
  "typesVersions": {
69
72
  "*": {
70
73
  "index": [