Files
cozystack/internal/controller/dashboard/static_refactored.go
Andrei Kvapil bd9dcb52a3 [dashboard] Add new patches
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
2025-10-31 18:06:44 +01:00

1849 lines
69 KiB
Go

package dashboard
import (
"encoding/json"
"strings"
dashboardv1alpha1 "github.com/cozystack/cozystack/api/dashboard/v1alpha1"
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// ---------------- Complete refactored static resources ----------------
// CreateAllBreadcrumbs creates all breadcrumb resources using helper functions
func CreateAllBreadcrumbs() []*dashboardv1alpha1.Breadcrumb {
return []*dashboardv1alpha1.Breadcrumb{
// Stock project factory configmap details
createBreadcrumb("stock-project-factory-configmap-details", []map[string]any{
createBreadcrumbItem("configmaps", "v1/configmaps", "/openapi-ui/{clusterName}/{namespace}/builtin-table/configmaps"),
createBreadcrumbItem("configmap", "{6}"),
}),
// Stock cluster factory namespace details
createBreadcrumb("stock-cluster-factory-namespace-details", []map[string]any{
createBreadcrumbItem("namespaces", "v1/namespaces", "/openapi-ui/{clusterName}/builtin-table/namespaces"),
createBreadcrumbItem("namespace", "{5}"),
}),
// Stock cluster factory node details
createBreadcrumb("stock-cluster-factory-node-details", []map[string]any{
createBreadcrumbItem("node", "v1/nodes", "/openapi-ui/{clusterName}/builtin-table/nodes"),
createBreadcrumbItem("node", "{5}"),
}),
// Stock project factory pod details
createBreadcrumb("stock-project-factory-pod-details", []map[string]any{
createBreadcrumbItem("pods", "v1/pods", "/openapi-ui/{clusterName}/{namespace}/builtin-table/pods"),
createBreadcrumbItem("pod", "{6}"),
}),
// Stock project factory secret details
createBreadcrumb("stock-project-factory-kube-secret-details", []map[string]any{
createBreadcrumbItem("secrets", "v1/secrets", "/openapi-ui/{clusterName}/{namespace}/builtin-table/secrets"),
createBreadcrumbItem("secret", "{6}"),
}),
// Stock project factory service details
createBreadcrumb("stock-project-factory-kube-service-details", []map[string]any{
createBreadcrumbItem("services", "v1/services", "/openapi-ui/{clusterName}/{namespace}/builtin-table/services"),
createBreadcrumbItem("service", "{6}"),
}),
// Stock project factory ingress details
createBreadcrumb("stock-project-factory-kube-ingress-details", []map[string]any{
createBreadcrumbItem("ingresses", "networking.k8s.io/v1/ingresses", "/openapi-ui/{clusterName}/{namespace}/builtin-table/ingresses"),
createBreadcrumbItem("ingress", "{6}"),
}),
// Stock cluster api table
createBreadcrumb("stock-cluster-api-table", []map[string]any{
createBreadcrumbItem("api", "{apiGroup}/{apiVersion}/{typeName}"),
}),
// Stock cluster api form
createBreadcrumb("stock-cluster-api-form", []map[string]any{
createBreadcrumbItem("create-api-res-namespaced-table", "{apiGroup}/{apiVersion}/{typeName}", "/openapi-ui/{clusterName}/api-table/{apiGroup}/{apiVersion}/{typeName}"),
createBreadcrumbItem("create-api-res-namespaced-typename", "Create"),
}),
// Stock cluster api form edit
createBreadcrumb("stock-cluster-api-form-edit", []map[string]any{
createBreadcrumbItem("create-api-res-namespaced-table", "{apiGroup}/{apiVersion}/{typeName}", "/openapi-ui/{clusterName}/api-table/{apiGroup}/{apiVersion}/{typeName}"),
createBreadcrumbItem("create-api-res-namespaced-typename", "Update"),
}),
// Stock cluster builtin table
createBreadcrumb("stock-cluster-builtin-table", []map[string]any{
createBreadcrumbItem("api", "v1/{typeName}"),
}),
// Stock cluster builtin form
createBreadcrumb("stock-cluster-builtin-form", []map[string]any{
createBreadcrumbItem("create-api-res-namespaced-table", "v1/{typeName}", "/openapi-ui/{clusterName}/builtin-table/{typeName}"),
createBreadcrumbItem("create-api-res-namespaced-typename", "Create"),
}),
// Stock cluster builtin form edit
createBreadcrumb("stock-cluster-builtin-form-edit", []map[string]any{
createBreadcrumbItem("create-api-res-namespaced-table", "v1/{typeName}", "/openapi-ui/{clusterName}/builtin-table/{typeName}"),
createBreadcrumbItem("create-api-res-namespaced-typename", "Update"),
}),
// Stock project api table
createBreadcrumb("stock-project-api-table", []map[string]any{
createBreadcrumbItem("api", "{apiGroup}/{apiVersion}/{typeName}"),
}),
// Stock project api form
createBreadcrumb("stock-project-api-form", []map[string]any{
createBreadcrumbItem("create-api-res-namespaced-table", "{apiGroup}/{apiVersion}/{typeName}", "/openapi-ui/{clusterName}/{namespace}/api-table/{apiGroup}/{apiVersion}/{typeName}"),
createBreadcrumbItem("create-api-res-namespaced-typename", "Create"),
}),
// Stock project api form edit
createBreadcrumb("stock-project-api-form-edit", []map[string]any{
createBreadcrumbItem("create-api-res-namespaced-table", "{apiGroup}/{apiVersion}/{typeName}", "/openapi-ui/{clusterName}/{namespace}/api-table/{apiGroup}/{apiVersion}/{typeName}"),
createBreadcrumbItem("create-api-res-namespaced-typename", "Update"),
}),
// Stock project builtin table
createBreadcrumb("stock-project-builtin-table", []map[string]any{
createBreadcrumbItem("api", "v1/{typeName}"),
}),
// Stock project builtin form
createBreadcrumb("stock-project-builtin-form", []map[string]any{
createBreadcrumbItem("create-api-res-namespaced-table", "v1/{typeName}", "/openapi-ui/{clusterName}/{namespace}/builtin-table/{typeName}"),
createBreadcrumbItem("create-api-res-namespaced-typename", "Create"),
}),
// Stock project builtin form edit
createBreadcrumb("stock-project-builtin-form-edit", []map[string]any{
createBreadcrumbItem("create-api-res-namespaced-table", "v1/{typeName}", "/openapi-ui/{clusterName}/{namespace}/builtin-table/{typeName}"),
createBreadcrumbItem("create-api-res-namespaced-typename", "Update"),
}),
}
}
// CreateAllCustomColumnsOverrides creates all custom column override resources using helper functions
func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverride {
return []*dashboardv1alpha1.CustomColumnsOverride{
// Factory details v1 services
createCustomColumnsOverride("factory-details-v1.services", []any{
createCustomColumnWithSpecificColor("Name", "Service", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createStringColumn("ClusterIP", ".spec.clusterIP"),
createStringColumn("LoadbalancerIP", ".spec.loadBalancerIP"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Stock namespace v1 services
createCustomColumnsOverride("stock-namespace-/v1/services", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createStringColumn("ClusterIP", ".spec.clusterIP"),
createStringColumn("LoadbalancerIP", ".status.loadBalancer.ingress[0].ip"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Stock namespace core cozystack io v1alpha1 tenantmodules
createCustomColumnsOverride("stock-namespace-/core.cozystack.io/v1alpha1/tenantmodules", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "M", "module", getColorForType("module"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/{reqsJsonPath[0]['.metadata.name']['-']}-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createReadyColumn(),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
createStringColumn("Version", ".status.version"),
}),
// Factory service details port mapping
createCustomColumnsOverride("factory-kube-service-details-port-mapping", []any{
createStringColumn("Name", ".name"),
createStringColumn("Port", ".port"),
createStringColumn("Protocol", ".protocol"),
createStringColumn("Pod port or name", ".targetPort"),
}),
// Factory details v1alpha1 cozystack io workloadmonitors
createCustomColumnsOverride("factory-details-v1alpha1.cozystack.io.workloadmonitors", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "W", "workloadmonitor", getColorForType("workloadmonitor"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/workloadmonitor-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createStringColumn("TYPE", ".spec.type"),
createStringColumn("VERSION", ".spec.version"),
createStringColumn("REPLICAS", ".spec.replicas"),
createStringColumn("MINREPLICAS", ".spec.minReplicas"),
createStringColumn("AVAILABLE", ".status.availableReplicas"),
createStringColumn("OBSERVED", ".status.observedReplicas"),
}),
// Factory details v1alpha1 core cozystack io tenantsecretstables
createCustomColumnsOverride("factory-details-v1alpha1.core.cozystack.io.tenantsecretstables", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "secret", getColorForType("secret"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createStringColumn("Key", ".data.key"),
createSecretBase64Column("Value", ".data.value"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Factory ingress details rules
createCustomColumnsOverride("factory-kube-ingress-details-rules", []any{
createStringColumn("Host", ".host"),
createCustomColumnWithJsonPath("Service", ".http.paths[0].backend.service.name", "S", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.http.paths[0].backend.service.name']['-']}"),
createStringColumn("Port", ".http.paths[0].backend.service.port.number"),
createStringColumn("Path", ".http.paths[0].path"),
}),
// Factory node images
createCustomColumnsOverride("factory-node-images", []any{
createStringColumn("ImageID", ".names[0]"),
createConverterBytesColumn("Size", ".sizeBytes"),
}),
// Factory pod details volume list
createCustomColumnsOverride("factory-pod-details-volume-list", []any{
createStringColumn("Name", ".name"),
}),
// Factory status conditions
createCustomColumnsOverride("factory-status-conditions", []any{
createStringColumn("Type", ".type"),
createBoolColumn("Status", ".status"),
createTimestampColumn("Updated", ".lastTransitionTime"),
createStringColumn("Reason", ".reason"),
createStringColumn("Message", ".message"),
}),
// Container status init containers list
createCustomColumnsOverride("container-status-init-containers-list", []any{
createStringColumn("Name", ".name"),
createStringColumn("Image", ".imageID"),
createBoolColumn("Started", ".started"),
createBoolColumn("Ready", ".ready"),
createStringColumn("RestartCount", ".restartCount"),
createStringColumn("WaitingReason", ".state.waiting.reason"),
createStringColumn("TerminatedReason", ".state.terminated.reason"),
}),
// Container status containers list
createCustomColumnsOverride("container-status-containers-list", []any{
createStringColumn("Name", ".name"),
createStringColumn("Image", ".imageID"),
createBoolColumn("Started", ".started"),
createBoolColumn("Ready", ".ready"),
createStringColumn("RestartCount", ".restartCount"),
createStringColumn("WaitingReason", ".state.waiting.reason"),
createStringColumn("TerminatedReason", ".state.terminated.reason"),
}),
// Container spec init containers list
createCustomColumnsOverride("container-spec-init-containers-list", []any{
createStringColumn("Name", ".name"),
createStringColumn("Image", ".image"),
createArrayColumn("Resources requests", ".resources.requests"),
createArrayColumn("Resources limits", ".resources.limits"),
}),
// Container spec containers list
createCustomColumnsOverride("container-spec-containers-list", []any{
createStringColumn("Name", ".name"),
createStringColumn("Image", ".image"),
createArrayColumn("Resources requests", ".resources.requests"),
createArrayColumn("Resources limits", ".resources.limits"),
createArrayColumn("Ports", ".ports[*].containerPort"),
}),
// Factory details networking k8s io v1 ingresses
createCustomColumnsOverride("factory-details-networking.k8s.io.v1.ingresses", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "I", "ingress", getColorForType("ingress"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createStringColumn("Hosts", ".spec.rules[*].host"),
createStringColumn("Address", ".status.loadBalancer.ingress[0].ip"),
createStringColumn("Port", ".spec.defaultBackend.service.port.number"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Stock namespace networking k8s io v1 ingresses
createCustomColumnsOverride("stock-namespace-/networking.k8s.io/v1/ingresses", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "I", "ingress", getColorForType("ingress"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createStringColumn("Hosts", ".spec.rules[*].host"),
createStringColumn("Address", ".status.loadBalancer.ingress[0].ip"),
createStringColumn("Port", ".spec.defaultBackend.service.port.number"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Stock cluster v1 configmaps
createCustomColumnsOverride("stock-cluster-/v1/configmaps", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "CM", "configmap", getColorForType("configmap"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", getColorForType("namespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Stock namespace v1 configmaps
createCustomColumnsOverride("stock-namespace-/v1/configmaps", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "CM", "configmap", getColorForType("configmap"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Cluster v1 configmaps
createCustomColumnsOverride("cluster-/v1/configmaps", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "CM", "configmap", getColorForType("configmap"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", getColorForType("namespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Stock cluster v1 nodes
createCustomColumnsOverride("stock-cluster-/v1/nodes", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "N", "node", getColorForType("node"), "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createSimpleStatusColumn("Status", "node-status"),
}),
// Factory node details v1 pods
createCustomColumnsOverride("factory-node-details-v1.pods", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", getColorForType("pod"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", getColorForType("namespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
createStringColumn("Restart Policy", ".spec.restartPolicy"),
createStringColumn("Pod IP", ".status.podIP"),
createStringColumn("QOS", ".status.qosClass"),
createSimpleStatusColumn("Status", "pod-status"),
}),
// Factory v1 pods
createCustomColumnsOverride("factory-v1.pods", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", getColorForType("pod"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createCustomColumnWithoutJsonPath("Node", "N", "node", getColorForType("node"), "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
createStringColumn("Restart Policy", ".spec.restartPolicy"),
createStringColumn("Pod IP", ".status.podIP"),
createStringColumn("QOS", ".status.qosClass"),
createSimpleStatusColumn("Status", "pod-status"),
}),
// Stock cluster v1 pods
createCustomColumnsOverride("stock-cluster-/v1/pods", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
createCustomColumnWithJsonPath("Node", ".spec.nodeName", "N", "node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
createStringColumn("Restart Policy", ".spec.restartPolicy"),
createStringColumn("Pod IP", ".status.podIP"),
createStringColumn("QOS", ".status.qosClass"),
createSimpleStatusColumn("Status", "pod-status"),
}),
// Stock namespace v1 pods
createCustomColumnsOverride("stock-namespace-/v1/pods", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createCustomColumnWithoutJsonPath("Node", "N", "node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
createStringColumn("Restart Policy", ".spec.restartPolicy"),
createStringColumn("Pod IP", ".status.podIP"),
createStringColumn("QOS", ".status.qosClass"),
createSimpleStatusColumn("Status", "pod-status"),
}),
// Stock cluster v1 secrets
createCustomColumnsOverride("stock-cluster-/v1/secrets", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
createStringColumn("Type", ".type"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Stock namespace v1 secrets
createCustomColumnsOverride("stock-namespace-/v1/secrets", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createStringColumn("Type", ".type"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
// Factory details v1alpha1 cozystack io workloads
createCustomColumnsOverride("factory-details-v1alpha1.cozystack.io.workloads", []any{
createStringColumn("Name", ".metadata.name"),
createStringColumn("Kind", ".status.kind"),
createStringColumn("Type", ".status.type"),
createStringColumn("CPU", ".status.resources.cpu"),
createStringColumn("Memory", ".status.resources.memory"),
createStringColumn("Operational", ".status.operational"),
}),
// Stock cluster core cozystack io v1alpha1 tenantnamespaces
createCustomColumnsOverride("stock-cluster-/core.cozystack.io/v1alpha1/tenantnamespaces", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "TN", "tenantnamespace", getColorForType("tenantnamespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.name']['-']}/factory/marketplace"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
}
}
// CreateAllCustomFormsOverrides creates all custom forms override resources using helper functions
func CreateAllCustomFormsOverrides() []*dashboardv1alpha1.CustomFormsOverride {
return []*dashboardv1alpha1.CustomFormsOverride{
// Default networking k8s io v1 ingresses
createCustomFormsOverride("default-/networking.k8s.io/v1/ingresses", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("metadata.namespace", "Namespace", "text"),
createFormItem("spec.rules", "Rules", "array"),
},
}),
// Default storage k8s io v1 storageclasses
createCustomFormsOverride("default-/storage.k8s.io/v1/storageclasses", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("provisioner", "Provisioner", "text"),
createFormItem("reclaimPolicy", "Reclaim Policy", "select"),
},
}),
// Default v1 configmaps
createCustomFormsOverride("default-/v1/configmaps", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("metadata.namespace", "Namespace", "text"),
createFormItem("data", "Data", "object"),
},
}),
// Default v1 namespaces
createCustomFormsOverride("default-/v1/namespaces", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("metadata.labels", "Labels", "object"),
},
}),
// Default v1 nodes
createCustomFormsOverride("default-/v1/nodes", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("spec.podCIDR", "Pod CIDR", "text"),
},
}),
// Default v1 persistentvolumeclaims
createCustomFormsOverride("default-/v1/persistentvolumeclaims", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("metadata.namespace", "Namespace", "text"),
createFormItem("spec.accessModes", "Access Modes", "array"),
},
}),
// Default v1 persistentvolumes
createCustomFormsOverride("default-/v1/persistentvolumes", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("spec.capacity", "Capacity", "object"),
},
}),
// Default v1 pods
createCustomFormsOverride("default-/v1/pods", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("metadata.namespace", "Namespace", "text"),
createFormItem("spec.containers", "Containers", "array"),
},
}),
// Default v1 secrets
createCustomFormsOverride("default-/v1/secrets", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("metadata.namespace", "Namespace", "text"),
createFormItem("type", "Type", "text"),
},
}),
// Default v1 services
createCustomFormsOverride("default-/v1/services", map[string]any{
"formItems": []any{
createFormItem("metadata.name", "Name", "text"),
createFormItem("metadata.namespace", "Namespace", "text"),
createFormItem("spec.ports", "Ports", "array"),
},
}),
}
}
// CreateAllFactories creates all factory resources using helper functions
func CreateAllFactories() []*dashboardv1alpha1.Factory {
// Marketplace factory
marketplaceSpec := map[string]any{
"key": "marketplace",
"sidebarTags": []any{
"marketplace-sidebar",
},
"urlsToFetch": []any{},
"withScrollableMainContentCard": true,
"data": []any{
contentCardWithTitle(31, "Marketplace", map[string]any{
"flexGrow": 1,
}, []any{
map[string]any{
"data": map[string]any{
"baseApiVersion": "v1alpha1",
"baseprefix": "openapi-ui",
"clusterNamePartOfUrl": "{2}",
"id": 311,
"mpResourceKind": "MarketplacePanel",
"mpResourceName": "marketplacepanels",
"namespacePartOfUrl": "{3}",
"baseApiGroup": "dashboard.cozystack.io",
},
"type": "MarketplaceCard",
},
}),
},
}
// Namespace details factory using unified approach
namespaceConfig := UnifiedResourceConfig{
Name: "namespace-details",
ResourceType: "factory",
Kind: "Namespace",
Plural: "namespaces",
Title: "namespace",
Size: BadgeSizeLarge,
}
namespaceSpec := createUnifiedFactory(namespaceConfig, nil, []any{"/api/clusters/{2}/k8s/api/v1/namespaces/{5}"})
// Node details factory
nodeHeader := createNodeHeader()
// Create node spec with tabs containing items
nodeTabs := []any{
map[string]any{
"key": "details",
"label": "Details",
"children": []any{
map[string]any{
"type": "ContentCard",
"data": map[string]any{
"id": "details-card",
"style": map[string]any{
"marginBottom": "24px",
},
},
"children": []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "details-title",
"text": "Node details",
"strong": true,
"style": map[string]any{
"fontSize": float64(20),
"marginBottom": "12px",
},
},
},
},
},
},
},
}
nodeSpec := map[string]any{
"key": "node-details",
"sidebarTags": []any{"node-sidebar"},
"withScrollableMainContentCard": true,
"urlsToFetch": []any{"/api/clusters/{2}/k8s/api/v1/nodes/{5}"},
"data": []any{
nodeHeader,
map[string]any{
"type": "antdTabs",
"data": map[string]any{
"id": "tabs-root",
"defaultActiveKey": "details",
"items": nodeTabs,
},
},
},
}
// Pod details factory
podHeader := createPodHeader()
// Create pod spec with empty tabs (items: nil)
podSpec := map[string]any{
"key": "pod-details",
"sidebarTags": []any{"pods-sidebar"},
"withScrollableMainContentCard": true,
"urlsToFetch": []any{"/api/clusters/{2}/k8s/api/v1/namespaces/{3}/pods/{6}"},
"data": []any{
podHeader,
map[string]any{
"type": "antdTabs",
"data": map[string]any{
"id": "tabs-root",
"defaultActiveKey": "details",
"items": nil,
},
},
},
}
// Secret details factory
secretHeader := map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "header-row",
"align": "center",
"gap": float64(6),
"style": map[string]any{
"marginBottom": "24px",
},
},
"children": []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "badge-secret",
"text": "S",
"title": "secret",
"style": map[string]any{
"backgroundColor": "#c46100",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": "20px",
"fontWeight": 400,
"lineHeight": "24px",
"minWidth": 24,
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
},
map[string]any{
"type": "parsedText",
"data": map[string]any{
"id": "header-secret-name",
"text": "{reqsJsonPath[0]['.metadata.name']['-']}",
"style": map[string]any{
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": "20px",
"lineHeight": "24px",
},
},
},
},
}
secretTabs := []any{
map[string]any{
"key": "details",
"label": "Details",
"children": []any{
contentCard("details-card", map[string]any{
"marginBottom": "24px",
}, []any{
antdText("details-title", true, "Secret details", map[string]any{
"fontSize": 20,
"marginBottom": "12px",
}),
spacer("details-spacer", 16),
antdRow("details-grid", []any{48, 12}, []any{
antdCol("col-left", 12, []any{
antdFlexVertical("col-left-stack", 24, []any{
antdFlexVertical("meta-name-block", 4, []any{
antdText("meta-name-label", true, "Name", nil),
parsedText("meta-name-value", "{reqsJsonPath[0]['.metadata.name']['-']}", nil),
}),
antdFlexVertical("meta-namespace-block", 8, []any{
antdText("meta-name-label", true, "Namespace", nil),
antdFlex("header-row", 6, []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "header-badge",
"text": "NS",
"title": "namespace",
"style": map[string]any{
"backgroundColor": "#a25792ff",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": "15px",
"fontWeight": 400,
"lineHeight": "24px",
"minWidth": 24,
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
},
map[string]any{
"type": "antdLink",
"data": map[string]any{
"id": "namespace-link",
"text": "{reqsJsonPath[0]['.metadata.namespace']['-']}",
"href": "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace",
},
},
}),
}),
antdFlexVertical("meta-labels-block", 8, []any{
antdText("labels-title", true, "Labels", map[string]any{
"fontSize": 14,
}),
map[string]any{
"type": "Labels",
"data": map[string]any{
"id": "labels-editor",
"endpoint": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/secrets/{6}",
"jsonPathToLabels": ".metadata.labels",
"pathToValue": "/metadata/labels",
"reqIndex": 0,
"modalTitle": "Edit labels",
"modalDescriptionText": "",
"inputLabel": "",
"notificationSuccessMessage": "Updated successfully",
"notificationSuccessMessageDescription": "Labels have been updated",
"editModalWidth": 650,
"maxEditTagTextLength": 35,
"paddingContainerEnd": "24px",
"containerStyle": map[string]any{
"marginTop": "-30px",
},
"selectProps": map[string]any{
"maxTagTextLength": 35,
},
},
},
}),
antdFlexVertical("ds-annotations", 4, []any{
antdText("annotations", true, "Annotations", nil),
map[string]any{
"type": "Annotations",
"data": map[string]any{
"id": "annotations",
"endpoint": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/secrets/{6}",
"jsonPathToObj": ".metadata.annotations",
"pathToValue": "/metadata/annotations",
"reqIndex": 0,
"modalTitle": "Edit annotations",
"modalDescriptionText": "",
"inputLabel": "",
"notificationSuccessMessage": "Updated successfully",
"notificationSuccessMessageDescription": "Annotations have been updated",
"editModalWidth": "800px",
"errorText": "0 Annotations",
"text": "~counter~ Annotations",
"cols": []any{11, 11, 2},
},
},
}),
antdFlexVertical("meta-created-block", 4, []any{
antdText("time-label", true, "Created", nil),
antdFlex("time-block", 6, []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "time-icon",
"text": "🌐",
},
},
map[string]any{
"type": "parsedText",
"data": map[string]any{
"formatter": "timestamp",
"id": "time-value",
"text": "{reqsJsonPath[0]['.metadata.creationTimestamp']['-']}",
},
},
}),
}),
}),
}),
antdCol("col-right", 12, []any{
antdFlexVertical("col-right-stack", 24, []any{
antdFlexVertical("secret-type-block", 4, []any{
antdText("secret-type-label", true, "Type", nil),
parsedText("secret-type-value", "{reqsJsonPath[0]['.type']['-']}", nil),
}),
antdFlexVertical("secret-sa-block", 4, []any{
map[string]any{
"type": "parsedText",
"data": map[string]any{
"id": "serviceaccount-title",
"text": "ServiceAccount",
"strong": true,
"style": map[string]any{
"fontWeight": "bold",
},
},
},
map[string]any{
"type": "antdLink",
"data": map[string]any{
"id": "serviceaccount-link",
"text": "{reqsJsonPath[0]['.metadata.annotations[\"kubernetes.io/service-account.name\"]']['-']}",
"href": "/openapi-ui/{2}/{3}/factory/serviceaccount-details/{reqsJsonPath[0]['.metadata.annotations[\"kubernetes.io/service-account.name\"]']['-']}",
},
},
}),
}),
}),
}),
}),
},
},
map[string]any{
"key": "yaml",
"label": "YAML",
"children": []any{
map[string]any{
"type": "YamlEditorSingleton",
"data": map[string]any{
"id": "yaml-editor",
"cluster": "{2}",
"isNameSpaced": true,
"prefillValuesRequestIndex": 0,
"substractHeight": float64(400),
"type": "builtin",
"typeName": "secrets",
"readOnly": true,
},
},
},
},
}
secretSpec := createFactorySpec("kube-secret-details", []any{"secret-sidebar"}, []any{"/api/clusters/{2}/k8s/api/v1/namespaces/{3}/secrets/{6}"}, secretHeader, secretTabs)
// Service details factory
serviceHeader := map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "header-row",
"align": "center",
"gap": float64(6),
"style": map[string]any{
"marginBottom": "24px",
},
},
"children": []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "badge-service",
"text": "S",
"title": "services",
"style": map[string]any{
"backgroundColor": "#6ca100",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": "20px",
"fontWeight": 400,
"lineHeight": "24px",
"minWidth": 24,
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
},
map[string]any{
"type": "parsedText",
"data": map[string]any{
"id": "service-name",
"text": "{reqsJsonPath[0]['.metadata.name']['-']}",
"style": map[string]any{
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": "20px",
"lineHeight": "24px",
},
},
},
},
}
serviceTabs := []any{
map[string]any{
"key": "details",
"label": "Details",
"children": []any{
contentCard("details-card", map[string]any{
"marginBottom": "24px",
}, []any{
antdText("details-title", true, "Service details", map[string]any{
"fontSize": 20,
"marginBottom": "12px",
}),
spacer("details-spacer", 16),
antdRow("details-grid", []any{48, 12}, []any{
antdCol("col-left", 12, []any{
antdFlexVertical("col-left-stack", 24, []any{
antdFlexVertical("meta-name-block", 4, []any{
antdText("meta-name-label", true, "Name", nil),
parsedText("meta-name-value", "{reqsJsonPath[0]['.metadata.name']['-']}", nil),
}),
antdFlexVertical("meta-namespace-block", 8, []any{
antdText("meta-name-label", true, "Namespace", nil),
antdFlex("header-row", 6, []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "header-badge",
"text": "NS",
"title": "namespace",
"style": map[string]any{
"backgroundColor": "#a25792ff",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": "15px",
"fontWeight": 400,
"lineHeight": "24px",
"minWidth": 24,
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
},
map[string]any{
"type": "antdLink",
"data": map[string]any{
"id": "namespace-link",
"text": "{reqsJsonPath[0]['.metadata.namespace']['-']}",
"href": "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace",
},
},
}),
}),
antdFlexVertical("meta-labels-block", 8, []any{
antdText("labels-title", true, "Labels", map[string]any{
"fontSize": 14,
}),
map[string]any{
"type": "Labels",
"data": map[string]any{
"id": "labels-editor",
"endpoint": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/services/{6}",
"jsonPathToLabels": ".metadata.labels",
"pathToValue": "/metadata/labels",
"reqIndex": 0,
"modalTitle": "Edit labels",
"modalDescriptionText": "",
"inputLabel": "",
"notificationSuccessMessage": "Updated successfully",
"notificationSuccessMessageDescription": "Labels have been updated",
"editModalWidth": 650,
"maxEditTagTextLength": 35,
"paddingContainerEnd": "24px",
"containerStyle": map[string]any{
"marginTop": "-30px",
},
"selectProps": map[string]any{
"maxTagTextLength": 35,
},
},
},
}),
antdFlexVertical("meta-pod-selector-block", 4, []any{
antdText("pod-selector", true, "Pod selector", map[string]any{
"fontSize": 14,
}),
map[string]any{
"type": "LabelsToSearchParams",
"data": map[string]any{
"id": "pod-to-search-params",
"jsonPathToLabels": ".spec.selector",
"linkPrefix": "/openapi-ui/{2}/search",
"reqIndex": 0,
"errorText": "-",
},
},
}),
antdFlexVertical("ds-annotations", 4, []any{
antdText("annotations", true, "Annotations", nil),
map[string]any{
"type": "Annotations",
"data": map[string]any{
"id": "annotations",
"endpoint": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/services/{6}",
"jsonPathToObj": ".metadata.annotations",
"pathToValue": "/metadata/annotations",
"reqIndex": 0,
"modalTitle": "Edit annotations",
"modalDescriptionText": "",
"inputLabel": "",
"notificationSuccessMessage": "Updated successfully",
"notificationSuccessMessageDescription": "Annotations have been updated",
"editModalWidth": "800px",
"errorText": "0 Annotations",
"text": "~counter~ Annotations",
"cols": []any{11, 11, 2},
},
},
}),
antdFlexVertical("meta-session-affinity-block", 4, []any{
antdText("meta-session-affinity-label", true, "Session affinity", nil),
parsedText("meta-session-affinity-value", "{reqsJsonPath[0]['.spec.sessionAffinity']['Not configured']}", nil),
}),
antdFlexVertical("meta-created-block", 4, []any{
antdText("time-label", true, "Created", nil),
antdFlex("time-block", 6, []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "time-icon",
"text": "🌐",
},
},
map[string]any{
"type": "parsedText",
"data": map[string]any{
"formatter": "timestamp",
"id": "time-value",
"text": "{reqsJsonPath[0]['.metadata.creationTimestamp']['-']}",
},
},
}),
}),
}),
}),
antdCol("col-right", 12, []any{
antdFlexVertical("col-right-stack", 24, []any{
antdText("routing-title", true, "Service routing", map[string]any{
"fontSize": 20,
"marginBottom": "12px",
}),
spacer("routing-spacer", 16),
antdFlexVertical("service-hostname-block", 4, []any{
antdText("service-hostname-label", true, "Hostname", nil),
parsedText("service-hostname-value", "{reqsJsonPath[0]['.metadata.name']['-']}.{reqsJsonPath[0]['.metadata.namespace']['-']}.svc.cluster.local", nil),
}),
antdFlexVertical("service-ip-block", 12, []any{
antdFlexVertical("clusterip-block", 4, []any{
antdText("clusterip-label", true, "ClusterIP address", nil),
parsedText("clusterip-value", "{reqsJsonPath[0]['.spec.clusterIP']['-']}", nil),
}),
antdFlexVertical("loadbalancerip-block", 4, []any{
antdText("loadbalancerip-label", true, "LoadBalancerIP address", nil),
parsedText("loadbalancerip-value", "{reqsJsonPath[0]['.status.loadBalancer.ingress[0].ip']['Not Configured']}", nil),
}),
}),
antdFlexVertical("service-port-mapping-block", 4, []any{
antdText("service-port-mapping-label", true, "Service port mapping", nil),
map[string]any{
"type": "EnrichedTable",
"data": map[string]any{
"id": "service-port-mapping-table",
"baseprefix": "/openapi-ui",
"clusterNamePartOfUrl": "{2}",
"customizationId": "factory-kube-service-details-port-mapping",
"fetchUrl": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/services/{6}",
"pathToItems": ".spec.ports",
"withoutControls": true,
},
},
}),
map[string]any{
"type": "VisibilityContainer",
"data": map[string]any{
"id": "service-pod-serving-vis",
"value": "{reqsJsonPath[0]['.spec.selector']['-']}",
"style": map[string]any{
"margin": 0,
"padding": 0,
},
},
"children": []any{
antdFlexVertical("service-pod-serving-block", 4, []any{
antdText("service-pod-serving-label", true, "Pod serving", nil),
map[string]any{
"type": "EnrichedTable",
"data": map[string]any{
"id": "service-pod-serving-table",
"baseprefix": "/openapi-ui",
"clusterNamePartOfUrl": "{2}",
"customizationId": "factory-kube-service-details-endpointslice",
"fetchUrl": "/api/clusters/{2}/k8s/apis/discovery.k8s.io/v1/namespaces/{3}/endpointslices",
"labelsSelector": map[string]any{
"kubernetes.io/service-name": "{reqsJsonPath[0]['.metadata.name']['-']}",
},
"pathToItems": ".items[*].endpoints",
"withoutControls": true,
},
},
}),
},
},
}),
}),
}),
}),
},
},
map[string]any{
"key": "yaml",
"label": "YAML",
"children": []any{
map[string]any{
"type": "YamlEditorSingleton",
"data": map[string]any{
"id": "yaml-editor",
"cluster": "{2}",
"isNameSpaced": true,
"prefillValuesRequestIndex": 0,
"substractHeight": float64(400),
"type": "builtin",
"typeName": "services",
},
},
},
},
map[string]any{
"key": "pods",
"label": "Pods",
"children": []any{
map[string]any{
"type": "VisibilityContainer",
"data": map[string]any{
"id": "service-pod-serving-vis",
"value": "{reqsJsonPath[0]['.spec.selector']['-']}",
"style": map[string]any{
"margin": 0,
"padding": 0,
},
},
"children": []any{
map[string]any{
"type": "EnrichedTable",
"data": map[string]any{
"id": "pods-table",
"baseprefix": "/openapi-ui",
"clusterNamePartOfUrl": "{2}",
"customizationId": "factory-node-details-/v1/pods",
"fetchUrl": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/pods",
"labelsSelectorFull": map[string]any{
"pathToLabels": ".spec.selector",
"reqIndex": 0,
},
"pathToItems": ".items",
"withoutControls": false,
},
},
},
},
},
},
}
serviceSpec := createFactorySpec("kube-service-details", []any{"service-sidebar"}, []any{"/api/clusters/{2}/k8s/api/v1/namespaces/{3}/services/{6}"}, serviceHeader, serviceTabs)
// Ingress details factory
ingressHeader := map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "header-row",
"align": "center",
"gap": 6,
"style": map[string]any{
"marginBottom": float64(24),
},
},
"children": []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "badge-ingress",
"text": "I",
"title": "ingresses",
"style": map[string]any{
"backgroundColor": "#2e7dff",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": float64(20),
"fontWeight": float64(400),
"lineHeight": "24px",
"minWidth": float64(24),
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
},
map[string]any{
"type": "parsedText",
"data": map[string]any{
"id": "ingress-name",
"text": "{reqsJsonPath[0]['.metadata.name']['-']}",
"style": map[string]any{
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": float64(20),
"lineHeight": "24px",
},
},
},
},
}
ingressTabs := []any{
map[string]any{
"key": "details",
"label": "Details",
"children": []any{
contentCard("details-card", map[string]any{
"marginBottom": float64(24),
}, []any{
antdRow("details-grid", []any{48, 12}, []any{
antdCol("col-left", 12, []any{
antdFlexVertical("col-left-stack", 24, []any{
antdFlexVertical("meta-name-block", 4, []any{
antdText("meta-name-label", true, "Name", nil),
parsedText("meta-name-value", "{reqsJsonPath[0]['.metadata.name']['-']}", nil),
}),
antdFlexVertical("meta-namespace-block", 8, []any{
antdText("meta-namespace-label", true, "Namespace", nil),
map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "namespace-row",
"align": "center",
"gap": 6,
},
"children": []any{
createUnifiedBadgeFromKind("ns-badge", "Namespace", "namespace", BadgeSizeMedium),
antdLink("namespace-link",
"{reqsJsonPath[0]['.metadata.namespace']['-']}",
"/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace",
),
},
},
}),
antdFlexVertical("meta-created-block", 4, []any{
antdText("time-label", true, "Created", nil),
antdFlex("time-block", 6, []any{
antdText("time-icon", false, "🌐", nil),
parsedTextWithFormatter("time-value", "{reqsJsonPath[0]['.metadata.creationTimestamp']['-']}", "timestamp"),
}),
}),
}),
}),
antdCol("col-right", 12, []any{
antdFlexVertical("col-right-stack", 24, []any{
antdFlexVertical("status-ingress-ip", 4, []any{
antdText("status-ingress-ip-label", true, "LoadBalancer IP", nil),
parsedText("status-ingress-ip-value", "{reqsJsonPath[0]['.status.loadBalancer.ingress[0].ip']['-']}", nil),
}),
antdFlexVertical("status-ingress-hostname", 4, []any{
antdText("status-ingress-hostname-label", true, "LoadBalancer Hostname", nil),
parsedText("status-ingress-hostname-value", "{reqsJsonPath[0]['.status.loadBalancer.ingress[0].hostname']['-']}", nil),
}),
}),
}),
}),
spacer("rules-title-spacer", float64(16)),
antdText("rules-title", true, "Rules", map[string]any{
"fontSize": float64(20),
}),
spacer("rules-spacer", float64(8)),
map[string]any{
"type": "EnrichedTable",
"data": map[string]any{
"id": "rules-table",
"fetchUrl": "/api/clusters/{2}/k8s/apis/networking.k8s.io/v1/namespaces/{3}/ingresses/{6}",
"clusterNamePartOfUrl": "{2}",
"customizationId": "factory-kube-ingress-details-rules",
"baseprefix": "/openapi-ui",
"withoutControls": true,
"pathToItems": []any{"spec", "rules"},
},
},
}),
},
},
map[string]any{
"key": "yaml",
"label": "YAML",
"children": []any{
map[string]any{
"type": "YamlEditorSingleton",
"data": map[string]any{
"id": "yaml-editor",
"cluster": "{2}",
"isNameSpaced": true,
"type": "builtin",
"typeName": "ingresses",
"prefillValuesRequestIndex": float64(0),
"substractHeight": float64(400),
},
},
},
},
}
ingressSpec := createFactorySpec("kube-ingress-details", []any{"ingress-sidebar"}, []any{"/api/clusters/{2}/k8s/apis/networking.k8s.io/v1/namespaces/{3}/ingresses/{6}"}, ingressHeader, ingressTabs)
// Workloadmonitor details factory
workloadmonitorHeader := createWorkloadmonitorHeader()
workloadmonitorTabs := []any{
map[string]any{
"key": "details",
"label": "Details",
"children": []any{
contentCard("details-card", map[string]any{
"marginBottom": float64(24),
}, []any{
antdRow("details-grid", []any{48, 12}, []any{
antdCol("col-left", 12, []any{
antdFlexVertical("col-left-stack", 24, []any{
antdFlexVertical("meta-name-block", 4, []any{
antdText("meta-name-label", true, "Name", nil),
parsedText("meta-name-value", "{reqsJsonPath[0]['.metadata.name']['-']}", nil),
}),
antdFlexVertical("meta-namespace-block", 8, []any{
antdText("meta-namespace-label", true, "Namespace", nil),
antdFlex("namespace-row", 6, []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "ns-badge",
"text": "NS",
"style": map[string]any{
"backgroundColor": "#a25792ff",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": 15,
"fontWeight": 400,
"lineHeight": "24px",
"minWidth": 24,
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
},
map[string]any{
"type": "antdLink",
"data": map[string]any{
"id": "namespace-link",
"text": "{reqsJsonPath[0]['.metadata.namespace']['-']}",
"href": "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace",
},
},
}),
}),
antdFlexVertical("meta-created-block", 4, []any{
antdText("time-label", true, "Created", nil),
antdFlex("time-block", 6, []any{
map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "time-icon",
"text": "🌐",
},
},
parsedTextWithFormatter("time-value", "{reqsJsonPath[0]['.metadata.creationTimestamp']['-']}", "timestamp"),
}),
}),
antdFlexVertical("meta-kind-block", 4, []any{
antdText("kind-label", true, "Kind", nil),
parsedText("kind-value", "{reqsJsonPath[0]['.spec.kind']['-']}", nil),
}),
antdFlexVertical("meta-type-block", 4, []any{
antdText("type-label", true, "Type", nil),
parsedText("type-value", "{reqsJsonPath[0]['.spec.type']['-']}", nil),
}),
}),
}),
antdCol("col-right", 12, []any{
antdFlexVertical("col-right-stack", 24, []any{
antdText("params-title", true, "Parameters", map[string]any{
"fontSize": float64(20),
"marginBottom": float64(12),
}),
antdFlexVertical("params-list", 24, []any{
antdFlexVertical("param-version", 4, []any{
antdText("param-version-label", true, "Version", nil),
parsedText("param-version-value", "{reqsJsonPath[0]['.spec.version']['-']}", nil),
}),
antdFlexVertical("param-replicas", 4, []any{
antdText("param-replicas-label", true, "Replicas", nil),
parsedText("param-replicas-value", "{reqsJsonPath[0]['.spec.replicas']['-']}", nil),
}),
antdFlexVertical("param-minreplicas", 4, []any{
antdText("param-minreplicas-label", true, "MinReplicas", nil),
parsedText("param-minreplicas-value", "{reqsJsonPath[0]['.spec.minReplicas']['-']}", nil),
}),
antdFlexVertical("param-available", 4, []any{
antdText("param-available-label", true, "AvailableReplicas", nil),
parsedText("param-available-value", "{reqsJsonPath[0]['.status.availableReplicas']['-']}", nil),
}),
antdFlexVertical("param-observed", 4, []any{
antdText("param-observed-label", true, "ObservedReplicas", nil),
parsedText("param-observed-value", "{reqsJsonPath[0]['.status.observedReplicas']['-']}", nil),
}),
antdFlexVertical("param-operational", 4, []any{
antdText("param-operational-label", true, "Operational", nil),
parsedText("param-operational-value", "{reqsJsonPath[0]['.status.operational']['-']}", nil),
}),
}),
}),
}),
}),
}),
},
},
map[string]any{
"key": "workloads",
"label": "Workloads",
"children": []any{
map[string]any{
"type": "EnrichedTable",
"data": map[string]any{
"id": "workloads-table",
"baseprefix": "/openapi-ui",
"clusterNamePartOfUrl": "{2}",
"customizationId": "factory-details-v1alpha1.cozystack.io.workloads",
"fetchUrl": "/api/clusters/{2}/k8s/apis/cozystack.io/v1alpha1/namespaces/{3}/workloads",
"labelsSelector": map[string]any{
"workloads.cozystack.io/monitor": "{reqs[0]['metadata','name']}",
},
"pathToItems": []any{"items"},
},
},
},
},
map[string]any{
"key": "yaml",
"label": "YAML",
"children": []any{
map[string]any{
"type": "YamlEditorSingleton",
"data": map[string]any{
"id": "yaml-editor",
"cluster": "{2}",
"isNameSpaced": true,
"prefillValuesRequestIndex": 0,
"substractHeight": float64(400),
"type": "builtin",
"typeName": "workloadmonitors",
},
},
},
},
}
workloadmonitorSpec := createFactorySpec("workloadmonitor-details", []any{"workloadmonitor-sidebar"}, []any{"/api/clusters/{2}/k8s/apis/cozystack.io/v1alpha1/namespaces/{3}/workloadmonitors/{6}"}, workloadmonitorHeader, workloadmonitorTabs)
return []*dashboardv1alpha1.Factory{
createFactory("marketplace", marketplaceSpec),
createFactory("namespace-details", namespaceSpec),
createFactory("node-details", nodeSpec),
createFactory("pod-details", podSpec),
createFactory("kube-secret-details", secretSpec),
createFactory("kube-service-details", serviceSpec),
createFactory("kube-ingress-details", ingressSpec),
createFactory("workloadmonitor-details", workloadmonitorSpec),
}
}
// CreateAllNavigations creates all navigation resources using helper functions
func CreateAllNavigations() []*dashboardv1alpha1.Navigation {
return []*dashboardv1alpha1.Navigation{
createNavigation("navigation", map[string]any{
"namespaces": map[string]any{
"change": "/openapi-ui/{selectedCluster}/{value}/factory/marketplace",
"clear": "/openapi-ui/{selectedCluster}/api-table/core.cozystack.io/v1alpha1/tenantnamespaces",
},
}),
}
}
// CreateAllTableUriMappings creates all table URI mapping resources using helper functions
func CreateAllTableUriMappings() []*dashboardv1alpha1.TableUriMapping {
// links are now handled through CustomFormsPrefills
return []*dashboardv1alpha1.TableUriMapping{}
}
// ---------------- Additional helper functions for missing resource types ----------------
// createCustomFormsOverride creates a CustomFormsOverride resource
func createCustomFormsOverride(customizationId string, spec map[string]any) *dashboardv1alpha1.CustomFormsOverride {
// Generate name from customizationId
name := customizationId
if strings.Contains(customizationId, "default-/") {
// For default-/ resources, replace "default-/" with "default-" and slashes with dots
name = strings.ReplaceAll(customizationId, "default-/", "default-")
name = strings.ReplaceAll(name, "/", ".")
}
// Create hidden fields list
hidden := []any{
[]any{"metadata", "creationTimestamp"},
}
// Add namespace to hidden for specific resources in the correct order
if strings.Contains(name, "namespaces") || strings.Contains(name, "nodes") {
hidden = append(hidden, []any{"metadata", "namespace"})
}
// Add remaining hidden fields
hidden = append(hidden, []any{
[]any{"metadata", "deletionGracePeriodSeconds"},
[]any{"metadata", "deletionTimestamp"},
[]any{"metadata", "finalizers"},
[]any{"metadata", "generateName"},
[]any{"metadata", "generation"},
[]any{"metadata", "managedFields"},
[]any{"metadata", "ownerReferences"},
[]any{"metadata", "resourceVersion"},
[]any{"metadata", "selfLink"},
[]any{"metadata", "uid"},
[]any{"kind"},
[]any{"apiVersion"},
[]any{"status"},
}...)
// Create new spec with all required fields including formItems from the original spec
newSpec := map[string]any{
"customizationId": customizationId,
"hidden": hidden,
"schema": map[string]any{},
"strategy": "merge",
}
// Merge caller-provided fields (like formItems) into newSpec
for key, value := range spec {
if key != "customizationId" && key != "hidden" && key != "schema" && key != "strategy" {
newSpec[key] = value
}
}
jsonData, _ := json.Marshal(newSpec)
return &dashboardv1alpha1.CustomFormsOverride{
TypeMeta: metav1.TypeMeta{
APIVersion: "dashboard.cozystack.io/v1alpha1",
Kind: "CustomFormsOverride",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: "",
},
Spec: dashboardv1alpha1.ArbitrarySpec{
JSON: v1.JSON{
Raw: jsonData,
},
},
}
}
// createNavigation creates a Navigation resource
func createNavigation(name string, spec map[string]any) *dashboardv1alpha1.Navigation {
jsonData, _ := json.Marshal(spec)
return &dashboardv1alpha1.Navigation{
TypeMeta: metav1.TypeMeta{
APIVersion: "dashboard.cozystack.io/v1alpha1",
Kind: "Navigation",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: "",
},
Spec: dashboardv1alpha1.ArbitrarySpec{
JSON: v1.JSON{
Raw: jsonData,
},
},
}
}
// createFormItem creates a form item for CustomFormsOverride
func createFormItem(path, label, fieldType string) map[string]any {
return map[string]any{
"path": path,
"label": label,
"type": fieldType,
}
}
// ---------------- Workloadmonitor specific functions ----------------
// createNamespaceHeader creates a header specifically for namespace with correct colors and text
func createNamespaceHeader() map[string]any {
badge := map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "header-badge",
"text": "NS",
"title": "Namespace",
"style": map[string]any{
"backgroundColor": "#a25792ff",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": "20px",
"fontWeight": float64(400),
"lineHeight": "24px",
"minWidth": float64(24),
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
}
nameText := parsedText("header-name", "{reqsJsonPath[0]['.metadata.name']['-']}", map[string]any{
"fontSize": "20px",
"lineHeight": "24px",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
})
return map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "header-row",
"align": "center",
"gap": float64(6),
"style": map[string]any{
"marginBottom": "24px",
},
},
"children": []any{
badge,
nameText,
},
}
}
// createNodeHeader creates a header specifically for node with correct colors and text
func createNodeHeader() map[string]any {
badge := map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "header-badge",
"text": "N",
"title": "nodes",
"style": map[string]any{
"backgroundColor": "#8476d1",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": "20px",
"fontWeight": float64(400),
"lineHeight": "24px",
"minWidth": float64(24),
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
}
nameText := parsedText("header-name", "{reqsJsonPath[0]['.metadata.name']['-']}", map[string]any{
"fontSize": "20px",
"lineHeight": "24px",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
})
statusBlock := map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "status-header-block",
"vertical": true,
"gap": float64(4),
},
"children": []any{
map[string]any{
"type": "StatusText",
"data": map[string]any{
"id": "node-status",
"values": []any{
"{reqsJsonPath[0]['.status.conditions[?(@.status=='True')].reason']['-']}",
},
"criteriaSuccess": "equals",
"strategySuccess": "every",
"valueToCompareSuccess": "KubeletReady",
"criteriaError": "equals",
"strategyError": "every",
"valueToCompareError": []any{
"KernelDeadlock",
"ReadonlyFilesystem",
"NetworkUnavailable",
"MemoryPressure",
"DiskPressure",
"PIDPressure",
},
"successText": "Available",
"errorText": "Unavailable",
"fallbackText": "Progressing",
},
},
},
}
return map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "header-row",
"align": "center",
"gap": float64(6),
"style": map[string]any{
"marginBottom": "24px",
},
},
"children": []any{
badge,
nameText,
statusBlock,
},
}
}
// createPodHeader creates a header specifically for pod with correct colors and text
func createPodHeader() map[string]any {
badge := map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "header-badge",
"text": "P",
"title": "Pods",
"style": map[string]any{
"backgroundColor": "#009596",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": "20px",
"fontWeight": float64(400),
"lineHeight": "24px",
"minWidth": float64(24),
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
}
nameText := parsedText("header-pod-name", "{reqsJsonPath[0]['.metadata.name']['-']}", map[string]any{
"fontSize": "20px",
"lineHeight": "24px",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
})
statusBlock := map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "status-header-block",
"vertical": true,
"gap": float64(4),
},
"children": []any{
map[string]any{
"type": "StatusText",
"data": map[string]any{
"id": "pod-status",
},
},
},
}
return map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "header-row",
"align": "center",
"gap": float64(6),
"style": map[string]any{
"marginBottom": "24px",
},
},
"children": []any{
badge,
nameText,
statusBlock,
},
}
}
// createWorkloadmonitorHeader creates a header specifically for workloadmonitor with correct colors and text
func createWorkloadmonitorHeader() map[string]any {
badge := map[string]any{
"type": "antdText",
"data": map[string]any{
"id": "badge-workloadmonitor",
"text": "W",
"title": "workloadmonitors",
"style": map[string]any{
"backgroundColor": "#c46100",
"borderRadius": "20px",
"color": "#fff",
"display": "inline-block",
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": float64(20),
"fontWeight": float64(400),
"lineHeight": "24px",
"minWidth": float64(24),
"padding": "0 9px",
"textAlign": "center",
"whiteSpace": "nowrap",
},
},
}
nameText := parsedText("workloadmonitor-name", "{reqsJsonPath[0]['.metadata.name']['-']}", map[string]any{
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
"fontSize": float64(20),
"lineHeight": "24px",
})
return map[string]any{
"type": "antdFlex",
"data": map[string]any{
"id": "header-row",
"align": "center",
"gap": float64(6),
"style": map[string]any{
"marginBottom": float64(24),
},
},
"children": []any{
badge,
nameText,
},
}
}
// ---------------- Complete resource creation function ----------------
// CreateAllStaticResources creates all static dashboard resources using helper functions
func CreateAllStaticResources() []client.Object {
var resources []client.Object
// Add all breadcrumbs
for _, breadcrumb := range CreateAllBreadcrumbs() {
resources = append(resources, breadcrumb)
}
// Add all custom column overrides
for _, customColumns := range CreateAllCustomColumnsOverrides() {
resources = append(resources, customColumns)
}
// Add all custom forms overrides
for _, customForms := range CreateAllCustomFormsOverrides() {
resources = append(resources, customForms)
}
// Add all factories
for _, factory := range CreateAllFactories() {
resources = append(resources, factory)
}
// Add all navigations
for _, navigation := range CreateAllNavigations() {
resources = append(resources, navigation)
}
// Add all table URI mappings
for _, tableUriMapping := range CreateAllTableUriMappings() {
resources = append(resources, tableUriMapping)
}
return resources
}