@kyverno/backstage-plugin-policy-reporter 2.0.1 → 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.
- package/README.md +100 -0
- package/dist/components/PolicyReportsDrawerComponent/PolicyReportsDrawerComponent.esm.js +62 -0
- package/dist/components/PolicyReportsDrawerComponent/PolicyReportsDrawerComponent.esm.js.map +1 -0
- package/dist/components/PolicyReportsTable/PolicyReportsTable.esm.js +22 -4
- package/dist/components/PolicyReportsTable/PolicyReportsTable.esm.js.map +1 -1
- package/package.json +16 -11
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# backstage-policy-reporter-plugin
|
|
2
|
+
|
|
3
|
+
The Frontend for the Policy Reporter plugin
|
|
4
|
+
|
|
5
|
+
This plugin integrates [Policy Reporter](https://kyverno.github.io/policy-reporter/) with Backstage to provide a clear and detailed view of Kyverno Policies applied to your entities
|
|
6
|
+
|
|
7
|
+
The [Backend](https://www.npmjs.com/package/@kyverno/backstage-plugin-policy-reporter-backend?activeTab=readme) plugin is required for this plugin to work
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add the plugin to your frontend app
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
yarn --cwd packages/app add @kyverno/backstage-plugin-policy-reporter
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Add the **EntityKyvernoPoliciesContent** component to the Entity routes in `packages/app/src/components/catalog/EntityPage.tsx`
|
|
18
|
+
|
|
19
|
+
```diff
|
|
20
|
+
|
|
21
|
+
+ import { EntityKyvernoPoliciesContent } from '@kyverno/backstage-plugin-policy-reporter';
|
|
22
|
+
|
|
23
|
+
const serviceEntityPage = (
|
|
24
|
+
|
|
25
|
+
<EntityLayout>
|
|
26
|
+
|
|
27
|
+
// ...
|
|
28
|
+
|
|
29
|
+
+ <EntityLayout.Route path="/kyverno" title="kyverno policy">
|
|
30
|
+
+ <EntityKyvernoPoliciesContent />
|
|
31
|
+
+ </EntityLayout.Route>
|
|
32
|
+
|
|
33
|
+
// ..
|
|
34
|
+
|
|
35
|
+
</EntityLayout>
|
|
36
|
+
)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Configuration
|
|
40
|
+
|
|
41
|
+
### Define Kubernetes Clusters
|
|
42
|
+
|
|
43
|
+
In your Backstage instance, define your Kubernetes clusters using the `Resource` kind and `kubernetes-cluster` type. Add the `kyverno.io/endpoint` annotation with the URL to the Policy Reporter API for each cluster.
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
apiVersion: backstage.io/v1alpha1
|
|
47
|
+
kind: Resource
|
|
48
|
+
metadata:
|
|
49
|
+
name: aks-dev
|
|
50
|
+
annotations:
|
|
51
|
+
# Add the Policy Reporter API endpoint as an annotation
|
|
52
|
+
kyverno.io/endpoint: http://kyverno.io/policy-reporter/api/
|
|
53
|
+
spec:
|
|
54
|
+
type: kubernetes-cluster
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Annotate Services
|
|
58
|
+
|
|
59
|
+
To show the policies on the service, add a dependency to the Kubernetes cluster resource in the `catalog-info.yaml` file of your service. Ensure that the necessary annotations are added as well. For more details, refer to the [How to annotate services](../../README.md#how-to-annotate-services) section.
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
metadata:
|
|
63
|
+
annotations:
|
|
64
|
+
kyverno.io/namespace: default # Specify the namespace of the service
|
|
65
|
+
kyverno.io/kind: Deployment,Pod # Specify the kind(s) of the Kubernetes resource(s)
|
|
66
|
+
kyverno.io/resource-name: policy-reporter # Specify the name of the resource
|
|
67
|
+
spec:
|
|
68
|
+
dependsOn:
|
|
69
|
+
# Add dependency to all environments the service is deployed to using the Resource entityRef
|
|
70
|
+
- resource:default/aks-dev
|
|
71
|
+
- resource:default/aks-tst
|
|
72
|
+
- resource:default/aks-qa
|
|
73
|
+
- resource:default/aks-prd
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Customization
|
|
77
|
+
|
|
78
|
+
To configure the plugin to make the policy Chip a link to custom documentation, follow the steps below.
|
|
79
|
+
|
|
80
|
+
To enable policy Chip links, the **EntityKyvernoPolicyReportsContent** component requires the **policyDocumentationUrl** prop to be set to the URL of the documentation.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const serviceEntityPage = (
|
|
84
|
+
<EntityLayout>
|
|
85
|
+
// ...
|
|
86
|
+
<EntityLayout.Route path="/kyverno" title="kyverno policy">
|
|
87
|
+
<EntityKyvernoPoliciesContent policyDocumentationUrl="Your full URL link" />
|
|
88
|
+
</EntityLayout.Route>
|
|
89
|
+
// ..
|
|
90
|
+
</EntityLayout>
|
|
91
|
+
);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The policy documentation file provided in the above step needs to follow a specific structure.
|
|
95
|
+
|
|
96
|
+
All policies being used should have a header that matches the exact same name as the policy. Under this header, you can add information about the policy and provide a guide on how to solve it.
|
|
97
|
+
|
|
98
|
+
The plugin will create a link using the following format: `<DocumentationUrl>#<PolicyName>`
|
|
99
|
+
|
|
100
|
+
See the [example/policy-documentation.md](../../example/policy-documentation.md) file for an example of how this could look.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { makeStyles, Paper, Box, Typography, Card, CardHeader, CardContent, Grid, Divider } from '@material-ui/core';
|
|
3
|
+
import { SeverityComponent } from '../SeverityComponent/SeverityComponent.esm.js';
|
|
4
|
+
import { StatusComponent } from '../StatusComponent/StatusComponent.esm.js';
|
|
5
|
+
|
|
6
|
+
const useStyles = makeStyles((theme) => ({
|
|
7
|
+
root: {
|
|
8
|
+
marginBottom: theme.spacing(2)
|
|
9
|
+
},
|
|
10
|
+
sectionTitle: {
|
|
11
|
+
marginBottom: theme.spacing(1),
|
|
12
|
+
fontWeight: 500
|
|
13
|
+
},
|
|
14
|
+
propertyLabel: {
|
|
15
|
+
color: theme.palette.text.secondary,
|
|
16
|
+
fontWeight: 500
|
|
17
|
+
},
|
|
18
|
+
propertyValue: {
|
|
19
|
+
textAlign: "right"
|
|
20
|
+
},
|
|
21
|
+
propertyContainer: {
|
|
22
|
+
marginBottom: theme.spacing(1),
|
|
23
|
+
display: "flex",
|
|
24
|
+
justifyContent: "space-between"
|
|
25
|
+
},
|
|
26
|
+
divider: {
|
|
27
|
+
margin: theme.spacing(2, 0)
|
|
28
|
+
},
|
|
29
|
+
message: {
|
|
30
|
+
padding: theme.spacing(2),
|
|
31
|
+
backgroundColor: theme.palette.grey[50],
|
|
32
|
+
borderRadius: theme.shape.borderRadius,
|
|
33
|
+
color: "black"
|
|
34
|
+
},
|
|
35
|
+
propertiesContainer: {
|
|
36
|
+
padding: theme.spacing(2),
|
|
37
|
+
backgroundColor: theme.palette.grey[50],
|
|
38
|
+
borderRadius: theme.shape.borderRadius
|
|
39
|
+
},
|
|
40
|
+
propertyItem: {
|
|
41
|
+
display: "flex",
|
|
42
|
+
justifyContent: "space-between",
|
|
43
|
+
borderBottom: `1px solid ${theme.palette.divider}`,
|
|
44
|
+
padding: theme.spacing(1, 0),
|
|
45
|
+
"&:last-child": {
|
|
46
|
+
borderBottom: "none"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}));
|
|
50
|
+
const PolicyReportsDrawerComponent = ({
|
|
51
|
+
content
|
|
52
|
+
}) => {
|
|
53
|
+
const classes = useStyles();
|
|
54
|
+
if (!content) {
|
|
55
|
+
return /* @__PURE__ */ React.createElement(Paper, { className: classes.root }, /* @__PURE__ */ React.createElement(Box, { p: 2 }, /* @__PURE__ */ React.createElement(Typography, { variant: "body1", color: "textSecondary" }, "No policy information available")));
|
|
56
|
+
}
|
|
57
|
+
const formattedDate = new Date(content.timestamp * 1e3).toLocaleString();
|
|
58
|
+
return /* @__PURE__ */ React.createElement(Card, { className: classes.root, "data-testid": "policy-reports-drawer" }, /* @__PURE__ */ React.createElement(CardHeader, { title: "Policy Details" }), /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(Typography, { variant: "h6", className: classes.sectionTitle }, "General Information"), /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 2 }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, md: 6 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "ID"), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyValue }, content.id))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, md: 6 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "Name"), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyValue }, content.name))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, md: 6 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "Namespace"), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyValue }, content.namespace))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, md: 6 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "Kind"), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyValue }, content.kind))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, md: 6 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "Resource ID"), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyValue }, content.resourceId))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, md: 6 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "Timestamp"), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyValue }, formattedDate)))), /* @__PURE__ */ React.createElement(Divider, { className: classes.divider }), /* @__PURE__ */ React.createElement(Typography, { variant: "h6", className: classes.sectionTitle }, "Status Information"), /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 2 }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, md: 6 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "Status"), /* @__PURE__ */ React.createElement(StatusComponent, { status: content.status }))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, md: 6 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "Severity"), /* @__PURE__ */ React.createElement(SeverityComponent, { severity: content.severity })))), /* @__PURE__ */ React.createElement(Divider, { className: classes.divider }), /* @__PURE__ */ React.createElement(Typography, { variant: "h6", className: classes.sectionTitle }, "Policy Information"), /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 2 }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "Policy"), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyValue }, content.policy))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Box, { className: classes.propertyContainer }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, "Rule"), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyValue }, content.rule)))), /* @__PURE__ */ React.createElement(Divider, { className: classes.divider }), /* @__PURE__ */ React.createElement(Typography, { variant: "h6", className: classes.sectionTitle }, "Message"), /* @__PURE__ */ React.createElement(Paper, { elevation: 0, className: classes.message }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, content.message)), content.properties && Object.keys(content.properties).length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Divider, { className: classes.divider }), /* @__PURE__ */ React.createElement(Typography, { variant: "h6", className: classes.sectionTitle }, "Additional Properties"), /* @__PURE__ */ React.createElement(Paper, { elevation: 0, className: classes.propertiesContainer }, Object.entries(content.properties).map(([key, value]) => /* @__PURE__ */ React.createElement(Box, { key, className: classes.propertyItem }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.propertyLabel }, key), /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, value)))))));
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export { PolicyReportsDrawerComponent };
|
|
62
|
+
//# sourceMappingURL=PolicyReportsDrawerComponent.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PolicyReportsDrawerComponent.esm.js","sources":["../../../src/components/PolicyReportsDrawerComponent/PolicyReportsDrawerComponent.tsx"],"sourcesContent":["import { ListResult } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport React from 'react';\nimport {\n Card,\n CardHeader,\n CardContent,\n Typography,\n Divider,\n Grid,\n Box,\n Paper,\n makeStyles,\n} from '@material-ui/core';\nimport { SeverityComponent } from '../SeverityComponent';\nimport { StatusComponent } from '../StatusComponent';\n\ninterface PolicyReportsDrawerProps {\n content: ListResult | undefined;\n}\n\n// Material-UI styles\nconst useStyles = makeStyles(theme => ({\n root: {\n marginBottom: theme.spacing(2),\n },\n sectionTitle: {\n marginBottom: theme.spacing(1),\n fontWeight: 500,\n },\n propertyLabel: {\n color: theme.palette.text.secondary,\n fontWeight: 500,\n },\n propertyValue: {\n textAlign: 'right',\n },\n propertyContainer: {\n marginBottom: theme.spacing(1),\n display: 'flex',\n justifyContent: 'space-between',\n },\n divider: {\n margin: theme.spacing(2, 0),\n },\n message: {\n padding: theme.spacing(2),\n backgroundColor: theme.palette.grey[50],\n borderRadius: theme.shape.borderRadius,\n color: 'black',\n },\n propertiesContainer: {\n padding: theme.spacing(2),\n backgroundColor: theme.palette.grey[50],\n borderRadius: theme.shape.borderRadius,\n },\n propertyItem: {\n display: 'flex',\n justifyContent: 'space-between',\n borderBottom: `1px solid ${theme.palette.divider}`,\n padding: theme.spacing(1, 0),\n '&:last-child': {\n borderBottom: 'none',\n },\n },\n}));\n\nexport const PolicyReportsDrawerComponent = ({\n content,\n}: PolicyReportsDrawerProps) => {\n const classes = useStyles();\n\n if (!content) {\n return (\n <Paper className={classes.root}>\n <Box p={2}>\n <Typography variant=\"body1\" color=\"textSecondary\">\n No policy information available\n </Typography>\n </Box>\n </Paper>\n );\n }\n\n // Format timestamp to readable date\n const formattedDate = new Date(content.timestamp * 1000).toLocaleString();\n\n return (\n <Card className={classes.root} data-testid=\"policy-reports-drawer\">\n <CardHeader title=\"Policy Details\" />\n <CardContent>\n {/* General Information */}\n <Typography variant=\"h6\" className={classes.sectionTitle}>\n General Information\n </Typography>\n <Grid container spacing={2}>\n <Grid item xs={12} md={6}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n ID\n </Typography>\n <Typography variant=\"body2\" className={classes.propertyValue}>\n {content.id}\n </Typography>\n </Box>\n </Grid>\n <Grid item xs={12} md={6}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n Name\n </Typography>\n <Typography variant=\"body2\" className={classes.propertyValue}>\n {content.name}\n </Typography>\n </Box>\n </Grid>\n <Grid item xs={12} md={6}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n Namespace\n </Typography>\n <Typography variant=\"body2\" className={classes.propertyValue}>\n {content.namespace}\n </Typography>\n </Box>\n </Grid>\n <Grid item xs={12} md={6}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n Kind\n </Typography>\n <Typography variant=\"body2\" className={classes.propertyValue}>\n {content.kind}\n </Typography>\n </Box>\n </Grid>\n <Grid item xs={12} md={6}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n Resource ID\n </Typography>\n <Typography variant=\"body2\" className={classes.propertyValue}>\n {content.resourceId}\n </Typography>\n </Box>\n </Grid>\n <Grid item xs={12} md={6}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n Timestamp\n </Typography>\n <Typography variant=\"body2\" className={classes.propertyValue}>\n {formattedDate}\n </Typography>\n </Box>\n </Grid>\n </Grid>\n\n <Divider className={classes.divider} />\n\n {/* Status Information */}\n <Typography variant=\"h6\" className={classes.sectionTitle}>\n Status Information\n </Typography>\n <Grid container spacing={2}>\n <Grid item xs={12} md={6}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n Status\n </Typography>\n <StatusComponent status={content.status} />\n </Box>\n </Grid>\n <Grid item xs={12} md={6}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n Severity\n </Typography>\n <SeverityComponent severity={content.severity} />\n </Box>\n </Grid>\n </Grid>\n\n <Divider className={classes.divider} />\n\n {/* Policy Information */}\n <Typography variant=\"h6\" className={classes.sectionTitle}>\n Policy Information\n </Typography>\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n Policy\n </Typography>\n <Typography variant=\"body2\" className={classes.propertyValue}>\n {content.policy}\n </Typography>\n </Box>\n </Grid>\n <Grid item xs={12}>\n <Box className={classes.propertyContainer}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n Rule\n </Typography>\n <Typography variant=\"body2\" className={classes.propertyValue}>\n {content.rule}\n </Typography>\n </Box>\n </Grid>\n </Grid>\n\n <Divider className={classes.divider} />\n\n {/* Message */}\n <Typography variant=\"h6\" className={classes.sectionTitle}>\n Message\n </Typography>\n <Paper elevation={0} className={classes.message}>\n <Typography variant=\"body2\">{content.message}</Typography>\n </Paper>\n\n {/* Additional Properties */}\n {content.properties && Object.keys(content.properties).length > 0 && (\n <>\n <Divider className={classes.divider} />\n <Typography variant=\"h6\" className={classes.sectionTitle}>\n Additional Properties\n </Typography>\n <Paper elevation={0} className={classes.propertiesContainer}>\n {Object.entries(content.properties).map(([key, value]) => (\n <Box key={key} className={classes.propertyItem}>\n <Typography variant=\"body2\" className={classes.propertyLabel}>\n {key}\n </Typography>\n <Typography variant=\"body2\">{value}</Typography>\n </Box>\n ))}\n </Paper>\n </>\n )}\n </CardContent>\n </Card>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ResponseErrorPanel, Table } from '@backstage/core-components';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { makeStyles } from '@material-ui/core';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { makeStyles, Drawer } from '@material-ui/core';
|
|
4
4
|
import Chip from '@material-ui/core/Chip';
|
|
5
5
|
import { StatusComponent } from '../StatusComponent/StatusComponent.esm.js';
|
|
6
6
|
import { SeverityComponent } from '../SeverityComponent/SeverityComponent.esm.js';
|
|
7
7
|
import Launch from '@material-ui/icons/Launch';
|
|
8
8
|
import { usePaginatedPolicies } from '../../hooks/usePaginatedPolicies.esm.js';
|
|
9
|
+
import { PolicyReportsDrawerComponent } from '../PolicyReportsDrawerComponent/PolicyReportsDrawerComponent.esm.js';
|
|
9
10
|
|
|
10
11
|
const PolicyReportsTable = ({
|
|
11
12
|
title,
|
|
@@ -21,6 +22,10 @@ const PolicyReportsTable = ({
|
|
|
21
22
|
justifyContent: "center"
|
|
22
23
|
}
|
|
23
24
|
}));
|
|
25
|
+
const [showDrawer, setShowDrawer] = useState(false);
|
|
26
|
+
const [drawerContent, setDrawerContent] = useState(
|
|
27
|
+
void 0
|
|
28
|
+
);
|
|
24
29
|
const classes = useStyles();
|
|
25
30
|
const columns = [
|
|
26
31
|
{
|
|
@@ -98,13 +103,26 @@ const PolicyReportsTable = ({
|
|
|
98
103
|
title
|
|
99
104
|
}
|
|
100
105
|
);
|
|
101
|
-
return /* @__PURE__ */ React.createElement(
|
|
106
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
107
|
+
Drawer,
|
|
108
|
+
{
|
|
109
|
+
anchor: "right",
|
|
110
|
+
open: showDrawer,
|
|
111
|
+
onClose: () => setShowDrawer(false)
|
|
112
|
+
},
|
|
113
|
+
/* @__PURE__ */ React.createElement(PolicyReportsDrawerComponent, { content: drawerContent })
|
|
114
|
+
), /* @__PURE__ */ React.createElement(
|
|
102
115
|
Table,
|
|
103
116
|
{
|
|
104
117
|
options: {
|
|
105
118
|
sorting: true,
|
|
106
119
|
padding: "dense"
|
|
107
120
|
},
|
|
121
|
+
onRowClick: (event, rowData) => {
|
|
122
|
+
event?.preventDefault();
|
|
123
|
+
setShowDrawer(true);
|
|
124
|
+
setDrawerContent(rowData);
|
|
125
|
+
},
|
|
108
126
|
data: policies?.items ?? [],
|
|
109
127
|
columns,
|
|
110
128
|
title,
|
|
@@ -114,7 +132,7 @@ const PolicyReportsTable = ({
|
|
|
114
132
|
onPageChange: (page) => setCurrentPage(page),
|
|
115
133
|
emptyContent: /* @__PURE__ */ React.createElement("div", { className: classes.empty }, emptyContentText)
|
|
116
134
|
}
|
|
117
|
-
);
|
|
135
|
+
));
|
|
118
136
|
};
|
|
119
137
|
|
|
120
138
|
export { PolicyReportsTable };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PolicyReportsTable.esm.js","sources":["../../../src/components/PolicyReportsTable/PolicyReportsTable.tsx"],"sourcesContent":["import {\n ResponseErrorPanel,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport React from 'react';\nimport {\n Filter,\n ListResult,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { makeStyles } from '@material-ui/core';\nimport Chip from '@material-ui/core/Chip';\nimport { StatusComponent } from '../StatusComponent';\nimport { SeverityComponent } from '../SeverityComponent';\nimport Launch from '@material-ui/icons/Launch';\nimport { Environment } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { usePaginatedPolicies } from '../../hooks/usePaginatedPolicies';\n\ninterface PolicyReportsTableProps {\n currentEnvironment: Environment;\n filter: Filter;\n title: string;\n emptyContentText: string;\n policyDocumentationUrl?: string;\n}\n\nexport const PolicyReportsTable = ({\n title,\n emptyContentText,\n currentEnvironment,\n filter,\n policyDocumentationUrl,\n}: PolicyReportsTableProps) => {\n const useStyles = makeStyles(theme => ({\n empty: {\n padding: theme.spacing(2),\n display: 'flex',\n justifyContent: 'center',\n },\n }));\n\n const classes = useStyles();\n\n const columns: TableColumn<ListResult>[] = [\n {\n title: 'name',\n field: 'name',\n },\n {\n title: 'namespace',\n field: 'namespace',\n },\n {\n title: 'kind',\n field: 'kind',\n },\n {\n title: 'policy',\n field: 'policy',\n render: (listResult: ListResult) => {\n // When policyDocumentationUrl is provided create link to the Policy section\n if (policyDocumentationUrl)\n return (\n <Chip\n label={listResult.policy}\n component=\"a\"\n target=\"_blank\"\n href={`${policyDocumentationUrl}#${listResult.policy}`}\n clickable\n icon={<Launch fontSize=\"small\" />}\n />\n );\n\n return <Chip label={listResult.policy} />;\n },\n },\n {\n title: 'rule',\n field: 'rule',\n render: (listResult: ListResult) => {\n return <Chip label={listResult.rule} />;\n },\n },\n {\n title: 'status',\n field: 'status',\n width: '30',\n render: (listResult: ListResult) => {\n return <StatusComponent status={listResult.status} />;\n },\n },\n {\n title: 'severity',\n field: 'severity',\n width: '30',\n render: (listResult: ListResult) => {\n return <SeverityComponent severity={listResult.severity} />;\n },\n },\n ];\n\n const {\n policies,\n policiesError,\n currentPage,\n setCurrentPage,\n setCurrentOffset,\n initialLoading,\n } = usePaginatedPolicies(currentEnvironment, filter);\n\n if (policiesError) return <ResponseErrorPanel error={policiesError} />;\n\n // Return loading table\n if (initialLoading)\n return (\n <Table\n options={{ paging: false, padding: 'dense' }}\n data={[]}\n columns={columns}\n isLoading\n title={title}\n />\n );\n\n return (\n <Table\n
|
|
1
|
+
{"version":3,"file":"PolicyReportsTable.esm.js","sources":["../../../src/components/PolicyReportsTable/PolicyReportsTable.tsx"],"sourcesContent":["import {\n ResponseErrorPanel,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport React, { useState } from 'react';\nimport {\n Filter,\n ListResult,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { Drawer, makeStyles } from '@material-ui/core';\nimport Chip from '@material-ui/core/Chip';\nimport { StatusComponent } from '../StatusComponent';\nimport { SeverityComponent } from '../SeverityComponent';\nimport Launch from '@material-ui/icons/Launch';\nimport { Environment } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { usePaginatedPolicies } from '../../hooks/usePaginatedPolicies';\nimport { PolicyReportsDrawerComponent } from '../PolicyReportsDrawerComponent/PolicyReportsDrawerComponent';\n\ninterface PolicyReportsTableProps {\n currentEnvironment: Environment;\n filter: Filter;\n title: string;\n emptyContentText: string;\n policyDocumentationUrl?: string;\n}\n\nexport const PolicyReportsTable = ({\n title,\n emptyContentText,\n currentEnvironment,\n filter,\n policyDocumentationUrl,\n}: PolicyReportsTableProps) => {\n const useStyles = makeStyles(theme => ({\n empty: {\n padding: theme.spacing(2),\n display: 'flex',\n justifyContent: 'center',\n },\n }));\n\n const [showDrawer, setShowDrawer] = useState<boolean>(false);\n const [drawerContent, setDrawerContent] = useState<ListResult | undefined>(\n undefined,\n );\n const classes = useStyles();\n\n const columns: TableColumn<ListResult>[] = [\n {\n title: 'name',\n field: 'name',\n },\n {\n title: 'namespace',\n field: 'namespace',\n },\n {\n title: 'kind',\n field: 'kind',\n },\n {\n title: 'policy',\n field: 'policy',\n render: (listResult: ListResult) => {\n // When policyDocumentationUrl is provided create link to the Policy section\n if (policyDocumentationUrl)\n return (\n <Chip\n label={listResult.policy}\n component=\"a\"\n target=\"_blank\"\n href={`${policyDocumentationUrl}#${listResult.policy}`}\n clickable\n icon={<Launch fontSize=\"small\" />}\n />\n );\n\n return <Chip label={listResult.policy} />;\n },\n },\n {\n title: 'rule',\n field: 'rule',\n render: (listResult: ListResult) => {\n return <Chip label={listResult.rule} />;\n },\n },\n {\n title: 'status',\n field: 'status',\n width: '30',\n render: (listResult: ListResult) => {\n return <StatusComponent status={listResult.status} />;\n },\n },\n {\n title: 'severity',\n field: 'severity',\n width: '30',\n render: (listResult: ListResult) => {\n return <SeverityComponent severity={listResult.severity} />;\n },\n },\n ];\n\n const {\n policies,\n policiesError,\n currentPage,\n setCurrentPage,\n setCurrentOffset,\n initialLoading,\n } = usePaginatedPolicies(currentEnvironment, filter);\n\n if (policiesError) return <ResponseErrorPanel error={policiesError} />;\n\n // Return loading table\n if (initialLoading)\n return (\n <Table\n options={{ paging: false, padding: 'dense' }}\n data={[]}\n columns={columns}\n isLoading\n title={title}\n />\n );\n\n return (\n <>\n <Drawer\n anchor=\"right\"\n open={showDrawer}\n onClose={() => setShowDrawer(false)}\n >\n <PolicyReportsDrawerComponent content={drawerContent} />\n </Drawer>\n <Table\n options={{\n sorting: true,\n padding: 'dense',\n }}\n onRowClick={(\n event?: React.MouseEvent<Element, MouseEvent>,\n rowData?: ListResult,\n ) => {\n event?.preventDefault();\n setShowDrawer(true);\n setDrawerContent(rowData);\n }}\n data={policies?.items ?? []}\n columns={columns}\n title={title}\n totalCount={policies?.count}\n page={currentPage}\n onRowsPerPageChange={page => setCurrentOffset(page)}\n onPageChange={page => setCurrentPage(page)}\n emptyContent={<div className={classes.empty}>{emptyContentText}</div>}\n />\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kyverno/backstage-plugin-policy-reporter",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"main": "dist/index.esm.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"backstage",
|
|
9
|
+
"kyverno",
|
|
10
|
+
"policy-reporter"
|
|
11
|
+
],
|
|
7
12
|
"backstage": {
|
|
8
13
|
"role": "frontend-plugin",
|
|
9
14
|
"pluginId": "policy-reporter",
|
|
@@ -36,11 +41,11 @@
|
|
|
36
41
|
"dependencies": {
|
|
37
42
|
"@backstage/catalog-client": "^1.9.1",
|
|
38
43
|
"@backstage/catalog-model": "^1.7.3",
|
|
39
|
-
"@backstage/core-components": "^0.16.
|
|
40
|
-
"@backstage/core-plugin-api": "^1.10.
|
|
41
|
-
"@backstage/plugin-catalog-react": "^1.15.
|
|
42
|
-
"@backstage/theme": "^0.6.
|
|
43
|
-
"@kyverno/backstage-plugin-policy-reporter-common": "^2.0.
|
|
44
|
+
"@backstage/core-components": "^0.16.4",
|
|
45
|
+
"@backstage/core-plugin-api": "^1.10.4",
|
|
46
|
+
"@backstage/plugin-catalog-react": "^1.15.2",
|
|
47
|
+
"@backstage/theme": "^0.6.4",
|
|
48
|
+
"@kyverno/backstage-plugin-policy-reporter-common": "^2.0.3",
|
|
44
49
|
"@material-ui/core": "^4.9.13",
|
|
45
50
|
"@material-ui/icons": "^4.9.1",
|
|
46
51
|
"@material-ui/lab": "4.0.0-alpha.61",
|
|
@@ -50,10 +55,10 @@
|
|
|
50
55
|
"react": "^16.13.1 || ^17.0.0 || ^18.0.0"
|
|
51
56
|
},
|
|
52
57
|
"devDependencies": {
|
|
53
|
-
"@backstage/cli": "^0.
|
|
54
|
-
"@backstage/core-app-api": "^1.15.
|
|
55
|
-
"@backstage/dev-utils": "^1.1.
|
|
56
|
-
"@backstage/test-utils": "^1.7.
|
|
58
|
+
"@backstage/cli": "^0.30.0",
|
|
59
|
+
"@backstage/core-app-api": "^1.15.5",
|
|
60
|
+
"@backstage/dev-utils": "^1.1.7",
|
|
61
|
+
"@backstage/test-utils": "^1.7.5",
|
|
57
62
|
"@testing-library/jest-dom": "^6.0.0",
|
|
58
63
|
"@testing-library/react": "^14.0.0",
|
|
59
64
|
"@testing-library/user-event": "^14.0.0",
|
|
@@ -62,7 +67,7 @@
|
|
|
62
67
|
"files": [
|
|
63
68
|
"dist"
|
|
64
69
|
],
|
|
65
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "f16449996db64192842fa919e25dd9439258fab6",
|
|
66
71
|
"typesVersions": {
|
|
67
72
|
"*": {
|
|
68
73
|
"index": [
|