mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-10 00:14:38 +00:00
Share one Resource scaffold across namespaced Kubernetes adapters
The k8s workload/config adapters in unifiedresources each hand-rolled the same Resource literal (Technology, LastSeen, UpdatedAt, Kubernetes facet, label tags) plus namespacedKubernetesIdentity return; dupl flagged the StatefulSet/Job and ReplicaSet/DaemonSet clones. Fold the scaffold into namespacedKubernetesResource and delegate all 19 namespaced adapters (Service included) to it; cluster-scoped kinds (PV, StorageClass, Namespace) keep bespoke identity construction. Contract: unified-resources Extension Points now name the shared scaffold as the way new namespaced kinds assemble resources. Proof: new TestNamespacedKubernetesResourceScaffold pins the scaffold fields and namespaced hostname identity. Full internal/unifiedresources test suite passes.
This commit is contained in:
parent
f4d57c6836
commit
74417de150
3 changed files with 87 additions and 203 deletions
|
|
@ -500,6 +500,17 @@ AI-only summary payloads, or page-local heuristics.
|
|||
`mockmode.IsEnabled()` and scales with the deployment's
|
||||
ready/desired/available replica state so degraded deployments read as
|
||||
elevated pressure on the surviving replicas.
|
||||
Namespaced Kubernetes adapters share one Resource scaffold: a new
|
||||
namespaced kind populates its kind-specific `K8sData` fields (after
|
||||
`baseKubernetesData`) and delegates Resource assembly and identity to
|
||||
`namespacedKubernetesResource(cluster, clusterName, namespace, name,
|
||||
resourceType, status, data, labels)` in
|
||||
`internal/unifiedresources/adapters.go` instead of hand-rolling the
|
||||
`Resource{...}` literal plus `namespacedKubernetesIdentity` return.
|
||||
The scaffold owns `Technology: "kubernetes"`, `LastSeen` from the
|
||||
cluster, `UpdatedAt`, the `Kubernetes` facet pointer, and label-derived
|
||||
tags; only cluster-scoped or non-namespaced kinds (cluster, node, PV,
|
||||
StorageClass, namespace itself) keep bespoke identity construction.
|
||||
5. Add platform registry, resolution, host-dedup, or monitored-system
|
||||
projection behavior through `internal/unifiedresources/registry.go`,
|
||||
`internal/unifiedresources/resolve.go`,
|
||||
|
|
|
|||
|
|
@ -2580,17 +2580,24 @@ func resourceFromKubernetesReplicaSet(cluster models.KubernetesCluster, replicaS
|
|||
data.OwnerKind = replicaSet.OwnerKind
|
||||
data.OwnerName = replicaSet.OwnerName
|
||||
data.Labels = labels
|
||||
return namespacedKubernetesResource(cluster, clusterName, replicaSet.Namespace, replicaSet.Name, ResourceTypeK8sReplicaSet, statusFromKubernetesReplicaSet(replicaSet), data, labels)
|
||||
}
|
||||
|
||||
// namespacedKubernetesResource assembles the Resource scaffold and namespaced
|
||||
// identity shared by kubernetes adapters once the kind-specific K8sData fields
|
||||
// are populated.
|
||||
func namespacedKubernetesResource(cluster models.KubernetesCluster, clusterName, namespace, name string, resourceType ResourceType, status ResourceStatus, data K8sData, labels map[string]string) (Resource, ResourceIdentity) {
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sReplicaSet,
|
||||
Type: resourceType,
|
||||
Technology: "kubernetes",
|
||||
Name: replicaSet.Name,
|
||||
Status: statusFromKubernetesReplicaSet(replicaSet),
|
||||
Name: name,
|
||||
Status: status,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, replicaSet.Namespace, replicaSet.Name)
|
||||
return resource, namespacedKubernetesIdentity(clusterName, namespace, name)
|
||||
}
|
||||
|
||||
func baseKubernetesData(cluster models.KubernetesCluster, clusterName, resourceKind string, capabilities *K8sMetricCapabilities) K8sData {
|
||||
|
|
@ -2647,18 +2654,7 @@ func resourceFromKubernetesService(cluster models.KubernetesCluster, service mod
|
|||
data.Selector = cloneLabelMap(service.Selector)
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(service.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sService,
|
||||
Technology: "kubernetes",
|
||||
Name: service.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
identity := namespacedKubernetesIdentity(clusterName, service.Namespace, service.Name)
|
||||
return resource, identity
|
||||
return namespacedKubernetesResource(cluster, clusterName, service.Namespace, service.Name, ResourceTypeK8sService, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesStatefulSet(cluster models.KubernetesCluster, statefulSet models.KubernetesStatefulSet, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2675,17 +2671,7 @@ func resourceFromKubernetesStatefulSet(cluster models.KubernetesCluster, statefu
|
|||
data.AvailableReplicas = statefulSet.AvailableReplicas
|
||||
data.ServiceName = statefulSet.ServiceName
|
||||
data.Labels = labels
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sStatefulSet,
|
||||
Technology: "kubernetes",
|
||||
Name: statefulSet.Name,
|
||||
Status: statusFromKubernetesStatefulSet(statefulSet),
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, statefulSet.Namespace, statefulSet.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, statefulSet.Namespace, statefulSet.Name, ResourceTypeK8sStatefulSet, statusFromKubernetesStatefulSet(statefulSet), data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesDaemonSet(cluster models.KubernetesCluster, daemonSet models.KubernetesDaemonSet, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2703,17 +2689,7 @@ func resourceFromKubernetesDaemonSet(cluster models.KubernetesCluster, daemonSet
|
|||
data.NumberUnavailable = daemonSet.NumberUnavailable
|
||||
data.NumberMisscheduled = daemonSet.NumberMisscheduled
|
||||
data.Labels = labels
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sDaemonSet,
|
||||
Technology: "kubernetes",
|
||||
Name: daemonSet.Name,
|
||||
Status: statusFromKubernetesDaemonSet(daemonSet),
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, daemonSet.Namespace, daemonSet.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, daemonSet.Namespace, daemonSet.Name, ResourceTypeK8sDaemonSet, statusFromKubernetesDaemonSet(daemonSet), data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesJob(cluster models.KubernetesCluster, job models.KubernetesJob, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2730,17 +2706,7 @@ func resourceFromKubernetesJob(cluster models.KubernetesCluster, job models.Kube
|
|||
data.StartTime = job.StartTime
|
||||
data.CompletionTime = job.CompletionTime
|
||||
data.Labels = labels
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sJob,
|
||||
Technology: "kubernetes",
|
||||
Name: job.Name,
|
||||
Status: statusFromKubernetesJob(job),
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, job.Namespace, job.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, job.Namespace, job.Name, ResourceTypeK8sJob, statusFromKubernetesJob(job), data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesCronJob(cluster models.KubernetesCluster, cronJob models.KubernetesCronJob, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2756,17 +2722,7 @@ func resourceFromKubernetesCronJob(cluster models.KubernetesCluster, cronJob mod
|
|||
data.LastScheduleTime = cronJob.LastScheduleTime
|
||||
data.LastSuccessfulTime = cronJob.LastSuccessfulTime
|
||||
data.Labels = labels
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sCronJob,
|
||||
Technology: "kubernetes",
|
||||
Name: cronJob.Name,
|
||||
Status: statusFromKubernetesCronJob(cronJob),
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, cronJob.Namespace, cronJob.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, cronJob.Namespace, cronJob.Name, ResourceTypeK8sCronJob, statusFromKubernetesCronJob(cronJob), data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesIngress(cluster models.KubernetesCluster, ingress models.KubernetesIngress, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2781,17 +2737,7 @@ func resourceFromKubernetesIngress(cluster models.KubernetesCluster, ingress mod
|
|||
data.Addresses = append([]string(nil), ingress.Addresses...)
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(ingress.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sIngress,
|
||||
Technology: "kubernetes",
|
||||
Name: ingress.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, ingress.Namespace, ingress.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, ingress.Namespace, ingress.Name, ResourceTypeK8sIngress, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesEndpointSlice(cluster models.KubernetesCluster, slice models.KubernetesEndpointSlice, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2817,17 +2763,7 @@ func resourceFromKubernetesEndpointSlice(cluster models.KubernetesCluster, slice
|
|||
data.ReadyEndpointCount = slice.ReadyEndpointCount
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(slice.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sEndpointSlice,
|
||||
Technology: "kubernetes",
|
||||
Name: slice.Name,
|
||||
Status: statusFromKubernetesEndpointSlice(slice),
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, slice.Namespace, slice.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, slice.Namespace, slice.Name, ResourceTypeK8sEndpointSlice, statusFromKubernetesEndpointSlice(slice), data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesNetworkPolicy(cluster models.KubernetesCluster, policy models.KubernetesNetworkPolicy, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2842,17 +2778,7 @@ func resourceFromKubernetesNetworkPolicy(cluster models.KubernetesCluster, polic
|
|||
data.EgressRuleCount = policy.EgressRuleCount
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(policy.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sNetworkPolicy,
|
||||
Technology: "kubernetes",
|
||||
Name: policy.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, policy.Namespace, policy.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, policy.Namespace, policy.Name, ResourceTypeK8sNetworkPolicy, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesPersistentVolume(cluster models.KubernetesCluster, volume models.KubernetesPersistentVolume, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2902,17 +2828,7 @@ func resourceFromKubernetesPersistentVolumeClaim(cluster models.KubernetesCluste
|
|||
data.VolumeName = claim.VolumeName
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(claim.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sPVC,
|
||||
Technology: "kubernetes",
|
||||
Name: claim.Name,
|
||||
Status: statusFromKubernetesPhase(claim.Phase),
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, claim.Namespace, claim.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, claim.Namespace, claim.Name, ResourceTypeK8sPVC, statusFromKubernetesPhase(claim.Phase), data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesStorageClass(cluster models.KubernetesCluster, class models.KubernetesStorageClass, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2959,17 +2875,7 @@ func resourceFromKubernetesConfigMap(cluster models.KubernetesCluster, configMap
|
|||
data.MetadataOnly = configMap.MetadataOnly
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(configMap.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sConfigMap,
|
||||
Technology: "kubernetes",
|
||||
Name: configMap.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, configMap.Namespace, configMap.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, configMap.Namespace, configMap.Name, ResourceTypeK8sConfigMap, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesSecret(cluster models.KubernetesCluster, secret models.KubernetesSecret, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -2985,17 +2891,7 @@ func resourceFromKubernetesSecret(cluster models.KubernetesCluster, secret model
|
|||
data.MetadataOnly = secret.MetadataOnly
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(secret.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sSecret,
|
||||
Technology: "kubernetes",
|
||||
Name: secret.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, secret.Namespace, secret.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, secret.Namespace, secret.Name, ResourceTypeK8sSecret, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesServiceAccount(cluster models.KubernetesCluster, account models.KubernetesServiceAccount, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -3010,17 +2906,7 @@ func resourceFromKubernetesServiceAccount(cluster models.KubernetesCluster, acco
|
|||
data.ImagePullSecrets = append([]string(nil), account.ImagePullSecrets...)
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(account.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sServiceAccount,
|
||||
Technology: "kubernetes",
|
||||
Name: account.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, account.Namespace, account.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, account.Namespace, account.Name, ResourceTypeK8sServiceAccount, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesRole(cluster models.KubernetesCluster, role models.KubernetesRole, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -3033,17 +2919,7 @@ func resourceFromKubernetesRole(cluster models.KubernetesCluster, role models.Ku
|
|||
data.RuleCount = role.RuleCount
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(role.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sRole,
|
||||
Technology: "kubernetes",
|
||||
Name: role.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, role.Namespace, role.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, role.Namespace, role.Name, ResourceTypeK8sRole, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesClusterRole(cluster models.KubernetesCluster, role models.KubernetesClusterRole, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -3086,17 +2962,7 @@ func resourceFromKubernetesRoleBinding(cluster models.KubernetesCluster, binding
|
|||
data.SubjectKinds = append([]string(nil), binding.SubjectKinds...)
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(binding.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sRoleBinding,
|
||||
Technology: "kubernetes",
|
||||
Name: binding.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, binding.Namespace, binding.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, binding.Namespace, binding.Name, ResourceTypeK8sRoleBinding, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesClusterRoleBinding(cluster models.KubernetesCluster, binding models.KubernetesClusterRoleBinding, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -3139,17 +3005,7 @@ func resourceFromKubernetesResourceQuota(cluster models.KubernetesCluster, quota
|
|||
data.Used = cloneStringMap(quota.Used)
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(quota.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sResourceQuota,
|
||||
Technology: "kubernetes",
|
||||
Name: quota.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, quota.Namespace, quota.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, quota.Namespace, quota.Name, ResourceTypeK8sResourceQuota, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesLimitRange(cluster models.KubernetesCluster, limitRange models.KubernetesLimitRange, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -3162,17 +3018,7 @@ func resourceFromKubernetesLimitRange(cluster models.KubernetesCluster, limitRan
|
|||
data.LimitTypes = append([]string(nil), limitRange.LimitTypes...)
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(limitRange.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sLimitRange,
|
||||
Technology: "kubernetes",
|
||||
Name: limitRange.Name,
|
||||
Status: StatusOnline,
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, limitRange.Namespace, limitRange.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, limitRange.Namespace, limitRange.Name, ResourceTypeK8sLimitRange, StatusOnline, data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesPodDisruptionBudget(cluster models.KubernetesCluster, budget models.KubernetesPodDisruptionBudget, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -3190,17 +3036,7 @@ func resourceFromKubernetesPodDisruptionBudget(cluster models.KubernetesCluster,
|
|||
data.ExpectedPods = budget.ExpectedPods
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(budget.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sPDB,
|
||||
Technology: "kubernetes",
|
||||
Name: budget.Name,
|
||||
Status: statusFromKubernetesPodDisruptionBudget(budget),
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, budget.Namespace, budget.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, budget.Namespace, budget.Name, ResourceTypeK8sPDB, statusFromKubernetesPodDisruptionBudget(budget), data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesHorizontalPodAutoscaler(cluster models.KubernetesCluster, autoscaler models.KubernetesHorizontalPodAutoscaler, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
@ -3219,17 +3055,7 @@ func resourceFromKubernetesHorizontalPodAutoscaler(cluster models.KubernetesClus
|
|||
data.MetricTypes = append([]string(nil), autoscaler.MetricTypes...)
|
||||
data.Labels = labels
|
||||
data.CreatedAt = zeroTimeToPtr(autoscaler.CreatedAt)
|
||||
resource := Resource{
|
||||
Type: ResourceTypeK8sHPA,
|
||||
Technology: "kubernetes",
|
||||
Name: autoscaler.Name,
|
||||
Status: statusFromKubernetesHorizontalPodAutoscaler(autoscaler),
|
||||
LastSeen: cluster.LastSeen,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Kubernetes: &data,
|
||||
Tags: labelsToTags(labels),
|
||||
}
|
||||
return resource, namespacedKubernetesIdentity(clusterName, autoscaler.Namespace, autoscaler.Name)
|
||||
return namespacedKubernetesResource(cluster, clusterName, autoscaler.Namespace, autoscaler.Name, ResourceTypeK8sHPA, statusFromKubernetesHorizontalPodAutoscaler(autoscaler), data, labels)
|
||||
}
|
||||
|
||||
func resourceFromKubernetesEvent(cluster models.KubernetesCluster, event models.KubernetesEvent, capabilities *K8sMetricCapabilities) (Resource, ResourceIdentity) {
|
||||
|
|
|
|||
|
|
@ -806,3 +806,50 @@ func TestResourceFromKubernetesDeployment_NilMetricsOutsideMockMode(t *testing.T
|
|||
t.Fatalf("expected nil Metrics outside mock mode (no canonical aggregation yet), got %+v", resource.Metrics)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamespacedKubernetesResourceScaffold(t *testing.T) {
|
||||
lastSeen := time.Date(2026, 6, 1, 12, 0, 0, 0, time.UTC)
|
||||
cluster := models.KubernetesCluster{ID: "cluster-3", Name: "prod", LastSeen: lastSeen}
|
||||
labels := map[string]string{"app": "ingest"}
|
||||
data := baseKubernetesData(cluster, "prod", "Job", nil)
|
||||
data.Namespace = "pipelines"
|
||||
|
||||
resource, identity := namespacedKubernetesResource(cluster, "prod", "pipelines", "nightly", ResourceTypeK8sJob, StatusOnline, data, labels)
|
||||
|
||||
if resource.Type != ResourceTypeK8sJob {
|
||||
t.Fatalf("type = %q, want %q", resource.Type, ResourceTypeK8sJob)
|
||||
}
|
||||
if resource.Technology != "kubernetes" {
|
||||
t.Fatalf("technology = %q, want kubernetes", resource.Technology)
|
||||
}
|
||||
if resource.Name != "nightly" {
|
||||
t.Fatalf("name = %q, want nightly", resource.Name)
|
||||
}
|
||||
if resource.Status != StatusOnline {
|
||||
t.Fatalf("status = %q, want %q", resource.Status, StatusOnline)
|
||||
}
|
||||
if !resource.LastSeen.Equal(lastSeen) {
|
||||
t.Fatalf("lastSeen = %s, want cluster lastSeen %s", resource.LastSeen, lastSeen)
|
||||
}
|
||||
if resource.UpdatedAt.IsZero() {
|
||||
t.Fatal("expected UpdatedAt to be stamped")
|
||||
}
|
||||
if resource.Kubernetes == nil || resource.Kubernetes.Namespace != "pipelines" {
|
||||
t.Fatalf("expected Kubernetes facet with namespace, got %+v", resource.Kubernetes)
|
||||
}
|
||||
if len(resource.Tags) == 0 {
|
||||
t.Fatal("expected label-derived tags on the scaffold")
|
||||
}
|
||||
wantHostnames := []string{"nightly", "pipelines/nightly", "prod:nightly"}
|
||||
if len(identity.Hostnames) != len(wantHostnames) {
|
||||
t.Fatalf("identity hostnames = %v, want %v", identity.Hostnames, wantHostnames)
|
||||
}
|
||||
for i, want := range wantHostnames {
|
||||
if identity.Hostnames[i] != want {
|
||||
t.Fatalf("identity hostnames[%d] = %q, want %q", i, identity.Hostnames[i], want)
|
||||
}
|
||||
}
|
||||
if identity.ClusterName != "prod" {
|
||||
t.Fatalf("identity clusterName = %q, want prod", identity.ClusterName)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue