UNPKG

@kinvolk/headlamp-plugin

Version:

The needed infrastructure for building Headlamp plugins.

215 lines (214 loc) 6.93 kB
/* * 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 { countBy } from 'lodash'; import Namespace from '../../lib/k8s/namespace'; import { getStatus } from '../resourceMap/nodes/KubeObjectStatus'; export const PROJECT_ID_LABEL = 'headlamp.dev/project-id'; export const getHealthIcon = (healthy, unhealthy, warning) => { if (healthy + unhealthy + warning === 0) return 'mdi:help-circle'; if (unhealthy > 0) return 'mdi:alert-circle'; if (warning > 0) return 'mdi:alert'; return 'mdi:check-circle'; }; export const getResourcesByKind = (resources, kind) => { return resources.filter(resource => resource.kind === kind); }; // Calculate health status for the project export const getResourcesHealth = (resources) => countBy(resources, it => getStatus(it)); export const defaultApiResources = (() => { const resources = [ { apiVersion: 'v1', version: 'v1', pluralName: 'configmaps', singularName: 'configmap', kind: 'ConfigMap', isNamespaced: true, }, { apiVersion: 'v1', version: 'v1', pluralName: 'endpoints', singularName: 'endpoints', kind: 'Endpoints', isNamespaced: true, }, { apiVersion: 'discovery.k8s.io/v1', version: 'v1', groupName: 'discovery.k8s.io', pluralName: 'endpointslices', singularName: 'endpointSlice', kind: 'EndpointSlice', isNamespaced: true, }, { apiVersion: 'v1', version: 'v1', pluralName: 'persistentvolumeclaims', singularName: 'persistentvolumeclaim', kind: 'PersistentVolumeClaim', isNamespaced: true, }, { apiVersion: 'v1', version: 'v1', pluralName: 'secrets', singularName: 'secret', kind: 'Secret', isNamespaced: true, }, { apiVersion: 'v1', version: 'v1', pluralName: 'services', singularName: 'service', kind: 'Service', isNamespaced: true, }, { apiVersion: 'apps/v1', version: 'v1', groupName: 'apps', pluralName: 'statefulsets', singularName: 'statefulset', kind: 'StatefulSet', isNamespaced: true, }, { apiVersion: 'apps/v1', version: 'v1', groupName: 'apps', pluralName: 'replicasets', singularName: 'replicaset', kind: 'ReplicaSet', isNamespaced: true, }, { apiVersion: 'apps/v1', version: 'v1', groupName: 'apps', pluralName: 'deployments', singularName: 'deployment', kind: 'Deployment', isNamespaced: true, }, { apiVersion: 'apps/v1', version: 'v1', groupName: 'apps', pluralName: 'daemonsets', singularName: 'daemonset', kind: 'DaemonSet', isNamespaced: true, }, { apiVersion: 'batch/v1', version: 'v1', groupName: 'batch', pluralName: 'jobs', singularName: 'job', kind: 'Job', isNamespaced: true, }, { apiVersion: 'batch/v1', version: 'v1', groupName: 'batch', pluralName: 'cronjobs', singularName: 'cronjob', kind: 'CronJob', isNamespaced: true, }, { apiVersion: 'networking.k8s.io/v1', version: 'v1', groupName: 'networking.k8s.io', pluralName: 'ingresses', singularName: 'ingress', kind: 'Ingress', isNamespaced: true, }, { apiVersion: 'networking.k8s.io/v1', version: 'v1', groupName: 'networking.k8s.io', pluralName: 'networkpolicies', singularName: 'networkpolicy', kind: 'NetworkPolicy', isNamespaced: true, }, { apiVersion: 'autoscaling/v2', version: 'v2', groupName: 'autoscaling', pluralName: 'horizontalpodautoscalers', singularName: 'horizontalpodautoscaler', kind: 'HorizontalPodAutoscaler', isNamespaced: true, }, { apiVersion: 'rbac.authorization.k8s.io/v1', version: 'v1', groupName: 'rbac.authorization.k8s.io', pluralName: 'roles', singularName: 'role', kind: 'Role', isNamespaced: true, }, { apiVersion: 'rbac.authorization.k8s.io/v1', version: 'v1', groupName: 'rbac.authorization.k8s.io', pluralName: 'rolebindings', singularName: 'rolebinding', kind: 'RoleBinding', isNamespaced: true, }, { apiVersion: 'v1', version: 'v1', pluralName: 'resourcequotas', singularName: 'resourcequota', kind: 'ResourceQuota', isNamespaced: true, }, { apiVersion: 'v1', version: 'v1', pluralName: 'limitranges', singularName: 'limitrange', kind: 'LimitRange', isNamespaced: true, }, ]; return resources; })(); // Convert project name to Kubernetes-compatible format export const toKubernetesName = (name) => { const converted = name .toLowerCase() .replace(/\s+/g, '-') // Replace spaces with dashes .replace(/[^a-z0-9-]/g, '-') // Replace other non-alphanumeric chars with dashes .replace(/-+/g, '-') // Replace multiple dashes with single dash .replace(/^-+|-+$/g, '') // Remove leading/trailing dashes .substring(0, 63); // Ensure max 63 characters for DNS-1123 compliance // Validate using existing Kubernetes validation return Namespace.isValidNamespaceFormat(converted) ? converted : ''; };