Skip to content

Commit

Permalink
feat: add deployment and stateful set resource viewers (#84)
Browse files Browse the repository at this point in the history
This change adds the Deployment and Stateful Set resource viewers.
  • Loading branch information
ChristopherFry committed Jul 28, 2022
1 parent 029a910 commit c456a8c
Show file tree
Hide file tree
Showing 7 changed files with 319 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import React from 'react';
import { getApplyReplacementsStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/applyReplacements';
import { getClusterIssuerStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/clusterIssuer';
import { getConfigMapStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/configMap';
import { getDeploymentStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/deployment';
import { getIngressStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/ingress';
import { getKptfileStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/kptfile';
import { getPersistentVolumeClaimStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/persistentVolumeClaim';
Expand All @@ -27,6 +28,7 @@ import { getRoleBindingStructuredMetadata } from './FirstClassViewers/Structured
import { getServiceStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/service';
import { getSetLabelsStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/setLabels';
import { getStarlarkRunStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/starlarkRun';
import { getStatefulSetStructuredMetadata } from './FirstClassViewers/StructuredMetadata/resources/statefulSet';
import {
CustomMetadataFn,
StructuredMetadata,
Expand All @@ -44,6 +46,12 @@ const getCustomMetadataFn = (
groupVersionKind: string,
): CustomMetadataFn | undefined => {
switch (groupVersionKind) {
case 'apps/v1/Deployment':
return getDeploymentStructuredMetadata;

case 'apps/v1/StatefulSet':
return getStatefulSetStructuredMetadata;

case 'cert-manager.io/v1/ClusterIssuer':
return getClusterIssuerStructuredMetadata;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright 2022 Google LLC
*
* 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 { Deployment } from '../../../../../../types/Deployment';
import { KubernetesResource } from '../../../../../../types/KubernetesResource';
import { Metadata } from '../StructuredMetadata';
import { getPodTemplatedStructuredMetadata } from './podTemplate';

export const getDeploymentStructuredMetadata = (
resource: KubernetesResource,
): Metadata => {
const deployment = resource as Deployment;

const podMetadata: Metadata = getPodTemplatedStructuredMetadata(
deployment.spec.template,
);

return {
replicas: deployment.spec.replicas,
serviceAccountName: deployment.spec.template.spec.serviceAccountName,
...podMetadata,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Copyright 2022 Google LLC
*
* 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 {
ContainerPort,
PodTemplateSpec,
VolumeMount,
} from '../../../../../../types/Pod';
import { Metadata } from '../StructuredMetadata';

export const getPodTemplatedStructuredMetadata = (
podTemplate: PodTemplateSpec,
): Metadata => {
const customMetadata: Metadata = {
serviceAccountName: podTemplate.spec.serviceAccountName,
podLabels: podTemplate.metadata.labels,
podAnnotations: podTemplate.metadata.annotations,
};

const getPortDescription = (port: ContainerPort): string =>
`exposes ${port.protocol || 'TCP'} port ${port.containerPort} ${
port.name ? `as ${port.name}` : ''
}`;

const getVolumeMountDescription = (volumeMount: VolumeMount): string =>
`${volumeMount.mountPath}${volumeMount.name} volume ${
volumeMount.readOnly ? '(readonly)' : ''
}`;

const templateContainers = podTemplate.spec.containers;
for (const [index, container] of templateContainers.entries()) {
const name =
templateContainers.length > 1 ? `container${index + 1}` : 'container';

const containerDetails: string[] = [
`name: ${container.name}`,
`image: ${container.image}`,
...(container.ports ?? []).map(getPortDescription),
...(container.volumeMounts ?? []).map(getVolumeMountDescription),
];

customMetadata[name] = containerDetails;
}

const volumes = podTemplate.spec.volumes ?? [];
for (const [index, volume] of volumes.entries()) {
const name = volumes.length > 1 ? `volume${index + 1}` : 'volume';

const volumeSource = (): string => {
if (volume.configMap) {
return `${volume.configMap.name} config map`;
}
if (volume.persistentVolumeClaim) {
return `${volume.persistentVolumeClaim?.claimName} persistent volume claim`;
}
return '';
};

const volumeDescription = `${volume.name}${volumeSource()}`;

customMetadata[name] = volumeDescription;
}

return customMetadata;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright 2022 Google LLC
*
* 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 { KubernetesResource } from '../../../../../../types/KubernetesResource';
import { StatefulSet } from '../../../../../../types/StatefulSet';
import { Metadata } from '../StructuredMetadata';
import { getPersistentVolumeClaimStructuredMetadata } from './persistentVolumeClaim';
import { getPodTemplatedStructuredMetadata } from './podTemplate';

export const getStatefulSetStructuredMetadata = (
resource: KubernetesResource,
): Metadata => {
const statefulSet = resource as StatefulSet;

const podMetadata: Metadata = getPodTemplatedStructuredMetadata(
statefulSet.spec.template,
);

const volumeClaimMetadata: Metadata = {};

const volumeClaimTemplates = statefulSet.spec.volumeClaimTemplates ?? [];
for (const [index, volumeClaim] of volumeClaimTemplates.entries()) {
const name =
volumeClaimTemplates.length > 1
? `volumeClaim${index + 1}`
: `volumeClaim`;

volumeClaimMetadata[name] =
getPersistentVolumeClaimStructuredMetadata(volumeClaim).volumeClaim;
}

return {
replicas: statefulSet.spec.replicas,
serviceName: statefulSet.spec.serviceName,
serviceAccountName: statefulSet.spec.template.spec.serviceAccountName,
...podMetadata,
...volumeClaimMetadata,
};
};
37 changes: 37 additions & 0 deletions plugins/cad/src/types/Deployment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright 2022 Google LLC
*
* 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 { KubernetesKeyValueObject } from './KubernetesResource';
import { PodTemplateSpec } from './Pod';

export type Deployment = {
apiVersion: string;
kind: string;
metadata: DeploymentMetadata;
spec: DeploymentSpec;
};

export type DeploymentMetadata = {
name: string;
namespace?: string;
labels?: KubernetesKeyValueObject;
annotations?: KubernetesKeyValueObject;
};

export type DeploymentSpec = {
replicas?: number;
template: PodTemplateSpec;
};
68 changes: 68 additions & 0 deletions plugins/cad/src/types/Pod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* Copyright 2022 Google LLC
*
* 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 { KubernetesKeyValueObject } from './KubernetesResource';

export type PodTemplateSpec = {
metadata: PodMetadata;
spec: PodSpec;
};

export type PodMetadata = {
name: string;
namespace?: string;
labels?: KubernetesKeyValueObject;
annotations?: KubernetesKeyValueObject;
};

export type PodSpec = {
serviceAccountName?: string;
volumes: Volume[];
containers: Container[];
};

export type Volume = {
name: string;
persistentVolumeClaim?: PersistentVolumeClaimVolumeSource;
configMap?: ConfigMapVolumeSource;
};

export type PersistentVolumeClaimVolumeSource = {
claimName: string;
};

export type ConfigMapVolumeSource = {
name: string;
};

export type Container = {
name: string;
image?: string;
ports?: ContainerPort[];
volumeMounts?: VolumeMount[];
};

export type ContainerPort = {
name: string;
containerPort: number;
protocol?: string;
};

export type VolumeMount = {
name: string;
mountPath: string;
readOnly?: boolean;
};
40 changes: 40 additions & 0 deletions plugins/cad/src/types/StatefulSet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright 2022 Google LLC
*
* 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 { KubernetesKeyValueObject } from './KubernetesResource';
import { PersistentVolumeClaim } from './PersistentVolumeClaim';
import { PodTemplateSpec } from './Pod';

export type StatefulSet = {
apiVersion: string;
kind: string;
metadata: StatefulSetMetadata;
spec: StatefulSetSpec;
};

export type StatefulSetMetadata = {
name: string;
namespace?: string;
labels?: KubernetesKeyValueObject;
annotations?: KubernetesKeyValueObject;
};

export type StatefulSetSpec = {
serviceName: string;
replicas?: number;
template: PodTemplateSpec;
volumeClaimTemplates?: PersistentVolumeClaim[];
};

0 comments on commit c456a8c

Please sign in to comment.