UNPKG

@kinvolk/headlamp-plugin

Version:

The needed infrastructure for building Headlamp plugins.

182 lines (181 loc) 6.53 kB
import { jsx as _jsx } from "react/jsx-runtime"; /* * Copyright 2025 The Kubernetes Authors * * 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 Box from '@mui/material/Box'; import { alpha } from '@mui/system/colorManipulator'; import { useTypedSelector } from '../../../redux/hooks'; import CRoleIcon from './img/c-role.svg?react'; import CmIcon from './img/cm.svg?react'; import CrbIcon from './img/crb.svg?react'; import CrdIcon from './img/crd.svg?react'; import CronjobIcon from './img/cronjob.svg?react'; import DeployIcon from './img/deploy.svg?react'; import DsIcon from './img/ds.svg?react'; import EpIcon from './img/ep.svg?react'; import GroupIcon from './img/group.svg?react'; import HpaIcon from './img/hpa.svg?react'; import IngIcon from './img/ing.svg?react'; import JobIcon from './img/job.svg?react'; import LimitsIcon from './img/limits.svg?react'; import NetpolIcon from './img/netpol.svg?react'; import NsIcon from './img/ns.svg?react'; import PodIcon from './img/pod.svg?react'; import PspIcon from './img/psp.svg?react'; import PvIcon from './img/pv.svg?react'; import PvcIcon from './img/pvc.svg?react'; import QuotaIcon from './img/quota.svg?react'; import RbIcon from './img/rb.svg?react'; import RoleIcon from './img/role.svg?react'; import RsIcon from './img/rs.svg?react'; import SaIcon from './img/sa.svg?react'; import ScIcon from './img/sc.svg?react'; import SecretIcon from './img/secret.svg?react'; import StsIcon from './img/sts.svg?react'; import SvcIcon from './img/svc.svg?react'; import UserIcon from './img/user.svg?react'; import VolIcon from './img/vol.svg?react'; const kindToIcon = { // core group Namespace: NsIcon, Pod: PodIcon, Service: SvcIcon, Endpoints: EpIcon, Endpoint: EpIcon, EndpointSlice: EpIcon, ConfigMap: CmIcon, Secret: SecretIcon, PersistentVolume: PvIcon, PodSecurityPolicy: PspIcon, PersistentVolumeClaim: PvcIcon, ServiceAccount: SaIcon, ResourceQuota: QuotaIcon, LimitRange: LimitsIcon, Volume: VolIcon, User: UserIcon, Group: GroupIcon, // apps 'apps/Deployment': DeployIcon, 'apps/ReplicaSet': RsIcon, 'apps/StatefulSet': StsIcon, 'apps/DaemonSet': DsIcon, // batch 'batch/Job': JobIcon, 'batch/CronJob': CronjobIcon, // jobset 'jobset.x-k8s.io/JobSet': JobIcon, // rbac 'rbac.authorization.k8s.io/Role': RoleIcon, 'rbac.authorization.k8s.io/RoleBinding': RbIcon, 'rbac.authorization.k8s.io/ClusterRole': CRoleIcon, 'rbac.authorization.k8s.io/ClusterRoleBinding': CrbIcon, // networking 'networking.k8s.io/Ingress': IngIcon, 'networking.k8s.io/NetworkPolicy': NetpolIcon, // autoscaling 'autoscaling/HorizontalPodAutoscaler': HpaIcon, // storage 'storage.k8s.io/StorageClass': ScIcon, // apiextensions 'apiextensions.k8s.io/CustomResourceDefinition': CrdIcon, }; const kindGroups = { workloads: new Set([ 'Pod', 'Deployment', 'ReplicaSet', 'StatefulSet', 'DaemonSet', 'ReplicaSet', 'Job', 'CronJob', 'JobSet', ]), storage: new Set(['PersistentVolumeClaim']), network: new Set([ 'Service', 'Endpoints', 'Endpoint', 'EndpointSlice', 'Ingress', 'IngressClass', 'NetworkPolicy', ]), security: new Set(['ServiceAccount', 'Role', 'RoleBinding', 'ClusterRole', 'ClusterRoleBinding']), configuration: new Set([ 'ConfigMap', 'Secret', 'HorizontalPodAutoscaler', 'VerticalPodAutoscaler', 'PodDisruptionBudget', 'PriorityClass', 'RuntimeClass', 'Lease', 'ResourceQuota', 'LimitRange', 'MutatingWebhookConfiguration', 'ValidatingWebhookConfiguration', ]), }; const getKindGroup = (kind) => Object.entries(kindGroups).find(([, set]) => set.has(kind))?.[0]; const lightness = '67.85%'; const chroma = '0.12'; const kindGroupColors = { workloads: `oklch(${lightness} ${chroma} 182.18)`, storage: `oklch(${lightness} ${chroma} 46.47)`, network: `oklch(${lightness} ${chroma} 225.16)`, security: `oklch(${lightness} ${chroma} 275.16)`, configuration: `oklch(${lightness} ${chroma} 320.03)`, other: `oklch(${lightness} 0 215.25)`, }; const getKindColor = (kind) => kindGroupColors[getKindGroup(kind) ?? 'other']; export const getKindGroupColor = (group) => kindGroupColors[group] ?? kindGroupColors.other; /** * Icon for the Kube resource * Color is based on the resource category (workload,storage, etc) * * Icons are taken from * https://github.com/kubernetes/community/tree/master/icons * * @param params.kind - Resource kind * @param params.apiGroup - Resource API group * @param params.width - width in css units * @param params.height - width in css units * @returns */ export function KubeIcon({ kind, apiGroup, width, height, }) { const pluginDefinedIcons = useTypedSelector(state => state.graphView.kindIcons); const apiGroupKey = apiGroup ? `${apiGroup}/${kind}` : null; const pluginIcon = (apiGroupKey && pluginDefinedIcons[apiGroupKey]) || pluginDefinedIcons[kind]; const IconComponent = (apiGroupKey && kindToIcon[apiGroupKey]) || kindToIcon[kind] || kindToIcon['Pod']; const icon = pluginIcon?.icon ?? (_jsx(IconComponent, { style: { scale: '1.1', width: '100%', height: '100%' } })); const color = pluginIcon?.color ?? getKindColor(kind); return (_jsx(Box, { sx: { color, flexShrink: 0, borderRadius: '50%', width: width ?? '100%', height: height ?? '100%', background: color.includes('oklch') ? color.replace(')', ' / 12%)') : alpha(color, 0.12), display: 'flex', alignItems: 'center', justifyContent: 'center', 'path[id=path3054-2-9]': { fill: 'none !important', }, }, children: icon })); }