Merge pull request #4210 from backstage/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-4.14.0

chore(deps): bump @typescript-eslint/eslint-plugin from 3.10.1 to 4.14.0
This commit is contained in:
Ben Lambert
2021-01-25 12:55:05 +01:00
committed by GitHub
19 changed files with 558 additions and 570 deletions
@@ -43,67 +43,6 @@ type DeploymentsAccordionsProps = {
children?: React.ReactNode;
};
export const DeploymentsAccordions = ({
deploymentResources,
clusterPodNamesWithErrors,
}: DeploymentsAccordionsProps) => {
const isOwnedBy = (
ownerReferences: V1OwnerReference[],
obj: V1Pod | V1ReplicaSet | V1Deployment,
): boolean => {
return ownerReferences?.some(or => or.name === obj.metadata?.name);
};
return (
<Grid
container
direction="column"
justify="flex-start"
alignItems="flex-start"
>
{deploymentResources.deployments.map((deployment, i) => (
<Grid container item key={i} xs>
{deploymentResources.replicaSets
// Filter out replica sets with no replicas
.filter(rs => rs.status && rs.status.replicas > 0)
// Find the replica sets this deployment owns
.filter(rs =>
isOwnedBy(rs.metadata?.ownerReferences ?? [], deployment),
)
.map((rs, j) => {
// Find the pods this replica set owns and render them in the table
const ownedPods = deploymentResources.pods.filter(pod =>
isOwnedBy(pod.metadata?.ownerReferences ?? [], rs),
);
const matchingHpa = deploymentResources.horizontalPodAutoscalers.find(
(hpa: V1HorizontalPodAutoscaler) => {
return (
(hpa.spec?.scaleTargetRef?.kind ?? '').toLowerCase() ===
'deployment' &&
(hpa.spec?.scaleTargetRef?.name ?? '') ===
(deployment.metadata?.name ?? 'unknown-deployment')
);
},
);
return (
<Grid item key={j} xs>
<DeploymentAccordion
deployment={deployment}
ownedPods={ownedPods}
matchingHpa={matchingHpa}
clusterPodNamesWithErrors={clusterPodNamesWithErrors}
/>
</Grid>
);
})}
</Grid>
))}
</Grid>
);
};
type DeploymentAccordionProps = {
deployment: V1Deployment;
ownedPods: V1Pod[];
@@ -112,33 +51,6 @@ type DeploymentAccordionProps = {
children?: React.ReactNode;
};
const DeploymentAccordion = ({
deployment,
ownedPods,
matchingHpa,
clusterPodNamesWithErrors,
}: DeploymentAccordionProps) => {
const podsWithErrors = ownedPods.filter(p =>
clusterPodNamesWithErrors.has(p.metadata?.name ?? ''),
);
return (
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<DeploymentSummary
deployment={deployment}
numberOfCurrentPods={ownedPods.length}
numberOfPodsWithErrors={podsWithErrors.length}
hpa={matchingHpa}
/>
</AccordionSummary>
<AccordionDetails>
<PodsTable pods={ownedPods} />
</AccordionDetails>
</Accordion>
);
};
type DeploymentSummaryProps = {
deployment: V1Deployment;
numberOfCurrentPods: number;
@@ -219,3 +131,91 @@ const DeploymentSummary = ({
</Grid>
);
};
const DeploymentAccordion = ({
deployment,
ownedPods,
matchingHpa,
clusterPodNamesWithErrors,
}: DeploymentAccordionProps) => {
const podsWithErrors = ownedPods.filter(p =>
clusterPodNamesWithErrors.has(p.metadata?.name ?? ''),
);
return (
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<DeploymentSummary
deployment={deployment}
numberOfCurrentPods={ownedPods.length}
numberOfPodsWithErrors={podsWithErrors.length}
hpa={matchingHpa}
/>
</AccordionSummary>
<AccordionDetails>
<PodsTable pods={ownedPods} />
</AccordionDetails>
</Accordion>
);
};
export const DeploymentsAccordions = ({
deploymentResources,
clusterPodNamesWithErrors,
}: DeploymentsAccordionsProps) => {
const isOwnedBy = (
ownerReferences: V1OwnerReference[],
obj: V1Pod | V1ReplicaSet | V1Deployment,
): boolean => {
return ownerReferences?.some(or => or.name === obj.metadata?.name);
};
return (
<Grid
container
direction="column"
justify="flex-start"
alignItems="flex-start"
>
{deploymentResources.deployments.map((deployment, i) => (
<Grid container item key={i} xs>
{deploymentResources.replicaSets
// Filter out replica sets with no replicas
.filter(rs => rs.status && rs.status.replicas > 0)
// Find the replica sets this deployment owns
.filter(rs =>
isOwnedBy(rs.metadata?.ownerReferences ?? [], deployment),
)
.map((rs, j) => {
// Find the pods this replica set owns and render them in the table
const ownedPods = deploymentResources.pods.filter(pod =>
isOwnedBy(pod.metadata?.ownerReferences ?? [], rs),
);
const matchingHpa = deploymentResources.horizontalPodAutoscalers.find(
(hpa: V1HorizontalPodAutoscaler) => {
return (
(hpa.spec?.scaleTargetRef?.kind ?? '').toLowerCase() ===
'deployment' &&
(hpa.spec?.scaleTargetRef?.name ?? '') ===
(deployment.metadata?.name ?? 'unknown-deployment')
);
},
);
return (
<Grid item key={j} xs>
<DeploymentAccordion
deployment={deployment}
ownedPods={ownedPods}
matchingHpa={matchingHpa}
clusterPodNamesWithErrors={clusterPodNamesWithErrors}
/>
</Grid>
);
})}
</Grid>
))}
</Grid>
);
};
@@ -86,29 +86,6 @@ const sortBySeverity = (a: DetectedError, b: DetectedError) => {
return 0;
};
export const ErrorReporting = ({ detectedErrors }: ErrorReportingProps) => {
const errors = Array.from(detectedErrors.values())
.flat()
.sort(sortBySeverity);
return (
<>
{errors.length === 0 ? (
<InfoCard title="Error Reporting">
<ErrorEmptyState />
</InfoCard>
) : (
<Table
title="Error Reporting"
data={errors}
columns={columns}
options={{ paging: true, search: false }}
/>
)}
</>
);
};
export const ErrorEmptyState = () => {
return (
<Grid
@@ -133,3 +110,26 @@ export const ErrorEmptyState = () => {
</Grid>
);
};
export const ErrorReporting = ({ detectedErrors }: ErrorReportingProps) => {
const errors = Array.from(detectedErrors.values())
.flat()
.sort(sortBySeverity);
return (
<>
{errors.length === 0 ? (
<InfoCard title="Error Reporting">
<ErrorEmptyState />
</InfoCard>
) : (
<Table
title="Error Reporting"
data={errors}
columns={columns}
options={{ paging: true, search: false }}
/>
)}
</>
);
};
@@ -32,42 +32,10 @@ type IngressesAccordionsProps = {
deploymentResources: GroupedResponses;
};
export const IngressesAccordions = ({
deploymentResources,
}: IngressesAccordionsProps) => {
return (
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
>
{deploymentResources.ingresses.map((ingress, i) => (
<Grid item key={i} xs>
<IngressAccordion ingress={ingress} />
</Grid>
))}
</Grid>
);
};
type IngressAccordionProps = {
ingress: ExtensionsV1beta1Ingress;
};
const IngressAccordion = ({ ingress }: IngressAccordionProps) => {
return (
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<IngressSummary ingress={ingress} />
</AccordionSummary>
<AccordionDetails>
<IngressCard ingress={ingress} />
</AccordionDetails>
</Accordion>
);
};
type IngressSummaryProps = {
ingress: ExtensionsV1beta1Ingress;
};
@@ -99,3 +67,34 @@ const IngressCard = ({ ingress }: IngressCardProps) => {
/>
);
};
const IngressAccordion = ({ ingress }: IngressAccordionProps) => {
return (
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<IngressSummary ingress={ingress} />
</AccordionSummary>
<AccordionDetails>
<IngressCard ingress={ingress} />
</AccordionDetails>
</Accordion>
);
};
export const IngressesAccordions = ({
deploymentResources,
}: IngressesAccordionsProps) => {
return (
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
>
{deploymentResources.ingresses.map((ingress, i) => (
<Grid item key={i} xs>
<IngressAccordion ingress={ingress} />
</Grid>
))}
</Grid>
);
};
@@ -50,6 +50,115 @@ import { DetectedError, detectErrors } from '../../error-detection';
import { IngressesAccordions } from '../IngressesAccordions';
import { ServicesAccordions } from '../ServicesAccordions';
type ClusterSummaryProps = {
clusterName: string;
totalNumberOfPods: number;
numberOfPodsWithErrors: number;
children?: React.ReactNode;
};
const ClusterSummary = ({
clusterName,
totalNumberOfPods,
numberOfPodsWithErrors,
}: ClusterSummaryProps) => {
return (
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
>
<Grid
xs={2}
item
direction="column"
justify="flex-start"
alignItems="flex-start"
spacing={0}
>
<Grid item xs>
<Typography variant="h3">{clusterName}</Typography>
<Typography color="textSecondary" variant="body1">
Cluster
</Typography>
</Grid>
</Grid>
<Grid item xs={1}>
<Divider style={{ height: '4em' }} orientation="vertical" />
</Grid>
<Grid
item
container
xs={3}
direction="column"
justify="flex-start"
alignItems="flex-start"
>
<Grid item>
<StatusOK>{totalNumberOfPods} pods</StatusOK>
</Grid>
<Grid item>
{numberOfPodsWithErrors > 0 ? (
<StatusError>{numberOfPodsWithErrors} pods with errors</StatusError>
) : (
<StatusOK>No pods with errors</StatusOK>
)}
</Grid>
</Grid>
</Grid>
);
};
type ClusterProps = {
clusterObjects: ClusterObjects;
detectedErrors?: DetectedError[];
children?: React.ReactNode;
};
const Cluster = ({ clusterObjects, detectedErrors }: ClusterProps) => {
const groupedResponses = groupResponses(clusterObjects.resources);
const podsWithErrors = new Set<string>(
detectedErrors
?.filter(de => de.kind === 'Pod')
.map(de => de.names)
.flat() ?? [],
);
return (
<>
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<ClusterSummary
clusterName={clusterObjects.cluster.name}
totalNumberOfPods={groupedResponses.pods.length}
numberOfPodsWithErrors={podsWithErrors.size}
/>
</AccordionSummary>
<AccordionDetails>
<Grid container direction="column">
<Grid item>
<DeploymentsAccordions
deploymentResources={groupedResponses}
clusterPodNamesWithErrors={podsWithErrors}
/>
</Grid>
<Grid item>
<IngressesAccordions deploymentResources={groupedResponses} />
</Grid>
<Grid item>
<ServicesAccordions deploymentResources={groupedResponses} />
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
</>
);
};
type KubernetesContentProps = { entity: Entity; children?: React.ReactNode };
export const KubernetesContent = ({ entity }: KubernetesContentProps) => {
@@ -161,112 +270,3 @@ export const KubernetesContent = ({ entity }: KubernetesContentProps) => {
</Page>
);
};
type ClusterProps = {
clusterObjects: ClusterObjects;
detectedErrors?: DetectedError[];
children?: React.ReactNode;
};
const Cluster = ({ clusterObjects, detectedErrors }: ClusterProps) => {
const groupedResponses = groupResponses(clusterObjects.resources);
const podsWithErrors = new Set<string>(
detectedErrors
?.filter(de => de.kind === 'Pod')
.map(de => de.names)
.flat() ?? [],
);
return (
<>
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<ClusterSummary
clusterName={clusterObjects.cluster.name}
totalNumberOfPods={groupedResponses.pods.length}
numberOfPodsWithErrors={podsWithErrors.size}
/>
</AccordionSummary>
<AccordionDetails>
<Grid container direction="column">
<Grid item>
<DeploymentsAccordions
deploymentResources={groupedResponses}
clusterPodNamesWithErrors={podsWithErrors}
/>
</Grid>
<Grid item>
<IngressesAccordions deploymentResources={groupedResponses} />
</Grid>
<Grid item>
<ServicesAccordions deploymentResources={groupedResponses} />
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
</>
);
};
type ClusterSummaryProps = {
clusterName: string;
totalNumberOfPods: number;
numberOfPodsWithErrors: number;
children?: React.ReactNode;
};
const ClusterSummary = ({
clusterName,
totalNumberOfPods,
numberOfPodsWithErrors,
}: ClusterSummaryProps) => {
return (
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
>
<Grid
xs={2}
item
direction="column"
justify="flex-start"
alignItems="flex-start"
spacing={0}
>
<Grid item xs>
<Typography variant="h3">{clusterName}</Typography>
<Typography color="textSecondary" variant="body1">
Cluster
</Typography>
</Grid>
</Grid>
<Grid item xs={1}>
<Divider style={{ height: '4em' }} orientation="vertical" />
</Grid>
<Grid
item
container
xs={3}
direction="column"
justify="flex-start"
alignItems="flex-start"
>
<Grid item>
<StatusOK>{totalNumberOfPods} pods</StatusOK>
</Grid>
<Grid item>
{numberOfPodsWithErrors > 0 ? (
<StatusError>{numberOfPodsWithErrors} pods with errors</StatusError>
) : (
<StatusOK>No pods with errors</StatusOK>
)}
</Grid>
</Grid>
</Grid>
);
};
@@ -77,65 +77,6 @@ interface KubernetesDrawerable {
metadata?: V1ObjectMeta;
}
interface KubernetesDrawerProps<T extends KubernetesDrawerable> {
object: T;
renderObject: (obj: T) => object;
buttonVariant?: 'h5' | 'subtitle2';
kind: string;
expanded?: boolean;
children?: React.ReactNode;
}
export const KubernetesDrawer = <T extends KubernetesDrawerable>({
object,
renderObject,
kind,
buttonVariant = 'subtitle2',
expanded = false,
children,
}: KubernetesDrawerProps<T>) => {
const [isOpen, setIsOpen] = useState(expanded);
const classes = useDrawerStyles();
const toggleDrawer = (e: ChangeEvent<{}>, newValue: boolean) => {
e.stopPropagation();
setIsOpen(newValue);
};
return (
<>
<PodDrawerButton
onClick={e => toggleDrawer(e, true)}
onFocus={event => event.stopPropagation()}
>
{children === undefined ? (
<Typography variant={buttonVariant}>
{object.metadata?.name ?? 'unknown object'}
</Typography>
) : (
children
)}
</PodDrawerButton>
<Drawer
classes={{
paper: classes.paper,
}}
anchor="right"
open={isOpen}
onClose={(e: any) => toggleDrawer(e, false)}
onClick={event => event.stopPropagation()}
>
<KubernetesDrawerContent
kind={kind}
toggleDrawer={toggleDrawer}
object={object}
renderObject={renderObject}
/>
</Drawer>
</>
);
};
interface KubernetesDrawerContentProps<T extends KubernetesDrawerable> {
toggleDrawer: (e: ChangeEvent<{}>, isOpen: boolean) => void;
object: T;
@@ -203,3 +144,61 @@ const KubernetesDrawerContent = <T extends KubernetesDrawerable>({
</>
);
};
interface KubernetesDrawerProps<T extends KubernetesDrawerable> {
object: T;
renderObject: (obj: T) => object;
buttonVariant?: 'h5' | 'subtitle2';
kind: string;
expanded?: boolean;
children?: React.ReactNode;
}
export const KubernetesDrawer = <T extends KubernetesDrawerable>({
object,
renderObject,
kind,
buttonVariant = 'subtitle2',
expanded = false,
children,
}: KubernetesDrawerProps<T>) => {
const [isOpen, setIsOpen] = useState(expanded);
const classes = useDrawerStyles();
const toggleDrawer = (e: ChangeEvent<{}>, newValue: boolean) => {
e.stopPropagation();
setIsOpen(newValue);
};
return (
<>
<PodDrawerButton
onClick={e => toggleDrawer(e, true)}
onFocus={event => event.stopPropagation()}
>
{children === undefined ? (
<Typography variant={buttonVariant}>
{object.metadata?.name ?? 'unknown object'}
</Typography>
) : (
children
)}
</PodDrawerButton>
<Drawer
classes={{
paper: classes.paper,
}}
anchor="right"
open={isOpen}
onClose={(e: any) => toggleDrawer(e, false)}
onClick={event => event.stopPropagation()}
>
<KubernetesDrawerContent
kind={kind}
toggleDrawer={toggleDrawer}
object={object}
renderObject={renderObject}
/>
</Drawer>
</>
);
};
@@ -29,46 +29,6 @@ import { V1Service } from '@kubernetes/client-node';
import { StructuredMetadataTable } from '@backstage/core';
import { ServiceDrawer } from './ServiceDrawer';
type ServicesAccordionsProps = {
deploymentResources: GroupedResponses;
};
export const ServicesAccordions = ({
deploymentResources,
}: ServicesAccordionsProps) => {
return (
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
>
{deploymentResources.services.map((service, i) => (
<Grid item key={i} xs>
<ServiceAccordion service={service} />
</Grid>
))}
</Grid>
);
};
type ServiceAccordionProps = {
service: V1Service;
};
const ServiceAccordion = ({ service }: ServiceAccordionProps) => {
return (
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<ServiceSummary service={service} />
</AccordionSummary>
<AccordionDetails>
<ServiceCard service={service} />
</AccordionDetails>
</Accordion>
);
};
type ServiceSummaryProps = {
service: V1Service;
};
@@ -121,3 +81,43 @@ const ServiceCard = ({ service }: ServiceCardProps) => {
/>
);
};
type ServicesAccordionsProps = {
deploymentResources: GroupedResponses;
};
type ServiceAccordionProps = {
service: V1Service;
};
const ServiceAccordion = ({ service }: ServiceAccordionProps) => {
return (
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<ServiceSummary service={service} />
</AccordionSummary>
<AccordionDetails>
<ServiceCard service={service} />
</AccordionDetails>
</Accordion>
);
};
export const ServicesAccordions = ({
deploymentResources,
}: ServicesAccordionsProps) => {
return (
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
>
{deploymentResources.services.map((service, i) => (
<Grid item key={i} xs>
<ServiceAccordion service={service} />
</Grid>
))}
</Grid>
);
};