Show kubernetes services
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
---
|
||||
|
||||
Show Kubernetes Service manifests
|
||||
@@ -47,6 +47,7 @@ import { DeploymentsAccordions } from '../DeploymentsAccordions';
|
||||
import { ErrorReporting } from '../ErrorReporting';
|
||||
import { groupResponses } from '../../utils/response';
|
||||
import { DetectedError, detectErrors } from '../../error-detection';
|
||||
import { ServicesAccordions } from '../ServicesAccordions';
|
||||
|
||||
type KubernetesContentProps = { entity: Entity; children?: React.ReactNode };
|
||||
|
||||
@@ -187,10 +188,18 @@ const Cluster = ({ clusterObjects, detectedErrors }: ClusterProps) => {
|
||||
/>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<DeploymentsAccordions
|
||||
deploymentResources={groupedResponses}
|
||||
clusterPodNamesWithErrors={podsWithErrors}
|
||||
/>
|
||||
<Grid container direction="column">
|
||||
<Grid item>
|
||||
<DeploymentsAccordions
|
||||
deploymentResources={groupedResponses}
|
||||
clusterPodNamesWithErrors={podsWithErrors}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid item>
|
||||
<ServicesAccordions deploymentResources={groupedResponses} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 services from './__fixtures__/2-services.json';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { ServiceDrawer } from './ServiceDrawer';
|
||||
|
||||
describe('ServiceDrawer', () => {
|
||||
it('should render deployment drawer', async () => {
|
||||
const { getByText, getAllByText } = render(
|
||||
wrapInTestApp(
|
||||
<ServiceDrawer service={(services as any).services[0]} expanded />,
|
||||
),
|
||||
);
|
||||
|
||||
expect(getAllByText('awesome-service-grpc')).toHaveLength(2);
|
||||
expect(getAllByText('Service')).toHaveLength(2);
|
||||
expect(getByText('YAML')).toBeInTheDocument();
|
||||
expect(getByText('Cluster IP')).toBeInTheDocument();
|
||||
expect(getByText('Ports')).toBeInTheDocument();
|
||||
expect(getByText('Target Port: 1997')).toBeInTheDocument();
|
||||
expect(getByText('App: awesome-service')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -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 { V1Service } from '@kubernetes/client-node';
|
||||
import { KubernetesDrawer } from '../KubernetesDrawer/KubernetesDrawer';
|
||||
import { Typography, Grid } from '@material-ui/core';
|
||||
|
||||
export const ServiceDrawer = ({
|
||||
service,
|
||||
expanded,
|
||||
}: {
|
||||
service: V1Service;
|
||||
expanded?: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<KubernetesDrawer
|
||||
object={service}
|
||||
expanded={expanded}
|
||||
kind="Service"
|
||||
renderObject={(service: V1Service) => {
|
||||
return {
|
||||
...service.spec,
|
||||
};
|
||||
}}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
justify="flex-start"
|
||||
alignItems="flex-start"
|
||||
spacing={0}
|
||||
>
|
||||
<Grid item>
|
||||
<Typography variant="h5">
|
||||
{service.metadata?.name ?? 'unknown object'}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Typography color="textSecondary" variant="body1">
|
||||
Service
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</KubernetesDrawer>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 twoDeployFixture from './__fixtures__/2-services.json';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { ServicesAccordions } from './ServicesAccordions';
|
||||
|
||||
describe('ServicesAccordions', () => {
|
||||
it('should render 2 services', async () => {
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(
|
||||
<ServicesAccordions deploymentResources={twoDeployFixture as any} />,
|
||||
),
|
||||
);
|
||||
|
||||
expect(getByText('awesome-service-grpc')).toBeInTheDocument();
|
||||
expect(getByText('Type: ClusterIP')).toBeInTheDocument();
|
||||
|
||||
expect(getByText('awesome-service-pg')).toBeInTheDocument();
|
||||
expect(getByText('Type: ExternalName')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||
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;
|
||||
};
|
||||
|
||||
const ServiceSummary = ({ service }: ServiceSummaryProps) => {
|
||||
return (
|
||||
<Grid container direction="row" justify="flex-start" alignItems="center">
|
||||
<Grid xs={3} item>
|
||||
<ServiceDrawer service={service} />
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={1}>
|
||||
<Divider style={{ height: '5em' }} orientation="vertical" />
|
||||
</Grid>
|
||||
|
||||
<Grid item>
|
||||
<Typography variant="subtitle2">
|
||||
Type: {service.spec?.type ?? '?'}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
type ServiceCardProps = {
|
||||
service: V1Service;
|
||||
};
|
||||
|
||||
const ServiceCard = ({ service }: ServiceCardProps) => {
|
||||
const metadata: any = {};
|
||||
|
||||
if (service.status?.loadBalancer?.ingress?.length ?? -1 > 0) {
|
||||
metadata.loadbalancer = service.status?.loadBalancer;
|
||||
}
|
||||
|
||||
if (service.spec?.type === 'ClusterIP') {
|
||||
metadata.clusterIP = service.spec.clusterIP;
|
||||
}
|
||||
if (service.spec?.type === 'ExternalName') {
|
||||
metadata.externalName = service.spec.externalName;
|
||||
}
|
||||
|
||||
return (
|
||||
<StructuredMetadataTable
|
||||
metadata={{
|
||||
type: service.spec?.type,
|
||||
ports: service.spec?.ports,
|
||||
...metadata,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"services": [
|
||||
{
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"artifact.spinnaker.io/location": "default",
|
||||
"artifact.spinnaker.io/name": "awesome-service-grpc",
|
||||
"artifact.spinnaker.io/type": "kubernetes/service",
|
||||
"moniker.spinnaker.io/application": "awesome-service",
|
||||
"moniker.spinnaker.io/cluster": "service awesome-service-grpc"
|
||||
},
|
||||
"creationTimestamp": "2021-01-04T16:35:04.000Z",
|
||||
"labels": {
|
||||
"app": "awesome-service",
|
||||
"app.kubernetes.io/managed-by": "spinnaker",
|
||||
"app.kubernetes.io/name": "awesome-service"
|
||||
},
|
||||
"name": "awesome-service-grpc",
|
||||
"namespace": "default",
|
||||
"resourceVersion": "548901649",
|
||||
"selfLink": "/api/v1/namespaces/default/services/awesome-service-grpc",
|
||||
"uid": "461cdcd7-8c61-4125-91f9-e03d745f2f2c"
|
||||
},
|
||||
"spec": {
|
||||
"clusterIP": "None",
|
||||
"ports": [
|
||||
{
|
||||
"name": "grpc",
|
||||
"port": 1997,
|
||||
"protocol": "TCP",
|
||||
"targetPort": 1997
|
||||
}
|
||||
],
|
||||
"selector": {
|
||||
"app": "awesome-service"
|
||||
},
|
||||
"sessionAffinity": "None",
|
||||
"type": "ClusterIP"
|
||||
},
|
||||
"status": {
|
||||
"loadBalancer": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"artifact.spinnaker.io/location": "default",
|
||||
"artifact.spinnaker.io/name": "awesome-service-pg",
|
||||
"artifact.spinnaker.io/type": "kubernetes/service",
|
||||
"moniker.spinnaker.io/application": "awesome-service",
|
||||
"moniker.spinnaker.io/cluster": "service awesome-service-pg"
|
||||
},
|
||||
"creationTimestamp": "2021-01-04T16:35:02.000Z",
|
||||
"labels": {
|
||||
"app": "awesome-service",
|
||||
"app.kubernetes.io/managed-by": "spinnaker",
|
||||
"app.kubernetes.io/name": "awesome-service"
|
||||
},
|
||||
"name": "awesome-service-pg",
|
||||
"namespace": "default",
|
||||
"resourceVersion": "548901625",
|
||||
"selfLink": "/api/v1/namespaces/default/services/awesome-service-pg",
|
||||
"uid": "7d7ff8f2-6caa-4888-ae55-b6d41833ab92"
|
||||
},
|
||||
"spec": {
|
||||
"externalName": "10.244.0.5",
|
||||
"ports": [
|
||||
{
|
||||
"name": "pg",
|
||||
"port": 5432,
|
||||
"protocol": "TCP",
|
||||
"targetPort": 5432
|
||||
}
|
||||
],
|
||||
"sessionAffinity": "None",
|
||||
"type": "ExternalName"
|
||||
},
|
||||
"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 { ServicesAccordions } from './ServicesAccordions';
|
||||
Reference in New Issue
Block a user