@kyverno/backstage-plugin-policy-reporter 2.4.1 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @kyverno/backstage-plugin-policy-reporter
2
2
 
3
+ ## 2.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 93bf028: Added namespace filtering to the `PolicyReportsPage`. Users can now filter the list of policy reports by selecting one or more namespaces from the selected cluster.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [93bf028]
12
+ - @kyverno/backstage-plugin-policy-reporter-common@2.2.0
13
+
14
+ ## 2.5.0
15
+
16
+ ### Minor Changes
17
+
18
+ - 44376bd: Add support for the `backstage.io/kubernetes-namespace` annotation as an alternative for the `kyverno.io/namespace`. This is useful for anyone already using the Kubernetes plugin. The kyverno namespaced annotation will always be the first priority.
19
+
20
+ Add `isPolicyReporterAvailable` helper function to validate if PolicyReporter is configured for an entity.
21
+
22
+ - ee217ed: Update to Backstage versions 1.43.0
23
+ - e713e1f: Migrate to OpenAPI-generated ApiClient, typed Express router, and common types instead of manual definitions.
24
+
25
+ **BREAKING:** The backend endpoint now accepts environment entity as a query parameter instead of a path parameter.
26
+
27
+ Frontend and backend must be updated simultaneously to maintain compatibility.
28
+
29
+ ### Patch Changes
30
+
31
+ - Updated dependencies [44376bd]
32
+ - Updated dependencies [ee217ed]
33
+ - Updated dependencies [e713e1f]
34
+ - @kyverno/backstage-plugin-policy-reporter-common@2.1.0
35
+
3
36
  ## 2.4.1
4
37
 
5
38
  ### Patch Changes
@@ -1,46 +1,8 @@
1
- class PolicyReporterApiClient {
2
- discoveryApi;
3
- fetchApi;
4
- constructor(options) {
5
- this.discoveryApi = options.discoveryApi;
6
- this.fetchApi = options.fetchApi;
7
- }
8
- /**
9
- * Creates a URL query string from a given parameters object.
10
- *
11
- * This function takes an optional object of key-value pairs and converts it into a URL query string.
12
- * If the value of a key is an array, each element of the array will be added as a separate query parameter.
13
- * If the value is not undefined or null, it will be converted to a string and added as a query parameter.
14
- *
15
- * @param {Record<string, any>} [params] - An optional object containing key-value pairs to be converted into URL parameters.
16
- * @returns {string} - A URL query string generated from the provided parameters.
17
- */
18
- createUrlParams(params) {
19
- const urlParams = new URLSearchParams();
20
- if (params) {
21
- for (const [key, value] of Object.entries(params)) {
22
- if (Array.isArray(value)) {
23
- value.forEach((val) => urlParams.append(key, val));
24
- } else if (value !== void 0 && value !== null) {
25
- urlParams.append(key, value.toString());
26
- }
27
- }
28
- }
29
- return urlParams.toString();
30
- }
31
- async namespacedResults(environment, filter, pagination) {
32
- const baseUrl = await this.discoveryApi.getBaseUrl("policy-reporter");
33
- const urlParams = this.createUrlParams({ ...filter, ...pagination });
34
- const url = `${baseUrl}/namespaced-resources/${encodeURIComponent(
35
- environment
36
- )}/results?${urlParams}`;
37
- const response = await this.fetchApi.fetch(url);
38
- if (!response.ok) {
39
- throw new Error("failed to fetch policies");
40
- }
41
- return await response.json();
42
- }
43
- }
1
+ import { createApiRef } from '@backstage/core-plugin-api';
44
2
 
45
- export { PolicyReporterApiClient };
3
+ const policyReporterApiRef = createApiRef({
4
+ id: "plugin.policy-reporter.service"
5
+ });
6
+
7
+ export { policyReporterApiRef };
46
8
  //# sourceMappingURL=PolicyReporterClient.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PolicyReporterClient.esm.js","sources":["../../src/api/PolicyReporterClient.ts"],"sourcesContent":["import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';\nimport { PolicyReporterApi } from './PolicyReporterApi';\nimport {\n Filter,\n Pagination,\n ResultList,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\n\nexport class PolicyReporterApiClient implements PolicyReporterApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: { fetchApi: FetchApi; discoveryApi: DiscoveryApi }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n /**\n * Creates a URL query string from a given parameters object.\n *\n * This function takes an optional object of key-value pairs and converts it into a URL query string.\n * If the value of a key is an array, each element of the array will be added as a separate query parameter.\n * If the value is not undefined or null, it will be converted to a string and added as a query parameter.\n *\n * @param {Record<string, any>} [params] - An optional object containing key-value pairs to be converted into URL parameters.\n * @returns {string} - A URL query string generated from the provided parameters.\n */\n private createUrlParams(params?: Record<string, any>): string {\n const urlParams = new URLSearchParams();\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (Array.isArray(value)) {\n value.forEach(val => urlParams.append(key, val));\n } else if (value !== undefined && value !== null) {\n urlParams.append(key, value.toString());\n }\n }\n }\n return urlParams.toString();\n }\n\n async namespacedResults(\n environment: string,\n filter?: Filter,\n pagination?: Pagination,\n ): Promise<ResultList> {\n const baseUrl = await this.discoveryApi.getBaseUrl('policy-reporter');\n\n const urlParams = this.createUrlParams({ ...filter, ...pagination });\n\n const url = `${baseUrl}/namespaced-resources/${encodeURIComponent(\n environment,\n )}/results?${urlParams}`;\n\n const response = await this.fetchApi.fetch(url);\n if (!response.ok) {\n throw new Error('failed to fetch policies');\n }\n return await response.json();\n }\n}\n"],"names":[],"mappings":"AAQO,MAAM,uBAAqD,CAAA;AAAA,EAC/C,YAAA;AAAA,EACA,QAAA;AAAA,EAEjB,YAAY,OAA6D,EAAA;AACvE,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA;AAC5B,IAAA,IAAA,CAAK,WAAW,OAAQ,CAAA,QAAA;AAAA;AAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,gBAAgB,MAAsC,EAAA;AAC5D,IAAM,MAAA,SAAA,GAAY,IAAI,eAAgB,EAAA;AAEtC,IAAA,IAAI,MAAQ,EAAA;AACV,MAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,MAAM,CAAG,EAAA;AACjD,QAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AACxB,UAAA,KAAA,CAAM,QAAQ,CAAO,GAAA,KAAA,SAAA,CAAU,MAAO,CAAA,GAAA,EAAK,GAAG,CAAC,CAAA;AAAA,SACtC,MAAA,IAAA,KAAA,KAAU,KAAa,CAAA,IAAA,KAAA,KAAU,IAAM,EAAA;AAChD,UAAA,SAAA,CAAU,MAAO,CAAA,GAAA,EAAK,KAAM,CAAA,QAAA,EAAU,CAAA;AAAA;AACxC;AACF;AAEF,IAAA,OAAO,UAAU,QAAS,EAAA;AAAA;AAC5B,EAEA,MAAM,iBAAA,CACJ,WACA,EAAA,MAAA,EACA,UACqB,EAAA;AACrB,IAAA,MAAM,OAAU,GAAA,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,iBAAiB,CAAA;AAEpE,IAAM,MAAA,SAAA,GAAY,KAAK,eAAgB,CAAA,EAAE,GAAG,MAAQ,EAAA,GAAG,YAAY,CAAA;AAEnE,IAAM,MAAA,GAAA,GAAM,CAAG,EAAA,OAAO,CAAyB,sBAAA,EAAA,kBAAA;AAAA,MAC7C;AAAA,KACD,YAAY,SAAS,CAAA,CAAA;AAEtB,IAAA,MAAM,QAAW,GAAA,MAAM,IAAK,CAAA,QAAA,CAAS,MAAM,GAAG,CAAA;AAC9C,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAM,MAAA,IAAI,MAAM,0BAA0B,CAAA;AAAA;AAE5C,IAAO,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAE/B;;;;"}
1
+ {"version":3,"file":"PolicyReporterClient.esm.js","sources":["../../src/api/PolicyReporterClient.ts"],"sourcesContent":["import { createApiRef } from '@backstage/core-plugin-api';\nimport { DefaultApiClient } from '@kyverno/backstage-plugin-policy-reporter-common';\n\nexport const policyReporterApiRef = createApiRef<DefaultApiClient>({\n id: 'plugin.policy-reporter.service',\n});\n"],"names":[],"mappings":";;AAGO,MAAM,uBAAuB,YAA+B,CAAA;AAAA,EACjE,EAAI,EAAA;AACN,CAAC;;;;"}
@@ -4,10 +4,10 @@ import { useEntity, MissingAnnotationEmptyState } from '@backstage/plugin-catalo
4
4
  import { Grid } from '@material-ui/core';
5
5
  import { PolicyReportsTable } from '../PolicyReportsTable/PolicyReportsTable.esm.js';
6
6
  import { SelectEnvironment } from '../SelectEnvironment/SelectEnvironment.esm.js';
7
- import { containsRequiredAnnotations, annotationsRequired } from '../../utils/annotations.esm.js';
7
+ import { isPolicyReporterAvailable, getNamespaces, getKinds, getResourceName } from '../../utils/annotations.esm.js';
8
8
  import { MissingEnvironmentsEmptyState } from '../MissingEnvironmentsEmptyState/MissingEnvironmentsEmptyState.esm.js';
9
9
  import { useEntityEnvironment } from '../../hooks/useEntityEnvironment.esm.js';
