diff --git a/.changeset/olive-zebras-itch.md b/.changeset/olive-zebras-itch.md index 5e67673e8c..6a12e35c87 100644 --- a/.changeset/olive-zebras-itch.md +++ b/.changeset/olive-zebras-itch.md @@ -2,4 +2,5 @@ '@backstage/plugin-kubernetes': patch --- -Show Kubernetes Service manifests +Show Kubernetes Service manifests. +Show Kubernetes Ingress manifests. diff --git a/plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.test.tsx b/plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.test.tsx new file mode 100644 index 0000000000..cf37eb3e79 --- /dev/null +++ b/plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.test.tsx @@ -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( + , + ), + ); + + 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); + }); +}); diff --git a/plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.tsx b/plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.tsx new file mode 100644 index 0000000000..2fbccf7968 --- /dev/null +++ b/plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.tsx @@ -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 ( + { + return { + ...ingress.spec, + }; + }} + > + + + + {ingress.metadata?.name ?? 'unknown object'} + + + + + Ingress + + + + + ); +}; diff --git a/plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.test.tsx b/plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.test.tsx new file mode 100644 index 0000000000..580561095e --- /dev/null +++ b/plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.test.tsx @@ -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( + , + ), + ); + + expect(getByText('awesome-service')).toBeInTheDocument(); + expect(getByText('Ingress')).toBeInTheDocument(); + }); +}); diff --git a/plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.tsx b/plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.tsx new file mode 100644 index 0000000000..a49f966ffd --- /dev/null +++ b/plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.tsx @@ -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 ( + + {deploymentResources.ingresses.map((ingress, i) => ( + + + + ))} + + ); +}; + +type IngressAccordionProps = { + ingress: ExtensionsV1beta1Ingress; +}; + +const IngressAccordion = ({ ingress }: IngressAccordionProps) => { + return ( + + }> + + + + + + + ); +}; + +type IngressSummaryProps = { + ingress: ExtensionsV1beta1Ingress; +}; + +const IngressSummary = ({ ingress }: IngressSummaryProps) => { + return ( + + + + + + + + + + ); +}; + +type IngressCardProps = { + ingress: ExtensionsV1beta1Ingress; +}; + +const IngressCard = ({ ingress }: IngressCardProps) => { + return ( + + ); +}; diff --git a/plugins/kubernetes/src/components/IngressesAccordions/__fixtures__/2-ingresses.json b/plugins/kubernetes/src/components/IngressesAccordions/__fixtures__/2-ingresses.json new file mode 100644 index 0000000000..136c70697d --- /dev/null +++ b/plugins/kubernetes/src/components/IngressesAccordions/__fixtures__/2-ingresses.json @@ -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": {} + } + } + ] +} diff --git a/plugins/kubernetes/src/components/IngressesAccordions/index.ts b/plugins/kubernetes/src/components/IngressesAccordions/index.ts new file mode 100644 index 0000000000..a71f53fac7 --- /dev/null +++ b/plugins/kubernetes/src/components/IngressesAccordions/index.ts @@ -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'; diff --git a/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx index 9716616009..092ada0724 100644 --- a/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx +++ b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx @@ -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) => { /> + + + +