Show kubernetes ingresses

This commit is contained in:
Kévin Gomez
2021-01-13 23:50:09 +01:00
parent d014185dbd
commit da9e5eb4b9
8 changed files with 313 additions and 1 deletions
+2 -1
View File
@@ -2,4 +2,5 @@
'@backstage/plugin-kubernetes': patch
---
Show Kubernetes Service manifests
Show Kubernetes Service manifests.
Show Kubernetes Ingress manifests.
@@ -0,0 +1,38 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { render } from '@testing-library/react';
import * as ingresses from './__fixtures__/2-ingresses.json';
import { wrapInTestApp } from '@backstage/test-utils';
import { IngressDrawer } from './IngressDrawer';
describe('IngressDrawer', () => {
it('should render ingress drawer', async () => {
const { getByText, getAllByText } = render(
wrapInTestApp(
<IngressDrawer ingress={(ingresses as any).ingresses[0]} expanded />,
),
);
expect(getAllByText('awesome-service')).toHaveLength(2);
expect(getByText('YAML')).toBeInTheDocument();
expect(getByText('Rules')).toBeInTheDocument();
expect(getByText('Host: api.awesome-host.io')).toBeInTheDocument();
expect(getAllByText('Service Port: 80')).toHaveLength(2);
expect(getAllByText('Service Name: awesome-service')).toHaveLength(2);
});
});
@@ -0,0 +1,60 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { ExtensionsV1beta1Ingress } from '@kubernetes/client-node';
import { KubernetesDrawer } from '../KubernetesDrawer/KubernetesDrawer';
import { Typography, Grid } from '@material-ui/core';
export const IngressDrawer = ({
ingress,
expanded,
}: {
ingress: ExtensionsV1beta1Ingress;
expanded?: boolean;
}) => {
return (
<KubernetesDrawer
object={ingress}
expanded={expanded}
kind="Ingress"
renderObject={(ingress: ExtensionsV1beta1Ingress) => {
return {
...ingress.spec,
};
}}
>
<Grid
container
direction="column"
justify="flex-start"
alignItems="flex-start"
spacing={0}
>
<Grid item>
<Typography variant="h5">
{ingress.metadata?.name ?? 'unknown object'}
</Typography>
</Grid>
<Grid item>
<Typography color="textSecondary" variant="body1">
Ingress
</Typography>
</Grid>
</Grid>
</KubernetesDrawer>
);
};
@@ -0,0 +1,34 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { render } from '@testing-library/react';
import * as oneIngressFixture from './__fixtures__/2-ingresses.json';
import { wrapInTestApp } from '@backstage/test-utils';
import { IngressesAccordions } from './IngressesAccordions';
describe('IngressesAccordions', () => {
it('should render 1 ingress', async () => {
const { getByText } = render(
wrapInTestApp(
<IngressesAccordions deploymentResources={oneIngressFixture as any} />,
),
);
expect(getByText('awesome-service')).toBeInTheDocument();
expect(getByText('Ingress')).toBeInTheDocument();
});
});
@@ -0,0 +1,101 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { GroupedResponses } from '../../types/types';
import React from 'react';
import {
Accordion,
AccordionDetails,
AccordionSummary,
Divider,
Grid,
} from '@material-ui/core';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { ExtensionsV1beta1Ingress } from '@kubernetes/client-node';
import { StructuredMetadataTable } from '@backstage/core';
import { IngressDrawer } from './IngressDrawer';
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;
};
const IngressSummary = ({ ingress }: IngressSummaryProps) => {
return (
<Grid container direction="row" justify="flex-start" alignItems="center">
<Grid xs={3} item>
<IngressDrawer ingress={ingress} />
</Grid>
<Grid item xs={1}>
<Divider style={{ height: '5em' }} orientation="vertical" />
</Grid>
</Grid>
);
};
type IngressCardProps = {
ingress: ExtensionsV1beta1Ingress;
};
const IngressCard = ({ ingress }: IngressCardProps) => {
return (
<StructuredMetadataTable
metadata={{
...ingress.spec,
}}
/>
);
};
@@ -0,0 +1,57 @@
{
"ingresses": [
{
"metadata": {
"annotations": {
"artifact.spinnaker.io/location": "default",
"artifact.spinnaker.io/name": "awesome-service",
"artifact.spinnaker.io/type": "kubernetes/ingress",
"kubernetes.io/ingress.class": "traefik",
"kubernetes.io/ingress.global-static-ip-name": "traefik-tcp-lb",
"moniker.spinnaker.io/application": "awesome-service",
"moniker.spinnaker.io/cluster": "ingress awesome-service"
},
"creationTimestamp": "2018-11-16T14:00:13.000Z",
"generation": 11,
"labels": {
"app": "awesome-service",
"app.kubernetes.io/managed-by": "spinnaker",
"app.kubernetes.io/name": "awesome-service"
},
"name": "awesome-service",
"namespace": "default",
"resourceVersion": "564824116",
"selfLink": "/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/awesome-service",
"uid": "f072e0b4-e9a7-11e8-af65-42010a9c0022"
},
"spec": {
"rules": [
{
"host": "api.awesome-host.io",
"http": {
"paths": [
{
"backend": {
"serviceName": "awesome-service",
"servicePort": 80
},
"path": "/v1/awesome-service"
},
{
"backend": {
"serviceName": "awesome-service",
"servicePort": 80
},
"path": "/v1/awesome-services"
}
]
}
}
]
},
"status": {
"loadBalancer": {}
}
}
]
}
@@ -0,0 +1,16 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { IngressesAccordions } from './IngressesAccordions';
@@ -47,6 +47,7 @@ import { DeploymentsAccordions } from '../DeploymentsAccordions';
import { ErrorReporting } from '../ErrorReporting';
import { groupResponses } from '../../utils/response';
import { DetectedError, detectErrors } from '../../error-detection';
import { IngressesAccordions } from '../IngressesAccordions';
import { ServicesAccordions } from '../ServicesAccordions';
type KubernetesContentProps = { entity: Entity; children?: React.ReactNode };
@@ -196,6 +197,10 @@ const Cluster = ({ clusterObjects, detectedErrors }: ClusterProps) => {
/>
</Grid>
<Grid item>
<IngressesAccordions deploymentResources={groupedResponses} />
</Grid>
<Grid item>
<ServicesAccordions deploymentResources={groupedResponses} />
</Grid>