10
- import { KYVERNO_NAMESPACE_ANNOTATION, KYVERNO_KIND_ANNOTATION, KYVERNO_RESOURCE_NAME_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';
10
+ import { KYVERNO_RESOURCE_NAME_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';
11
11
 
12
12
  const PageContent = ({ children }) => /* @__PURE__ */ jsx(Page, { themeId: "tool", children: /* @__PURE__ */ jsx(Content, { children }) });
13
13
  const EntityCustomPoliciesContent = ({
@@ -18,7 +18,7 @@ const EntityCustomPoliciesContent = ({
18
18
  }) => {
19
19
  const { entity } = useEntity();
20
20
  const annotations = entity.metadata.annotations;
21
- const annotationsState = containsRequiredAnnotations(annotations);
21
+ const annotationsState = isPolicyReporterAvailable(entity);
22
22
  const {
23
23
  environments,
24
24
  environmentsLoading,
@@ -30,15 +30,15 @@ const EntityCustomPoliciesContent = ({
30
30
  MissingAnnotationEmptyState,
31
31
  {
32
32
  readMoreUrl: annotationsDocumentationUrl,
33
- annotation: annotationsRequired
33
+ annotation: KYVERNO_RESOURCE_NAME_ANNOTATION
34
34
  }
35
35
  ) });
36
36
  if (environmentsLoading) return /* @__PURE__ */ jsx(Progress, {});
37
37
  if (environments === void 0 || !currentEnvironment)
38
38
  return /* @__PURE__ */ jsx(PageContent, { children: /* @__PURE__ */ jsx(MissingEnvironmentsEmptyState, { entity }) });
39
- const namespaces = annotations[KYVERNO_NAMESPACE_ANNOTATION].split(",");
40
- const kinds = annotations[KYVERNO_KIND_ANNOTATION].split(",");
41
- const resourceName = annotations[KYVERNO_RESOURCE_NAME_ANNOTATION];
39
+ const namespaces = getNamespaces(annotations);
40
+ const kinds = getKinds(annotations);
41
+ const resourceName = getResourceName(annotations);
42
42
  return /* @__PURE__ */ jsxs(PageContent, { children: [
43
43
  /* @__PURE__ */ jsx(ContentHeader, { title, children: /* @__PURE__ */ jsx(
44
44
  SelectEnvironment,
@@ -1 +1 @@
1
- {"version":3,"file":"EntityCustomPoliciesContent.esm.js","sources":["../../../src/components/EntityCustomPoliciesContent/EntityCustomPoliciesContent.tsx"],"sourcesContent":["import {\n Content,\n ContentHeader,\n Page,\n Progress,\n} from '@backstage/core-components';\nimport {\n MissingAnnotationEmptyState,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport { Grid } from '@material-ui/core';\nimport { PolicyReportsTable } from '../PolicyReportsTable';\nimport { SelectEnvironment } from '../SelectEnvironment';\nimport {\n containsRequiredAnnotations,\n annotationsRequired,\n} from '../../utils/annotations';\nimport { MissingEnvironmentsEmptyState } from '../MissingEnvironmentsEmptyState';\nimport { useEntityEnvironment } from '../../hooks/useEntityEnvironment';\nimport {\n KYVERNO_KIND_ANNOTATION,\n KYVERNO_NAMESPACE_ANNOTATION,\n KYVERNO_RESOURCE_NAME_ANNOTATION,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\n\ntype EntityCustomPoliciesContentProps = {\n annotationsDocumentationUrl?: string;\n policyDocumentationUrl?: string;\n sources: string[];\n title: string;\n};\n\ntype PageContentProps = {\n children: React.ReactNode;\n};\n\nconst PageContent = ({ children }: PageContentProps) => (\n <Page themeId=\"tool\">\n <Content>{children}</Content>\n </Page>\n);\n\nexport const EntityCustomPoliciesContent = ({\n annotationsDocumentationUrl,\n policyDocumentationUrl,\n sources,\n title,\n}: EntityCustomPoliciesContentProps) => {\n const { entity } = useEntity();\n const annotations = entity.metadata.annotations;\n\n // Boolean variable to validate that entity have required annotations\n const annotationsState: boolean = containsRequiredAnnotations(annotations);\n\n const {\n environments,\n environmentsLoading,\n setCurrentEnvironment,\n currentEnvironment,\n } = useEntityEnvironment(entity, annotationsState);\n\n // Annotations missing\n if (!annotationsState)\n return (\n <PageContent>\n <MissingAnnotationEmptyState\n readMoreUrl={annotationsDocumentationUrl}\n annotation={annotationsRequired}\n />\n </PageContent>\n );\n\n // Fetching environments\n if (environmentsLoading) return <Progress />;\n\n // Environments missing\n if (environments === undefined || !currentEnvironment)\n return (\n <PageContent>\n <MissingEnvironmentsEmptyState entity={entity} />\n </PageContent>\n );\n\n const namespaces = annotations![KYVERNO_NAMESPACE_ANNOTATION].split(',');\n const kinds = annotations![KYVERNO_KIND_ANNOTATION].split(',');\n const resourceName = annotations![KYVERNO_RESOURCE_NAME_ANNOTATION];\n\n return (\n <PageContent>\n <ContentHeader title={title}>\n <SelectEnvironment\n environments={environments}\n currentEnvironment={currentEnvironment}\n setCurrentEnvironment={setCurrentEnvironment}\n />\n </ContentHeader>\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources,\n kinds,\n status: ['fail', 'warn', 'error'],\n search: resourceName,\n }}\n title=\"Failing Policy Results\"\n emptyContentText=\"No failing policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources,\n kinds,\n status: ['pass'],\n search: resourceName,\n }}\n title=\"Passing Policy Results\"\n emptyContentText=\"No passing policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources,\n kinds,\n status: ['skip'],\n search: resourceName,\n }}\n title=\"Skipped Policy Results\"\n emptyContentText=\"No skipped policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n </Grid>\n </PageContent>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;AAoCA,MAAM,WAAc,GAAA,CAAC,EAAE,QAAA,EACrB,qBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,OAAA,EAAQ,MACZ,EAAA,QAAA,kBAAA,GAAA,CAAC,OAAS,EAAA,EAAA,QAAA,EAAS,CACrB,EAAA,CAAA;AAGK,MAAM,8BAA8B,CAAC;AAAA,EAC1C,2BAAA;AAAA,EACA,sBAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAwC,KAAA;AACtC,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,SAAU,EAAA;AAC7B,EAAM,MAAA,WAAA,GAAc,OAAO,QAAS,CAAA,WAAA;AAGpC,EAAM,MAAA,gBAAA,GAA4B,4BAA4B,WAAW,CAAA;AAEzE,EAAM,MAAA;AAAA,IACJ,YAAA;AAAA,IACA,mBAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA,GACF,GAAI,oBAAqB,CAAA,MAAA,EAAQ,gBAAgB,CAAA;AAGjD,EAAA,IAAI,CAAC,gBAAA;AACH,IAAA,2BACG,WACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,2BAAA;AAAA,MAAA;AAAA,QACC,WAAa,EAAA,2BAAA;AAAA,QACb,UAAY,EAAA;AAAA;AAAA,KAEhB,EAAA,CAAA;AAIJ,EAAI,IAAA,mBAAA,EAA4B,uBAAA,GAAA,CAAC,QAAS,EAAA,EAAA,CAAA;AAG1C,EAAI,IAAA,YAAA,KAAiB,UAAa,CAAC,kBAAA;AACjC,IAAA,uBACG,GAAA,CAAA,WAAA,EAAA,EACC,QAAC,kBAAA,GAAA,CAAA,6BAAA,EAAA,EAA8B,QAAgB,CACjD,EAAA,CAAA;AAGJ,EAAA,MAAM,UAAa,GAAA,WAAA,CAAa,4BAA4B,CAAA,CAAE,MAAM,GAAG,CAAA;AACvE,EAAA,MAAM,KAAQ,GAAA,WAAA,CAAa,uBAAuB,CAAA,CAAE,MAAM,GAAG,CAAA;AAC7D,EAAM,MAAA,YAAA,GAAe,YAAa,gCAAgC,CAAA;AAElE,EAAA,4BACG,WACC,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,iBAAc,KACb,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,YAAA;AAAA,QACA,kBAAA;AAAA,QACA;AAAA;AAAA,KAEJ,EAAA,CAAA;AAAA,oBACC,IAAA,CAAA,IAAA,EAAA,EAAK,SAAS,EAAA,IAAA,EAAC,SAAS,CACvB,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,IAAC,EAAA,EAAA,EAAI,EACb,EAAA,QAAA,kBAAA,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,kBAAA;AAAA,UACA,MAAQ,EAAA;AAAA,YACN,UAAA;AAAA,YACA,OAAA;AAAA,YACA,KAAA;AAAA,YACA,MAAQ,EAAA,CAAC,MAAQ,EAAA,MAAA,EAAQ,OAAO,CAAA;AAAA,YAChC,MAAQ,EAAA;AAAA,WACV;AAAA,UACA,KAAM,EAAA,wBAAA;AAAA,UACN,gBAAiB,EAAA,qBAAA;AAAA,UACjB,sBAAA;AAAA,UACA,YAAc,EAAA;AAAA;AAAA,OAElB,EAAA,CAAA;AAAA,sBACC,GAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAC,IAAI,EACb,EAAA,QAAA,kBAAA,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,kBAAA;AAAA,UACA,MAAQ,EAAA;AAAA,YACN,UAAA;AAAA,YACA,OAAA;AAAA,YACA,KAAA;AAAA,YACA,MAAA,EAAQ,CAAC,MAAM,CAAA;AAAA,YACf,MAAQ,EAAA;AAAA,WACV;AAAA,UACA,KAAM,EAAA,wBAAA;AAAA,UACN,gBAAiB,EAAA,qBAAA;AAAA,UACjB,sBAAA;AAAA,UACA,YAAc,EAAA;AAAA;AAAA,OAElB,EAAA,CAAA;AAAA,sBACC,GAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAC,IAAI,EACb,EAAA,QAAA,kBAAA,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,kBAAA;AAAA,UACA,MAAQ,EAAA;AAAA,YACN,UAAA;AAAA,YACA,OAAA;AAAA,YACA,KAAA;AAAA,YACA,MAAA,EAAQ,CAAC,MAAM,CAAA;AAAA,YACf,MAAQ,EAAA;AAAA,WACV;AAAA,UACA,KAAM,EAAA,wBAAA;AAAA,UACN,gBAAiB,EAAA,qBAAA;AAAA,UACjB,sBAAA;AAAA,UACA,YAAc,EAAA;AAAA;AAAA,OAElB,EAAA;AAAA,KACF,EAAA;AAAA,GACF,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"EntityCustomPoliciesContent.esm.js","sources":["../../../src/components/EntityCustomPoliciesContent/EntityCustomPoliciesContent.tsx"],"sourcesContent":["import {\n Content,\n ContentHeader,\n Page,\n Progress,\n} from '@backstage/core-components';\nimport {\n MissingAnnotationEmptyState,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport { Grid } from '@material-ui/core';\nimport { PolicyReportsTable } from '../PolicyReportsTable';\nimport { SelectEnvironment } from '../SelectEnvironment';\nimport {\n getKinds,\n getNamespaces,\n getResourceName,\n isPolicyReporterAvailable,\n} from '../../utils/annotations';\nimport { MissingEnvironmentsEmptyState } from '../MissingEnvironmentsEmptyState';\nimport { useEntityEnvironment } from '../../hooks/useEntityEnvironment';\nimport { KYVERNO_RESOURCE_NAME_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';\n\ntype EntityCustomPoliciesContentProps = {\n annotationsDocumentationUrl?: string;\n policyDocumentationUrl?: string;\n sources: string[];\n title: string;\n};\n\ntype PageContentProps = {\n children: React.ReactNode;\n};\n\nconst PageContent = ({ children }: PageContentProps) => (\n <Page themeId=\"tool\">\n <Content>{children}</Content>\n </Page>\n);\n\nexport const EntityCustomPoliciesContent = ({\n annotationsDocumentationUrl,\n policyDocumentationUrl,\n sources,\n title,\n}: EntityCustomPoliciesContentProps) => {\n const { entity } = useEntity();\n const annotations = entity.metadata.annotations;\n\n const annotationsState = isPolicyReporterAvailable(entity);\n\n const {\n environments,\n environmentsLoading,\n setCurrentEnvironment,\n currentEnvironment,\n } = useEntityEnvironment(entity, annotationsState);\n\n // Annotations missing\n if (!annotationsState)\n return (\n <PageContent>\n <MissingAnnotationEmptyState\n readMoreUrl={annotationsDocumentationUrl}\n annotation={KYVERNO_RESOURCE_NAME_ANNOTATION}\n />\n </PageContent>\n );\n\n // Fetching environments\n if (environmentsLoading) return <Progress />;\n\n // Environments missing\n if (environments === undefined || !currentEnvironment)\n return (\n <PageContent>\n <MissingEnvironmentsEmptyState entity={entity} />\n </PageContent>\n );\n\n const namespaces = getNamespaces(annotations);\n const kinds = getKinds(annotations);\n const resourceName = getResourceName(annotations);\n\n return (\n <PageContent>\n <ContentHeader title={title}>\n <SelectEnvironment\n environments={environments}\n currentEnvironment={currentEnvironment}\n setCurrentEnvironment={setCurrentEnvironment}\n />\n </ContentHeader>\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources,\n kinds,\n status: ['fail', 'warn', 'error'],\n search: resourceName,\n }}\n title=\"Failing Policy Results\"\n emptyContentText=\"No failing policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources,\n kinds,\n status: ['pass'],\n search: resourceName,\n }}\n title=\"Passing Policy Results\"\n emptyContentText=\"No passing policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources,\n kinds,\n status: ['skip'],\n search: resourceName,\n }}\n title=\"Skipped Policy Results\"\n emptyContentText=\"No skipped policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n </Grid>\n </PageContent>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -4,10 +4,10 @@ import { useEntity, MissingAnnotationEmptyState } from '@backstage/plugin-catalo
4
4
  import { Grid } from '@material-ui/core';
5
5
  import { PolicyReportsTable } from '../PolicyReportsTable/PolicyReportsTable.esm.js';
6
6
  import { SelectEnvironment } from '../SelectEnvironment/SelectEnvironment.esm.js';
7
- import { annotationsRequired, containsRequiredAnnotations } from '../../utils/annotations.esm.js';
7
+ import { isPolicyReporterAvailable, getNamespaces, getKinds, getResourceName } from '../../utils/annotations.esm.js';
8
8
  import { MissingEnvironmentsEmptyState } from '../MissingEnvironmentsEmptyState/MissingEnvironmentsEmptyState.esm.js';
9
9
  import { useEntityEnvironment } from '../../hooks/useEntityEnvironment.esm.js';
10
- import { KYVERNO_NAMESPACE_ANNOTATION, KYVERNO_KIND_ANNOTATION, KYVERNO_RESOURCE_NAME_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';
10
+ import { KYVERNO_RESOURCE_NAME_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';
11
11
 
12
12
  const PageContent = ({ children }) => /* @__PURE__ */ jsx(Page, { themeId: "tool", children: /* @__PURE__ */ jsx(Content, { children }) });
13
13
  const EntityKyvernoPoliciesContent = ({
@@ -16,7 +16,7 @@ const EntityKyvernoPoliciesContent = ({
16
16
  }) => {
17
17
  const { entity } = useEntity();
18
18
  const annotations = entity.metadata.annotations;
19
- const annotationsState = containsRequiredAnnotations(annotations);
19
+ const annotationsState = isPolicyReporterAvailable(entity);
20
20
  const {
21
21
  environments,
22
22
  environmentsLoading,
@@ -28,15 +28,15 @@ const EntityKyvernoPoliciesContent = ({
28
28
  MissingAnnotationEmptyState,
29
29
  {
30
30
  readMoreUrl: annotationsDocumentationUrl,
31
- annotation: annotationsRequired
31
+ annotation: KYVERNO_RESOURCE_NAME_ANNOTATION
32
32
  }
33
33
  ) });
34
34
  if (environmentsLoading) return /* @__PURE__ */ jsx(Progress, {});
35
35
  if (environments === void 0 || !currentEnvironment)
36
36
  return /* @__PURE__ */ jsx(PageContent, { children: /* @__PURE__ */ jsx(MissingEnvironmentsEmptyState, { entity }) });
37
- const namespaces = annotations[KYVERNO_NAMESPACE_ANNOTATION].split(",");
38
- const kinds = annotations[KYVERNO_KIND_ANNOTATION].split(",");
39
- const resourceName = annotations[KYVERNO_RESOURCE_NAME_ANNOTATION];
37
+ const namespaces = getNamespaces(annotations);
38
+ const kinds = getKinds(annotations);
39
+ const resourceName = getResourceName(annotations);
40
40
  return /* @__PURE__ */ jsxs(PageContent, { children: [
41
41
  /* @__PURE__ */ jsx(ContentHeader, { title: "Kyverno Policy Reports", children: /* @__PURE__ */ jsx(
42
42
  SelectEnvironment,
@@ -1 +1 @@
1
- {"version":3,"file":"EntityKyvernoPoliciesContent.esm.js","sources":["../../../src/components/EntityKyvernoPoliciesContent/EntityKyvernoPoliciesContent.tsx"],"sourcesContent":["import {\n Content,\n ContentHeader,\n Page,\n Progress,\n} from '@backstage/core-components';\nimport {\n MissingAnnotationEmptyState,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport { Grid } from '@material-ui/core';\nimport { PolicyReportsTable } from '../PolicyReportsTable';\nimport { SelectEnvironment } from '../SelectEnvironment';\nimport {\n containsRequiredAnnotations,\n annotationsRequired,\n} from '../../utils/annotations';\nimport { MissingEnvironmentsEmptyState } from '../MissingEnvironmentsEmptyState';\nimport { useEntityEnvironment } from '../../hooks/useEntityEnvironment';\nimport {\n KYVERNO_KIND_ANNOTATION,\n KYVERNO_NAMESPACE_ANNOTATION,\n KYVERNO_RESOURCE_NAME_ANNOTATION,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\n\ntype KyvernoPoliciesContentProps = {\n annotationsDocumentationUrl?: string;\n policyDocumentationUrl?: string;\n};\n\ntype PageContentProps = {\n children: React.ReactNode;\n};\n\nconst PageContent = ({ children }: PageContentProps) => (\n <Page themeId=\"tool\">\n <Content>{children}</Content>\n </Page>\n);\n\nexport const EntityKyvernoPoliciesContent = ({\n annotationsDocumentationUrl,\n policyDocumentationUrl,\n}: KyvernoPoliciesContentProps) => {\n const { entity } = useEntity();\n const annotations = entity.metadata.annotations;\n\n // Boolean variable to validate that entity have required annotations\n const annotationsState: boolean = containsRequiredAnnotations(annotations);\n\n const {\n environments,\n environmentsLoading,\n setCurrentEnvironment,\n currentEnvironment,\n } = useEntityEnvironment(entity, annotationsState);\n\n // Annotations missing\n if (!annotationsState)\n return (\n <PageContent>\n <MissingAnnotationEmptyState\n readMoreUrl={annotationsDocumentationUrl}\n annotation={annotationsRequired}\n />\n </PageContent>\n );\n\n // Fetching environments\n if (environmentsLoading) return <Progress />;\n\n // Environments missing\n if (environments === undefined || !currentEnvironment)\n return (\n <PageContent>\n <MissingEnvironmentsEmptyState entity={entity} />\n </PageContent>\n );\n\n const namespaces = annotations![KYVERNO_NAMESPACE_ANNOTATION].split(',');\n const kinds = annotations![KYVERNO_KIND_ANNOTATION].split(',');\n const resourceName = annotations![KYVERNO_RESOURCE_NAME_ANNOTATION];\n\n return (\n <PageContent>\n <ContentHeader title=\"Kyverno Policy Reports\">\n <SelectEnvironment\n environments={environments}\n currentEnvironment={currentEnvironment}\n setCurrentEnvironment={setCurrentEnvironment}\n />\n </ContentHeader>\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources: ['kyverno'],\n kinds,\n status: ['fail', 'warn', 'error'],\n search: resourceName,\n }}\n title=\"Failing Policy Results\"\n emptyContentText=\"No failing policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources: ['kyverno'],\n kinds,\n status: ['pass'],\n search: resourceName,\n }}\n title=\"Passing Policy Results\"\n emptyContentText=\"No passing policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources: ['kyverno'],\n kinds,\n status: ['skip'],\n search: resourceName,\n }}\n title=\"Skipped Policy Results\"\n emptyContentText=\"No skipped policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n </Grid>\n </PageContent>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EntityKyvernoPoliciesContent.esm.js","sources":["../../../src/components/EntityKyvernoPoliciesContent/EntityKyvernoPoliciesContent.tsx"],"sourcesContent":["import {\n Content,\n ContentHeader,\n Page,\n Progress,\n} from '@backstage/core-components';\nimport {\n MissingAnnotationEmptyState,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport { Grid } from '@material-ui/core';\nimport { PolicyReportsTable } from '../PolicyReportsTable';\nimport { SelectEnvironment } from '../SelectEnvironment';\nimport {\n getKinds,\n getNamespaces,\n getResourceName,\n isPolicyReporterAvailable,\n} from '../../utils/annotations';\nimport { MissingEnvironmentsEmptyState } from '../MissingEnvironmentsEmptyState';\nimport { useEntityEnvironment } from '../../hooks/useEntityEnvironment';\nimport { KYVERNO_RESOURCE_NAME_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';\n\ntype KyvernoPoliciesContentProps = {\n annotationsDocumentationUrl?: string;\n policyDocumentationUrl?: string;\n};\n\ntype PageContentProps = {\n children: React.ReactNode;\n};\n\nconst PageContent = ({ children }: PageContentProps) => (\n <Page themeId=\"tool\">\n <Content>{children}</Content>\n </Page>\n);\n\nexport const EntityKyvernoPoliciesContent = ({\n annotationsDocumentationUrl,\n policyDocumentationUrl,\n}: KyvernoPoliciesContentProps) => {\n const { entity } = useEntity();\n const annotations = entity.metadata.annotations;\n\n // Boolean variable to validate that entity have required annotations\n const annotationsState = isPolicyReporterAvailable(entity);\n\n const {\n environments,\n environmentsLoading,\n setCurrentEnvironment,\n currentEnvironment,\n } = useEntityEnvironment(entity, annotationsState);\n\n // Annotations missing\n if (!annotationsState)\n return (\n <PageContent>\n <MissingAnnotationEmptyState\n readMoreUrl={annotationsDocumentationUrl}\n annotation={KYVERNO_RESOURCE_NAME_ANNOTATION}\n />\n </PageContent>\n );\n\n // Fetching environments\n if (environmentsLoading) return <Progress />;\n\n // Environments missing\n if (environments === undefined || !currentEnvironment)\n return (\n <PageContent>\n <MissingEnvironmentsEmptyState entity={entity} />\n </PageContent>\n );\n\n const namespaces = getNamespaces(annotations);\n const kinds = getKinds(annotations);\n const resourceName = getResourceName(annotations);\n\n return (\n <PageContent>\n <ContentHeader title=\"Kyverno Policy Reports\">\n <SelectEnvironment\n environments={environments}\n currentEnvironment={currentEnvironment}\n setCurrentEnvironment={setCurrentEnvironment}\n />\n </ContentHeader>\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources: ['kyverno'],\n kinds,\n status: ['fail', 'warn', 'error'],\n search: resourceName,\n }}\n title=\"Failing Policy Results\"\n emptyContentText=\"No failing policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources: ['kyverno'],\n kinds,\n status: ['pass'],\n search: resourceName,\n }}\n title=\"Passing Policy Results\"\n emptyContentText=\"No passing policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n namespaces,\n sources: ['kyverno'],\n kinds,\n status: ['skip'],\n search: resourceName,\n }}\n title=\"Skipped Policy Results\"\n emptyContentText=\"No skipped policies\"\n policyDocumentationUrl={policyDocumentationUrl}\n enableSearch={false}\n />\n </Grid>\n </Grid>\n </PageContent>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -7,6 +7,8 @@ import { PolicyReportsTable } from '../PolicyReportsTable/PolicyReportsTable.esm
7
7
  import { useState } from 'react';
8
8
  import { SelectStatus } from '../SelectStatus/SelectStatus.esm.js';
9
9
  import { SelectSeverity } from '../SelectSeverity/SelectSeverity.esm.js';
10
+ import { SelectNamespace } from '../SelectNamespace/SelectNamespace.esm.js';
11
+ import { useNamespaces } from '../../hooks/useNamespaces.esm.js';
10
12
 
11
13
  const PolicyReportsPage = ({
12
14
  title = "Policy Reports",
@@ -21,6 +23,8 @@ const PolicyReportsPage = ({
21
23
  } = useEnvironments();
22
24
  const [status, setStatus] = useState(["fail"]);
23
25
  const [severity, setSeverity] = useState([]);
26
+ const [selectedNamespaces, setSelectedNamespaces] = useState([]);
27
+ const { namespaces: availableNamespaces } = useNamespaces(currentEnvironment);
24
28
  if (environmentsLoading) return /* @__PURE__ */ jsx(Progress, {});
25
29
  if (environments === void 0 || !currentEnvironment)
26
30
  return /* @__PURE__ */ jsxs(Page, { themeId: "tool", children: [
@@ -59,6 +63,14 @@ const PolicyReportsPage = ({
59
63
  setSeverity
60
64
  }
61
65
  ),
66
+ /* @__PURE__ */ jsx(
67
+ SelectNamespace,
68
+ {
69
+ currentNamespaces: selectedNamespaces,
70
+ setNamespaces: setSelectedNamespaces,
71
+ availableNamespaces
72
+ }
73
+ ),
62
74
  /* @__PURE__ */ jsx(
63
75
  SelectEnvironment,
64
76
  {
@@ -74,7 +86,8 @@ const PolicyReportsPage = ({
74
86
  currentEnvironment,
75
87
  filter: {
76
88
  status,
77
- severities: severity
89
+ severities: severity,
90
+ namespaces: selectedNamespaces
78
91
  },
79
92
  title: "Policy Results",
80
93
  emptyContentText: "No policies found",
@@ -1 +1 @@
1
- {"version":3,"file":"PolicyReportsPage.esm.js","sources":["../../../src/components/PolicyReportsPage/PolicyReportsPage.tsx"],"sourcesContent":["import {\n Content,\n ContentHeader,\n EmptyState,\n Header,\n Link,\n Page,\n Progress,\n} from '@backstage/core-components';\nimport { useEnvironments } from '../../hooks/useEnvironments';\nimport { SelectEnvironment } from '../SelectEnvironment';\nimport { Button, Grid } from '@material-ui/core';\nimport { PolicyReportsTable } from '../PolicyReportsTable';\nimport { useState } from 'react';\nimport {\n Severity,\n Status,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { SelectStatus } from '../SelectStatus';\nimport { SelectSeverity } from '../SelectSeverity';\n\nexport interface PolicyReportsPageProps {\n title?: string;\n policyDocumentationUrl?: string;\n subtitle?: string;\n}\n\nexport const PolicyReportsPage = ({\n title = 'Policy Reports',\n subtitle = 'View all policy reports from a Kubernetes cluster',\n policyDocumentationUrl,\n}: PolicyReportsPageProps) => {\n const {\n environments,\n environmentsLoading,\n setCurrentEnvironment,\n currentEnvironment,\n } = useEnvironments();\n\n const [status, setStatus] = useState<Status[]>(['fail']);\n const [severity, setSeverity] = useState<Severity[]>([]);\n\n // Fetching environments\n if (environmentsLoading) return <Progress />;\n\n // Environments missing\n if (environments === undefined || !currentEnvironment)\n return (\n <Page themeId=\"tool\">\n <Header title={title} subtitle={subtitle} />\n <Content>\n <EmptyState\n missing=\"content\"\n title=\"No kubernetes-cluster Resources found\"\n description={\n <>\n You need to define a Resource with the kubernetes-cluster type\n and a<code> kyverno.io/endpoint </code> annotation for this\n plugin to work.\n </>\n }\n action={\n <>\n <Button\n color=\"primary\"\n component={Link}\n to=\"https://github.com/kyverno/backstage-policy-reporter-plugin\"\n >\n Read More\n </Button>\n </>\n }\n />\n </Content>\n </Page>\n );\n\n return (\n <Page themeId=\"tool\">\n <Header title={title} subtitle={subtitle} />\n <Content>\n <ContentHeader>\n <SelectStatus currentStatus={status} setStatus={setStatus} />\n <SelectSeverity\n currentSeverity={severity}\n setSeverity={setSeverity}\n />\n <SelectEnvironment\n environments={environments}\n currentEnvironment={currentEnvironment}\n setCurrentEnvironment={setCurrentEnvironment}\n />\n </ContentHeader>\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n status: status,\n severities: severity,\n }}\n title=\"Policy Results\"\n emptyContentText=\"No policies found\"\n policyDocumentationUrl={policyDocumentationUrl}\n pagination={{ offset: 25 }}\n />\n </Grid>\n </Grid>\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PolicyReportsPage.esm.js","sources":["../../../src/components/PolicyReportsPage/PolicyReportsPage.tsx"],"sourcesContent":["import {\n Content,\n ContentHeader,\n EmptyState,\n Header,\n Link,\n Page,\n Progress,\n} from '@backstage/core-components';\nimport { useEnvironments } from '../../hooks/useEnvironments';\nimport { SelectEnvironment } from '../SelectEnvironment';\nimport { Button, Grid } from '@material-ui/core';\nimport { PolicyReportsTable } from '../PolicyReportsTable';\nimport { useState } from 'react';\nimport {\n Severity,\n Status,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { SelectStatus } from '../SelectStatus';\nimport { SelectSeverity } from '../SelectSeverity';\nimport { SelectNamespace } from '../SelectNamespace';\nimport { useNamespaces } from '../../hooks/useNamespaces';\n\nexport interface PolicyReportsPageProps {\n title?: string;\n policyDocumentationUrl?: string;\n subtitle?: string;\n}\n\nexport const PolicyReportsPage = ({\n title = 'Policy Reports',\n subtitle = 'View all policy reports from a Kubernetes cluster',\n policyDocumentationUrl,\n}: PolicyReportsPageProps) => {\n const {\n environments,\n environmentsLoading,\n setCurrentEnvironment,\n currentEnvironment,\n } = useEnvironments();\n\n const [status, setStatus] = useState<Status[]>(['fail']);\n const [severity, setSeverity] = useState<Severity[]>([]);\n const [selectedNamespaces, setSelectedNamespaces] = useState<string[]>([]);\n const { namespaces: availableNamespaces } = useNamespaces(currentEnvironment);\n\n // Fetching environments\n if (environmentsLoading) return <Progress />;\n\n // Environments missing\n if (environments === undefined || !currentEnvironment)\n return (\n <Page themeId=\"tool\">\n <Header title={title} subtitle={subtitle} />\n <Content>\n <EmptyState\n missing=\"content\"\n title=\"No kubernetes-cluster Resources found\"\n description={\n <>\n You need to define a Resource with the kubernetes-cluster type\n and a<code> kyverno.io/endpoint </code> annotation for this\n plugin to work.\n </>\n }\n action={\n <>\n <Button\n color=\"primary\"\n component={Link}\n to=\"https://github.com/kyverno/backstage-policy-reporter-plugin\"\n >\n Read More\n </Button>\n </>\n }\n />\n </Content>\n </Page>\n );\n\n return (\n <Page themeId=\"tool\">\n <Header title={title} subtitle={subtitle} />\n <Content>\n <ContentHeader>\n <SelectStatus currentStatus={status} setStatus={setStatus} />\n <SelectSeverity\n currentSeverity={severity}\n setSeverity={setSeverity}\n />\n <SelectNamespace\n currentNamespaces={selectedNamespaces}\n setNamespaces={setSelectedNamespaces}\n availableNamespaces={availableNamespaces}\n />\n <SelectEnvironment\n environments={environments}\n currentEnvironment={currentEnvironment}\n setCurrentEnvironment={setCurrentEnvironment}\n />\n </ContentHeader>\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <PolicyReportsTable\n currentEnvironment={currentEnvironment}\n filter={{\n status: status,\n severities: severity,\n namespaces: selectedNamespaces,\n }}\n title=\"Policy Results\"\n emptyContentText=\"No policies found\"\n policyDocumentationUrl={policyDocumentationUrl}\n pagination={{ offset: 25 }}\n />\n </Grid>\n </Grid>\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import MenuItem from '@material-ui/core/MenuItem';
3
+ import InputLabel from '@material-ui/core/InputLabel';
4
+ import FormControl from '@material-ui/core/FormControl';
5
+ import Select from '@material-ui/core/Select';
6
+ import { makeStyles } from '@material-ui/core/styles';
7
+ import { Checkbox, ListItemText } from '@material-ui/core';
8
+
9
+ const useStyles = makeStyles({
10
+ formControl: {
11
+ margin: 8,
12
+ minWidth: 150
13
+ }
14
+ });
15
+ const SelectNamespace = ({
16
+ currentNamespaces,
17
+ setNamespaces,
18
+ availableNamespaces
19
+ }) => {
20
+ const classes = useStyles();
21
+ const handleChange = (event) => {
22
+ setNamespaces(event.target.value);
23
+ };
24
+ return /* @__PURE__ */ jsxs(FormControl, { className: classes.formControl, children: [
25
+ /* @__PURE__ */ jsx(InputLabel, { id: "select-namespace-label", shrink: true, children: "Namespaces" }),
26
+ /* @__PURE__ */ jsx(
27
+ Select,
28
+ {
29
+ labelId: "select-namespace-label",
30
+ id: "select-namespace",
31
+ multiple: true,
32
+ displayEmpty: true,
33
+ value: currentNamespaces,
34
+ renderValue: (selected) => {
35
+ if (selected.length === 0) {
36
+ return "All";
37
+ }
38
+ return selected.join(", ");
39
+ },
40
+ onChange: handleChange,
41
+ children: availableNamespaces.map((namespace) => /* @__PURE__ */ jsxs(MenuItem, { value: namespace, children: [
42
+ /* @__PURE__ */ jsx(Checkbox, { checked: currentNamespaces.includes(namespace) }),
43
+ /* @__PURE__ */ jsx(ListItemText, { primary: namespace })
44
+ ] }, namespace))
45
+ }
46
+ )
47
+ ] });
48
+ };
49
+
50
+ export { SelectNamespace };
51
+ //# sourceMappingURL=SelectNamespace.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectNamespace.esm.js","sources":["../../../src/components/SelectNamespace/SelectNamespace.tsx"],"sourcesContent":["import MenuItem from '@material-ui/core/MenuItem';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport FormControl from '@material-ui/core/FormControl';\nimport Select from '@material-ui/core/Select';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Checkbox, ListItemText } from '@material-ui/core';\n\nconst useStyles = makeStyles({\n formControl: {\n margin: 8,\n minWidth: 150,\n },\n});\n\nexport type SelectNamespaceProps = {\n currentNamespaces: string[];\n setNamespaces: (namespaces: string[]) => void;\n availableNamespaces: string[];\n};\n\nexport const SelectNamespace = ({\n currentNamespaces,\n setNamespaces,\n availableNamespaces,\n}: SelectNamespaceProps) => {\n const classes = useStyles();\n\n const handleChange = (event: any) => {\n setNamespaces(event.target.value);\n };\n\n return (\n <FormControl className={classes.formControl}>\n <InputLabel id=\"select-namespace-label\" shrink>\n Namespaces\n </InputLabel>\n <Select\n labelId=\"select-namespace-label\"\n id=\"select-namespace\"\n multiple\n displayEmpty\n value={currentNamespaces}\n renderValue={selected => {\n if ((selected as string[]).length === 0) {\n return 'All';\n }\n\n return (selected as string[]).join(', ');\n }}\n onChange={handleChange}\n >\n {availableNamespaces.map(namespace => (\n <MenuItem key={namespace} value={namespace}>\n <Checkbox checked={currentNamespaces.includes(namespace)} />\n <ListItemText primary={namespace} />\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAOA,MAAM,YAAY,UAAW,CAAA;AAAA,EAC3B,WAAa,EAAA;AAAA,IACX,MAAQ,EAAA,CAAA;AAAA,IACR,QAAU,EAAA;AAAA;AAEd,CAAC,CAAA;AAQM,MAAM,kBAAkB,CAAC;AAAA,EAC9B,iBAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAA4B,KAAA;AAC1B,EAAA,MAAM,UAAU,SAAU,EAAA;AAE1B,EAAM,MAAA,YAAA,GAAe,CAAC,KAAe,KAAA;AACnC,IAAc,aAAA,CAAA,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,GAClC;AAEA,EAAA,uBACG,IAAA,CAAA,WAAA,EAAA,EAAY,SAAW,EAAA,OAAA,CAAQ,WAC9B,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAW,EAAA,EAAA,EAAA,EAAG,wBAAyB,EAAA,MAAA,EAAM,MAAC,QAE/C,EAAA,YAAA,EAAA,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAQ,EAAA,wBAAA;AAAA,QACR,EAAG,EAAA,kBAAA;AAAA,QACH,QAAQ,EAAA,IAAA;AAAA,QACR,YAAY,EAAA,IAAA;AAAA,QACZ,KAAO,EAAA,iBAAA;AAAA,QACP,aAAa,CAAY,QAAA,KAAA;AACvB,UAAK,IAAA,QAAA,CAAsB,WAAW,CAAG,EAAA;AACvC,YAAO,OAAA,KAAA;AAAA;AAGT,UAAQ,OAAA,QAAA,CAAsB,KAAK,IAAI,CAAA;AAAA,SACzC;AAAA,QACA,QAAU,EAAA,YAAA;AAAA,QAET,8BAAoB,GAAI,CAAA,CAAA,SAAA,qBACtB,IAAA,CAAA,QAAA,EAAA,EAAyB,OAAO,SAC/B,EAAA,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,QAAS,EAAA,EAAA,OAAA,EAAS,iBAAkB,CAAA,QAAA,CAAS,SAAS,CAAG,EAAA,CAAA;AAAA,0BAC1D,GAAA,CAAC,YAAa,EAAA,EAAA,OAAA,EAAS,SAAW,EAAA;AAAA,SAAA,EAAA,EAFrB,SAGf,CACD;AAAA;AAAA;AACH,GACF,EAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,28 @@
1
+ import { useAsync } from 'react-use';
2
+ import { useApi } from '@backstage/core-plugin-api';
3
+ import { policyReporterApiRef } from '../api/PolicyReporterClient.esm.js';
4
+
5
+ const useNamespaces = (currentEnvironment) => {
6
+ const api = useApi(policyReporterApiRef);
7
+ const {
8
+ value: namespaces,
9
+ loading,
10
+ error
11
+ } = useAsync(async () => {
12
+ if (!currentEnvironment) {
13
+ return [];
14
+ }
15
+ const response = await api.getNamespaces({
16
+ query: { environment: currentEnvironment.entityRef }
17
+ });
18
+ return response.json();
19
+ }, [api, currentEnvironment]);
20
+ return {
21
+ namespaces: namespaces ?? [],
22
+ loading,
23
+ error
24
+ };
25
+ };
26
+
27
+ export { useNamespaces };
28
+ //# sourceMappingURL=useNamespaces.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useNamespaces.esm.js","sources":["../../src/hooks/useNamespaces.ts"],"sourcesContent":["import { useAsync } from 'react-use';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { policyReporterApiRef } from '../api';\nimport { Environment } from '@kyverno/backstage-plugin-policy-reporter-common';\n\nexport const useNamespaces = (currentEnvironment?: Environment) => {\n const api = useApi(policyReporterApiRef);\n\n const {\n value: namespaces,\n loading,\n error,\n } = useAsync(async () => {\n if (!currentEnvironment) {\n return [];\n }\n\n const response = await api.getNamespaces({\n query: { environment: currentEnvironment.entityRef },\n });\n return response.json();\n }, [api, currentEnvironment]);\n\n return {\n namespaces: namespaces ?? [],\n loading,\n error,\n };\n};\n"],"names":[],"mappings":";;;;AAKa,MAAA,aAAA,GAAgB,CAAC,kBAAqC,KAAA;AACjE,EAAM,MAAA,GAAA,GAAM,OAAO,oBAAoB,CAAA;AAEvC,EAAM,MAAA;AAAA,IACJ,KAAO,EAAA,UAAA;AAAA,IACP,OAAA;AAAA,IACA;AAAA,GACF,GAAI,SAAS,YAAY;AACvB,IAAA,IAAI,CAAC,kBAAoB,EAAA;AACvB,MAAA,OAAO,EAAC;AAAA;AAGV,IAAM,MAAA,QAAA,GAAW,MAAM,GAAA,CAAI,aAAc,CAAA;AAAA,MACvC,KAAO,EAAA,EAAE,WAAa,EAAA,kBAAA,CAAmB,SAAU;AAAA,KACpD,CAAA;AACD,IAAA,OAAO,SAAS,IAAK,EAAA;AAAA,GACpB,EAAA,CAAC,GAAK,EAAA,kBAAkB,CAAC,CAAA;AAE5B,EAAO,OAAA;AAAA,IACL,UAAA,EAAY,cAAc,EAAC;AAAA,IAC3B,OAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { useAsync } from 'react-use';
2
2
  import { useApi } from '@backstage/core-plugin-api';
3
- import { policyReporterApiRef } from '../api/PolicyReporterApi.esm.js';
3
+ import { policyReporterApiRef } from '../api/PolicyReporterClient.esm.js';
4
4
  import { useState, useEffect } from 'react';
5
5
 
6
6
  const DEFAULT_OFFSET = 5;
@@ -22,18 +22,18 @@ const usePaginatedPolicies = (currentEnvironment, filter, pagination) => {
22
22
  loading: policiesLoading,
23
23
  error: policiesError
24
24
  } = useAsync(async () => {
25
- const data = await policyReporterApi.namespacedResults(
26
- currentEnvironment.entityRef,
27
- filter,
28
- {
25
+ const data = await policyReporterApi.getNamespacedResults({
26
+ query: {
27
+ environment: encodeURI(currentEnvironment.entityRef),
28
+ ...filter,
29
29
  // Material UI expects the first page to be 0. But the Policy Reporter API expects the first page to be 1
30
30
  // This increments the currentPage with 1 to match the expected page by the Policy Reporter API
31
31
  page: currentPage + 1,
32
32
  offset: currentOffset
33
33
  }
34
- );
34
+ });
35
35
  setInitialLoading(false);
36
- return data;
36
+ return data.json();
37
37
  }, [currentEnvironment, filter, currentPage, currentOffset]);
38
38
  return {
39
39
  policies,
@@ -1 +1 @@
1
- {"version":3,"file":"usePaginatedPolicies.esm.js","sources":["../../src/hooks/usePaginatedPolicies.ts"],"sourcesContent":["import { useAsync } from 'react-use';\nimport {\n Environment,\n Pagination,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { policyReporterApiRef } from '../api';\nimport {\n Filter,\n ResultList,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { useEffect, useState } from 'react';\n\nconst DEFAULT_OFFSET = 5;\nconst DEFAULT_PAGE = 0;\n\nexport const usePaginatedPolicies = (\n currentEnvironment: Environment,\n filter: Filter,\n pagination?: Partial<Pagination>,\n) => {\n const policyReporterApi = useApi(policyReporterApiRef);\n const [currentPage, setCurrentPage] = useState<number>(\n pagination?.page ?? DEFAULT_PAGE,\n );\n const [currentOffset, setCurrentOffset] = useState<number>(\n pagination?.offset ?? DEFAULT_OFFSET,\n );\n const [initialLoading, setInitialLoading] = useState<boolean>(true);\n\n useEffect(() => {\n setInitialLoading(true);\n }, [currentEnvironment]);\n\n const {\n value: policies,\n loading: policiesLoading,\n error: policiesError,\n } = useAsync(async (): Promise<ResultList> => {\n const data = await policyReporterApi.namespacedResults(\n currentEnvironment.entityRef,\n filter,\n {\n // Material UI expects the first page to be 0. But the Policy Reporter API expects the first page to be 1\n // This increments the currentPage with 1 to match the expected page by the Policy Reporter API\n page: currentPage + 1,\n offset: currentOffset,\n },\n );\n setInitialLoading(false);\n return data;\n }, [currentEnvironment, filter, currentPage, currentOffset]);\n\n return {\n policies,\n policiesLoading,\n policiesError,\n currentPage,\n setCurrentPage,\n currentOffset,\n setCurrentOffset,\n initialLoading,\n };\n};\n"],"names":[],"mappings":";;;;;AAaA,MAAM,cAAiB,GAAA,CAAA;AACvB,MAAM,YAAe,GAAA,CAAA;AAEd,MAAM,oBAAuB,GAAA,CAClC,kBACA,EAAA,MAAA,EACA,UACG,KAAA;AACH,EAAM,MAAA,iBAAA,GAAoB,OAAO,oBAAoB,CAAA;AACrD,EAAM,MAAA,CAAC,WAAa,EAAA,cAAc,CAAI,GAAA,QAAA;AAAA,IACpC,YAAY,IAAQ,IAAA;AAAA,GACtB;AACA,EAAM,MAAA,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAA,QAAA;AAAA,IACxC,YAAY,MAAU,IAAA;AAAA,GACxB;AACA,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAAkB,IAAI,CAAA;AAElE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,GACxB,EAAG,CAAC,kBAAkB,CAAC,CAAA;AAEvB,EAAM,MAAA;AAAA,IACJ,KAAO,EAAA,QAAA;AAAA,IACP,OAAS,EAAA,eAAA;AAAA,IACT,KAAO,EAAA;AAAA,GACT,GAAI,SAAS,YAAiC;AAC5C,IAAM,MAAA,IAAA,GAAO,MAAM,iBAAkB,CAAA,iBAAA;AAAA,MACnC,kBAAmB,CAAA,SAAA;AAAA,MACnB,MAAA;AAAA,MACA;AAAA;AAAA;AAAA,QAGE,MAAM,WAAc,GAAA,CAAA;AAAA,QACpB,MAAQ,EAAA;AAAA;AACV,KACF;AACA,IAAA,iBAAA,CAAkB,KAAK,CAAA;AACvB,IAAO,OAAA,IAAA;AAAA,KACN,CAAC,kBAAA,EAAoB,MAAQ,EAAA,WAAA,EAAa,aAAa,CAAC,CAAA;AAE3D,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA,eAAA;AAAA,IACA,aAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
1
+ {"version":3,"file":"usePaginatedPolicies.esm.js","sources":["../../src/hooks/usePaginatedPolicies.ts"],"sourcesContent":["import { useAsync } from 'react-use';\nimport {\n Environment,\n Pagination,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { policyReporterApiRef } from '../api';\nimport {\n Filter,\n ResultList,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { useEffect, useState } from 'react';\n\nconst DEFAULT_OFFSET = 5;\nconst DEFAULT_PAGE = 0;\n\nexport const usePaginatedPolicies = (\n currentEnvironment: Environment,\n filter: Filter,\n pagination?: Partial<Pagination>,\n) => {\n const policyReporterApi = useApi(policyReporterApiRef);\n const [currentPage, setCurrentPage] = useState<number>(\n pagination?.page ?? DEFAULT_PAGE,\n );\n const [currentOffset, setCurrentOffset] = useState<number>(\n pagination?.offset ?? DEFAULT_OFFSET,\n );\n const [initialLoading, setInitialLoading] = useState<boolean>(true);\n\n useEffect(() => {\n setInitialLoading(true);\n }, [currentEnvironment]);\n\n const {\n value: policies,\n loading: policiesLoading,\n error: policiesError,\n } = useAsync(async (): Promise<ResultList> => {\n const data = await policyReporterApi.getNamespacedResults({\n query: {\n environment: encodeURI(currentEnvironment.entityRef),\n ...filter,\n // Material UI expects the first page to be 0. But the Policy Reporter API expects the first page to be 1\n // This increments the currentPage with 1 to match the expected page by the Policy Reporter API\n page: currentPage + 1,\n offset: currentOffset,\n },\n });\n\n setInitialLoading(false);\n return data.json();\n }, [currentEnvironment, filter, currentPage, currentOffset]);\n\n return {\n policies,\n policiesLoading,\n policiesError,\n currentPage,\n setCurrentPage,\n currentOffset,\n setCurrentOffset,\n initialLoading,\n };\n};\n"],"names":[],"mappings":";;;;;AAaA,MAAM,cAAiB,GAAA,CAAA;AACvB,MAAM,YAAe,GAAA,CAAA;AAEd,MAAM,oBAAuB,GAAA,CAClC,kBACA,EAAA,MAAA,EACA,UACG,KAAA;AACH,EAAM,MAAA,iBAAA,GAAoB,OAAO,oBAAoB,CAAA;AACrD,EAAM,MAAA,CAAC,WAAa,EAAA,cAAc,CAAI,GAAA,QAAA;AAAA,IACpC,YAAY,IAAQ,IAAA;AAAA,GACtB;AACA,EAAM,MAAA,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAA,QAAA;AAAA,IACxC,YAAY,MAAU,IAAA;AAAA,GACxB;AACA,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAAkB,IAAI,CAAA;AAElE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,GACxB,EAAG,CAAC,kBAAkB,CAAC,CAAA;AAEvB,EAAM,MAAA;AAAA,IACJ,KAAO,EAAA,QAAA;AAAA,IACP,OAAS,EAAA,eAAA;AAAA,IACT,KAAO,EAAA;AAAA,GACT,GAAI,SAAS,YAAiC;AAC5C,IAAM,MAAA,IAAA,GAAO,MAAM,iBAAA,CAAkB,oBAAqB,CAAA;AAAA,MACxD,KAAO,EAAA;AAAA,QACL,WAAA,EAAa,SAAU,CAAA,kBAAA,CAAmB,SAAS,CAAA;AAAA,QACnD,GAAG,MAAA;AAAA;AAAA;AAAA,QAGH,MAAM,WAAc,GAAA,CAAA;AAAA,QACpB,MAAQ,EAAA;AAAA;AACV,KACD,CAAA;AAED,IAAA,iBAAA,CAAkB,KAAK,CAAA;AACvB,IAAA,OAAO,KAAK,IAAK,EAAA;AAAA,KAChB,CAAC,kBAAA,EAAoB,MAAQ,EAAA,WAAA,EAAa,aAAa,CAAC,CAAA;AAE3D,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA,eAAA;AAAA,IACA,aAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -1,7 +1,7 @@
1
1
  import { createPlugin, createApiFactory, fetchApiRef, discoveryApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
2
- import { policyReporterApiRef } from './api/PolicyReporterApi.esm.js';
3
- import { PolicyReporterApiClient } from './api/PolicyReporterClient.esm.js';
4
2
  import { rootRouteRef } from './routes.esm.js';
3
+ import { DefaultApiClient } from '@kyverno/backstage-plugin-policy-reporter-common';
4
+ import { policyReporterApiRef } from './api/PolicyReporterClient.esm.js';
5
5
 
6
6
  const policyReporterPlugin = createPlugin({
7
7
  id: "policy-reporter",
@@ -9,7 +9,7 @@ const policyReporterPlugin = createPlugin({
9
9
  createApiFactory({
10
10
  api: policyReporterApiRef,
11
11
  deps: { fetchApi: fetchApiRef, discoveryApi: discoveryApiRef },
12
- factory: ({ discoveryApi, fetchApi }) => new PolicyReporterApiClient({ discoveryApi, fetchApi })
12
+ factory: ({ discoveryApi, fetchApi }) => new DefaultApiClient({ discoveryApi, fetchApi })
13
13
  })
14
14
  ]
15
15
  });
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\nimport { policyReporterApiRef } from './api/PolicyReporterApi';\nimport { PolicyReporterApiClient } from './api/PolicyReporterClient';\n\nimport { rootRouteRef } from './routes';\n\nexport const policyReporterPlugin = createPlugin({\n id: 'policy-reporter',\n apis: [\n createApiFactory({\n api: policyReporterApiRef,\n deps: { fetchApi: fetchApiRef, discoveryApi: discoveryApiRef },\n factory: ({ discoveryApi, fetchApi }) =>\n new PolicyReporterApiClient({ discoveryApi, fetchApi }),\n }),\n ],\n});\n\nexport const EntityKyvernoPoliciesContent = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'EntityKyvernoPoliciesContent',\n component: () =>\n import('./components/EntityKyvernoPoliciesContent').then(\n m => m.EntityKyvernoPoliciesContent,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const EntityCustomPoliciesContent = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'EntityCustomPoliciesContent',\n component: () =>\n import('./components/EntityCustomPoliciesContent').then(\n m => m.EntityCustomPoliciesContent,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const PolicyReportsPage = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'PolicyReportsPage',\n component: () =>\n import('./components/PolicyReportsPage').then(m => m.PolicyReportsPage),\n mountPoint: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":";;;;;AAYO,MAAM,uBAAuB,YAAa,CAAA;AAAA,EAC/C,EAAI,EAAA,iBAAA;AAAA,EACJ,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,oBAAA;AAAA,MACL,IAAM,EAAA,EAAE,QAAU,EAAA,WAAA,EAAa,cAAc,eAAgB,EAAA;AAAA,MAC7D,OAAA,EAAS,CAAC,EAAE,YAAc,EAAA,QAAA,EACxB,KAAA,IAAI,uBAAwB,CAAA,EAAE,YAAc,EAAA,QAAA,EAAU;AAAA,KACzD;AAAA;AAEL,CAAC;AAEM,MAAM,+BAA+B,oBAAqB,CAAA,OAAA;AAAA,EAC/D,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,8BAAA;AAAA,IACN,SAAW,EAAA,MACT,OAAO,wDAA2C,CAAE,CAAA,IAAA;AAAA,MAClD,OAAK,CAAE,CAAA;AAAA,KACT;AAAA,IACF,UAAY,EAAA;AAAA,GACb;AACH;AAEO,MAAM,8BAA8B,oBAAqB,CAAA,OAAA;AAAA,EAC9D,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,6BAAA;AAAA,IACN,SAAW,EAAA,MACT,OAAO,uDAA0C,CAAE,CAAA,IAAA;AAAA,MACjD,OAAK,CAAE,CAAA;AAAA,KACT;AAAA,IACF,UAAY,EAAA;AAAA,GACb;AACH;AAEO,MAAM,oBAAoB,oBAAqB,CAAA,OAAA;AAAA,EACpD,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,mBAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,6CAAgC,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,iBAAiB,CAAA;AAAA,IACxE,UAAY,EAAA;AAAA,GACb;AACH;;;;"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { DefaultApiClient } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { policyReporterApiRef } from './api';\n\nexport const policyReporterPlugin = createPlugin({\n id: 'policy-reporter',\n apis: [\n createApiFactory({\n api: policyReporterApiRef,\n deps: { fetchApi: fetchApiRef, discoveryApi: discoveryApiRef },\n factory: ({ discoveryApi, fetchApi }) =>\n new DefaultApiClient({ discoveryApi, fetchApi }),\n }),\n ],\n});\n\nexport const EntityKyvernoPoliciesContent = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'EntityKyvernoPoliciesContent',\n component: () =>\n import('./components/EntityKyvernoPoliciesContent').then(\n m => m.EntityKyvernoPoliciesContent,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const EntityCustomPoliciesContent = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'EntityCustomPoliciesContent',\n component: () =>\n import('./components/EntityCustomPoliciesContent').then(\n m => m.EntityCustomPoliciesContent,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const PolicyReportsPage = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'PolicyReportsPage',\n component: () =>\n import('./components/PolicyReportsPage').then(m => m.PolicyReportsPage),\n mountPoint: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":";;;;;AAYO,MAAM,uBAAuB,YAAa,CAAA;AAAA,EAC/C,EAAI,EAAA,iBAAA;AAAA,EACJ,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,oBAAA;AAAA,MACL,IAAM,EAAA,EAAE,QAAU,EAAA,WAAA,EAAa,cAAc,eAAgB,EAAA;AAAA,MAC7D,OAAA,EAAS,CAAC,EAAE,YAAc,EAAA,QAAA,EACxB,KAAA,IAAI,gBAAiB,CAAA,EAAE,YAAc,EAAA,QAAA,EAAU;AAAA,KAClD;AAAA;AAEL,CAAC;AAEM,MAAM,+BAA+B,oBAAqB,CAAA,OAAA;AAAA,EAC/D,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,8BAAA;AAAA,IACN,SAAW,EAAA,MACT,OAAO,wDAA2C,CAAE,CAAA,IAAA;AAAA,MAClD,OAAK,CAAE,CAAA;AAAA,KACT;AAAA,IACF,UAAY,EAAA;AAAA,GACb;AACH;AAEO,MAAM,8BAA8B,oBAAqB,CAAA,OAAA;AAAA,EAC9D,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,6BAAA;AAAA,IACN,SAAW,EAAA,MACT,OAAO,uDAA0C,CAAE,CAAA,IAAA;AAAA,MACjD,OAAK,CAAE,CAAA;AAAA,KACT;AAAA,IACF,UAAY,EAAA;AAAA,GACb;AACH;AAEO,MAAM,oBAAoB,oBAAqB,CAAA,OAAA;AAAA,EACpD,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,mBAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,6CAAgC,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,iBAAiB,CAAA;AAAA,IACxE,UAAY,EAAA;AAAA,GACb;AACH;;;;"}
@@ -1,13 +1,31 @@
1
- import { KYVERNO_RESOURCE_NAME_ANNOTATION, KYVERNO_KIND_ANNOTATION, KYVERNO_NAMESPACE_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';
1
+ import { KYVERNO_RESOURCE_NAME_ANNOTATION, KYVERNO_NAMESPACE_ANNOTATION, KUBERNETES_NAMESPACE_ANNOTATION, KYVERNO_KIND_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';
2
2
 
3
- const annotationsRequired = [
4
- KYVERNO_RESOURCE_NAME_ANNOTATION,
5
- KYVERNO_KIND_ANNOTATION,
6
- KYVERNO_NAMESPACE_ANNOTATION
7
- ];
8
- const containsRequiredAnnotations = (annotations) => {
9
- return annotations ? annotationsRequired.every((key) => key in annotations) : false;
3
+ const isPolicyReporterAvailable = (entity) => Boolean(entity.metadata.annotations?.[KYVERNO_RESOURCE_NAME_ANNOTATION]);
4
+ const getNamespaces = (annotations) => {
5
+ if (!annotations) return [];
6
+ if (annotations[KYVERNO_NAMESPACE_ANNOTATION]) {
7
+ return annotations[KYVERNO_NAMESPACE_ANNOTATION].split(",").map(
8
+ (item) => item.trim()
9
+ );
10
+ }
11
+ if (annotations[KUBERNETES_NAMESPACE_ANNOTATION]) {
12
+ return [annotations[KUBERNETES_NAMESPACE_ANNOTATION]];
13
+ }
14
+ return [];
15
+ };
16
+ const getKinds = (annotations) => {
17
+ if (!annotations) return [];
18
+ if (annotations[KYVERNO_KIND_ANNOTATION]) {
19
+ return annotations[KYVERNO_KIND_ANNOTATION].split(",").map(
20
+ (item) => item.trim()
21
+ );
22
+ }
23
+ return [];
24
+ };
25
+ const getResourceName = (annotations) => {
26
+ if (!annotations) return "";
27
+ return annotations[KYVERNO_RESOURCE_NAME_ANNOTATION] || "";
10
28
  };
11
29
 
12
- export { annotationsRequired, containsRequiredAnnotations };
30
+ export { getKinds, getNamespaces, getResourceName, isPolicyReporterAvailable };
13
31
  //# sourceMappingURL=annotations.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"annotations.esm.js","sources":["../../src/utils/annotations.ts"],"sourcesContent":["import {\n KYVERNO_KIND_ANNOTATION,\n KYVERNO_NAMESPACE_ANNOTATION,\n KYVERNO_RESOURCE_NAME_ANNOTATION,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\n\n// Define all annotations required for the component to work\nexport const annotationsRequired: string[] = [\n KYVERNO_RESOURCE_NAME_ANNOTATION,\n KYVERNO_KIND_ANNOTATION,\n KYVERNO_NAMESPACE_ANNOTATION,\n];\n\n// Check annotations object for all required annotations\nexport const containsRequiredAnnotations = (\n annotations: Record<string, string> | undefined,\n): boolean => {\n return annotations\n ? annotationsRequired.every(key => key in annotations)\n : false;\n};\n"],"names":[],"mappings":";;AAOO,MAAM,mBAAgC,GAAA;AAAA,EAC3C,gCAAA;AAAA,EACA,uBAAA;AAAA,EACA;AACF;AAGa,MAAA,2BAAA,GAA8B,CACzC,WACY,KAAA;AACZ,EAAA,OAAO,cACH,mBAAoB,CAAA,KAAA,CAAM,CAAO,GAAA,KAAA,GAAA,IAAO,WAAW,CACnD,GAAA,KAAA;AACN;;;;"}
1
+ {"version":3,"file":"annotations.esm.js","sources":["../../src/utils/annotations.ts"],"sourcesContent":["import { Entity } from '@backstage/catalog-model';\nimport {\n KYVERNO_KIND_ANNOTATION,\n KYVERNO_NAMESPACE_ANNOTATION,\n KYVERNO_RESOURCE_NAME_ANNOTATION,\n KUBERNETES_NAMESPACE_ANNOTATION,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\n\n/**\n * Utility functions for working with Backstage entity annotations\n * specifically for Kyverno policy reporter plugin integration\n */\n\n/**\n * Validates that an annotations object contains all required annotation keys\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @param required - Array of required annotation keys to check for\n * @returns true if all required keys exist in annotations, false otherwise\n */\nexport const containsRequiredAnnotations = (\n annotations: Record<string, string> | undefined,\n required: string[],\n): boolean => {\n return annotations ? required.every(key => key in annotations) : false;\n};\n\n/**\n * Validates that an entity has configured policy reporter\n * @param entity - The the Backstage entity\n * @returns true if policy reporter is configured.\n */\nexport const isPolicyReporterAvailable = (entity: Entity) =>\n Boolean(entity.metadata.annotations?.[KYVERNO_RESOURCE_NAME_ANNOTATION]);\n\n/**\n * Extracts namespace values from annotations, supporting both Kyverno and Kubernetes formats\n * Priority: Kyverno namespace annotation (comma-separated) > Kubernetes namespace annotation (single value)\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @returns Array of namespace strings, empty array if no namespace annotations found\n */\nexport const getNamespaces = (\n annotations: Record<string, string> | undefined,\n): string[] => {\n if (!annotations) return [];\n\n // Check for Kyverno-specific namespace annotation (supports multiple namespaces)\n if (annotations[KYVERNO_NAMESPACE_ANNOTATION]) {\n return annotations[KYVERNO_NAMESPACE_ANNOTATION].split(',').map(item =>\n item.trim(),\n );\n }\n\n // Fall back to standard Kubernetes namespace annotation (single namespace)\n if (annotations[KUBERNETES_NAMESPACE_ANNOTATION]) {\n return [annotations[KUBERNETES_NAMESPACE_ANNOTATION]];\n }\n\n return [];\n};\n\n/**\n * Extracts Kubernetes resource kinds from Kyverno-specific annotation\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @returns Array of Kubernetes resource kind strings (e.g., ['Pod', 'Service']), empty array if not found\n */\nexport const getKinds = (\n annotations: Record<string, string> | undefined,\n): string[] => {\n if (!annotations) return [];\n\n // Parse comma-separated list of Kubernetes resource kinds\n if (annotations[KYVERNO_KIND_ANNOTATION]) {\n return annotations[KYVERNO_KIND_ANNOTATION].split(',').map(item =>\n item.trim(),\n );\n }\n\n return [];\n};\n\n/**\n * Extracts a specific resource name from Kyverno annotation\n * Used to target a particular Kubernetes resource for policy evaluation\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @returns Resource name string, empty string if annotation not found\n */\nexport const getResourceName = (\n annotations: Record<string, string> | undefined,\n): string => {\n if (!annotations) return '';\n\n return annotations[KYVERNO_RESOURCE_NAME_ANNOTATION] || '';\n};\n"],"names":[],"mappings":";;AA+Ba,MAAA,yBAAA,GAA4B,CAAC,MACxC,KAAA,OAAA,CAAQ,OAAO,QAAS,CAAA,WAAA,GAAc,gCAAgC,CAAC;AAQ5D,MAAA,aAAA,GAAgB,CAC3B,WACa,KAAA;AACb,EAAI,IAAA,CAAC,WAAa,EAAA,OAAO,EAAC;AAG1B,EAAI,IAAA,WAAA,CAAY,4BAA4B,CAAG,EAAA;AAC7C,IAAA,OAAO,WAAY,CAAA,4BAA4B,CAAE,CAAA,KAAA,CAAM,GAAG,CAAE,CAAA,GAAA;AAAA,MAAI,CAAA,IAAA,KAC9D,KAAK,IAAK;AAAA,KACZ;AAAA;AAIF,EAAI,IAAA,WAAA,CAAY,+BAA+B,CAAG,EAAA;AAChD,IAAO,OAAA,CAAC,WAAY,CAAA,+BAA+B,CAAC,CAAA;AAAA;AAGtD,EAAA,OAAO,EAAC;AACV;AAOa,MAAA,QAAA,GAAW,CACtB,WACa,KAAA;AACb,EAAI,IAAA,CAAC,WAAa,EAAA,OAAO,EAAC;AAG1B,EAAI,IAAA,WAAA,CAAY,uBAAuB,CAAG,EAAA;AACxC,IAAA,OAAO,WAAY,CAAA,uBAAuB,CAAE,CAAA,KAAA,CAAM,GAAG,CAAE,CAAA,GAAA;AAAA,MAAI,CAAA,IAAA,KACzD,KAAK,IAAK;AAAA,KACZ;AAAA;AAGF,EAAA,OAAO,EAAC;AACV;AAQa,MAAA,eAAA,GAAkB,CAC7B,WACW,KAAA;AACX,EAAI,IAAA,CAAC,aAAoB,OAAA,EAAA;AAEzB,EAAO,OAAA,WAAA,CAAY,gCAAgC,CAAK,IAAA,EAAA;AAC1D;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kyverno/backstage-plugin-policy-reporter",
3
- "version": "2.4.1",
3
+ "version": "2.6.0",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -39,13 +39,13 @@
39
39
  "directory": "plugins/policy-reporter"
40
40
  },
41
41
  "dependencies": {
42
- "@backstage/catalog-client": "^1.10.0",
43
- "@backstage/catalog-model": "^1.7.4",
44
- "@backstage/core-components": "^0.17.2",
45
- "@backstage/core-plugin-api": "^1.10.7",
46
- "@backstage/plugin-catalog-react": "^1.18.0",
47
- "@backstage/theme": "^0.6.6",
48
- "@kyverno/backstage-plugin-policy-reporter-common": "^2.0.7",
42
+ "@backstage/catalog-client": "^1.12.0",
43
+ "@backstage/catalog-model": "^1.7.5",
44
+ "@backstage/core-components": "^0.18.1",
45
+ "@backstage/core-plugin-api": "^1.11.0",
46
+ "@backstage/plugin-catalog-react": "^1.21.1",
47
+ "@backstage/theme": "^0.6.8",
48
+ "@kyverno/backstage-plugin-policy-reporter-common": "^2.2.0",
49
49
  "@material-ui/core": "^4.12.4",
50
50
  "@material-ui/icons": "^4.11.3",
51
51
  "@material-ui/lab": "4.0.0-alpha.61",
@@ -55,10 +55,10 @@
55
55
  "react": "^16.13.1 || ^17.0.0 || ^18.0.0"
56
56
  },
57
57
  "devDependencies": {
58
- "@backstage/cli": "^0.32.1",
59
- "@backstage/core-app-api": "^1.17.0",
60
- "@backstage/dev-utils": "^1.1.10",
61
- "@backstage/test-utils": "^1.7.8",
58
+ "@backstage/cli": "^0.34.3",
59
+ "@backstage/core-app-api": "^1.19.0",
60
+ "@backstage/dev-utils": "^1.1.14",
61
+ "@backstage/test-utils": "^1.7.11",
62
62
  "@testing-library/jest-dom": "^6.0.0",
63
63
  "@testing-library/react": "^14.0.0",
64
64
  "@testing-library/user-event": "^14.0.0",
@@ -1,8 +0,0 @@
1
- import { createApiRef } from '@backstage/core-plugin-api';
2
-
3
- const policyReporterApiRef = createApiRef({
4
- id: "plugin.policy-reporter.service"
5
- });
6
-
7
- export { policyReporterApiRef };
8
- //# sourceMappingURL=PolicyReporterApi.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PolicyReporterApi.esm.js","sources":["../../src/api/PolicyReporterApi.ts"],"sourcesContent":["import { createApiRef } from '@backstage/core-plugin-api';\nimport {\n Filter,\n Pagination,\n ResultList,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\n\nexport const policyReporterApiRef = createApiRef<PolicyReporterApi>({\n id: 'plugin.policy-reporter.service',\n});\n\nexport type PolicyReporterApi = {\n namespacedResults: (\n environment: string,\n filter?: Filter,\n pagination?: Pagination,\n ) => Promise<ResultList>;\n};\n"],"names":[],"mappings":";;AAOO,MAAM,uBAAuB,YAAgC,CAAA;AAAA,EAClE,EAAI,EAAA;AACN,CAAC;;;;"}