From d38272061c2e940ccdab3d7815f6592608c6943c Mon Sep 17 00:00:00 2001 From: "Rao, B V Chalapathi" Date: Wed, 7 Jun 2023 20:18:43 +0530 Subject: [PATCH 1/2] KSM Cyclomatic fix for Job and PV files Changes to be committed: modified: internal/store/job.go modified: internal/store/persistentvolume.go --- internal/store/job.go | 762 ++++++++++++++++------------- internal/store/persistentvolume.go | 579 +++++++++++----------- 2 files changed, 717 insertions(+), 624 deletions(-) diff --git a/internal/store/job.go b/internal/store/job.go index 1c0e04c987..fa734192a6 100644 --- a/internal/store/job.go +++ b/internal/store/job.go @@ -44,357 +44,21 @@ var ( func jobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ - *generator.NewFamilyGeneratorWithStability( - descJobAnnotationsName, - descJobAnnotationsHelp, - metric.Gauge, - basemetrics.ALPHA, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", j.Annotations, allowAnnotationsList) - return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: annotationKeys, - LabelValues: annotationValues, - Value: 1, - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - descJobLabelsName, - descJobLabelsHelp, - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) - return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: labelKeys, - LabelValues: labelValues, - Value: 1, - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_info", - "Information about job.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: 1, - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_created", - "Unix creation timestamp", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if !j.CreationTimestamp.IsZero() { - ms = append(ms, &metric.Metric{ - Value: float64(j.CreationTimestamp.Unix()), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_spec_parallelism", - "The maximum desired number of pods the job should run at any given time.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if j.Spec.Parallelism != nil { - ms = append(ms, &metric.Metric{ - Value: float64(*j.Spec.Parallelism), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_spec_completions", - "The desired number of successfully finished pods the job should be run with.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if j.Spec.Completions != nil { - ms = append(ms, &metric.Metric{ - Value: float64(*j.Spec.Completions), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_spec_active_deadline_seconds", - "The duration in seconds relative to the startTime that the job may be active before the system tries to terminate it.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if j.Spec.ActiveDeadlineSeconds != nil { - ms = append(ms, &metric.Metric{ - Value: float64(*j.Spec.ActiveDeadlineSeconds), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_succeeded", - "The number of pods which reached Phase Succeeded.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: float64(j.Status.Succeeded), - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_failed", - "The number of pods which reached Phase Failed and the reason for failure.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - var ms []*metric.Metric - - if float64(j.Status.Failed) == 0 { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: float64(j.Status.Failed), - }, - }, - } - } - - for _, c := range j.Status.Conditions { - condition := c - if condition.Type == v1batch.JobFailed { - reasonKnown := false - for _, reason := range jobFailureReasons { - reasonKnown = reasonKnown || failureReason(&condition, reason) - - // for known reasons - ms = append(ms, &metric.Metric{ - LabelKeys: []string{"reason"}, - LabelValues: []string{reason}, - Value: boolFloat64(failureReason(&condition, reason)), - }) - } - // for unknown reasons - if !reasonKnown { - ms = append(ms, &metric.Metric{ - LabelKeys: []string{"reason"}, - LabelValues: []string{""}, - Value: float64(j.Status.Failed), - }) - } - } - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_active", - "The number of actively running pods.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: float64(j.Status.Active), - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_complete", - "The job has completed its execution.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - for _, c := range j.Status.Conditions { - if c.Type == v1batch.JobComplete { - metrics := addConditionMetrics(c.Status) - for _, m := range metrics { - metric := m - metric.LabelKeys = []string{"condition"} - ms = append(ms, metric) - } - } - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_failed", - "The job has failed its execution.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - for _, c := range j.Status.Conditions { - if c.Type == v1batch.JobFailed { - metrics := addConditionMetrics(c.Status) - for _, m := range metrics { - metric := m - metric.LabelKeys = []string{"condition"} - ms = append(ms, metric) - } - } - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_start_time", - "StartTime represents time when the job was acknowledged by the Job Manager.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if j.Status.StartTime != nil { - ms = append(ms, &metric.Metric{ - - Value: float64(j.Status.StartTime.Unix()), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_completion_time", - "CompletionTime represents time when the job was completed.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - if j.Status.CompletionTime != nil { - ms = append(ms, &metric.Metric{ - - Value: float64(j.Status.CompletionTime.Unix()), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_owner", - "Information about the Job's owner.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - labelKeys := []string{"owner_kind", "owner_name", "owner_is_controller"} - - owners := j.GetOwnerReferences() - - if len(owners) == 0 { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: labelKeys, - LabelValues: []string{"", "", ""}, - Value: 1, - }, - }, - } - } - - ms := make([]*metric.Metric, len(owners)) - - for i, owner := range owners { - if owner.Controller != nil { - ms[i] = &metric.Metric{ - LabelKeys: labelKeys, - LabelValues: []string{owner.Kind, owner.Name, strconv.FormatBool(*owner.Controller)}, - Value: 1, - } - } else { - ms[i] = &metric.Metric{ - LabelKeys: labelKeys, - LabelValues: []string{owner.Kind, owner.Name, "false"}, - Value: 1, - } - } - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), + createJobAnnotations(allowAnnotationsList), + createJobLabels(allowLabelsList), + createJobInfo(), + createJobCreated(), + createJobSpecParallelism(), + createJobSpecCompletions(), + createJobSpecActiveDeadlineSeconds(), + createJobStatusSucceeded(), + createJobStatusFailed(), + createJobStatusActive(), + createJobComplete(), + createJobFailed(), + createJobStatusStartTime(), + createJobStatusCompletionTime(), + createJobOwner(), } } @@ -431,3 +95,399 @@ func failureReason(jc *v1batch.JobCondition, reason string) bool { } return jc.Reason == reason } + +func createJobAnnotations(allowAnnotationsList []string) generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + descJobAnnotationsName, + descJobAnnotationsHelp, + metric.Gauge, + basemetrics.ALPHA, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", j.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ) +} + +func createJobLabels(allowLabelsList []string) generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + descJobLabelsName, + descJobLabelsHelp, + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: labelKeys, + LabelValues: labelValues, + Value: 1, + }, + }, + } + }), + ) +} + +func createJobInfo() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_info", + "Information about job.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: 1, + }, + }, + } + }), + ) +} + +func createJobCreated() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_created", + "Unix creation timestamp", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if !j.CreationTimestamp.IsZero() { + ms = append(ms, &metric.Metric{ + Value: float64(j.CreationTimestamp.Unix()), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobSpecParallelism() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_spec_parallelism", + "The maximum desired number of pods the job should run at any given time.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if j.Spec.Parallelism != nil { + ms = append(ms, &metric.Metric{ + Value: float64(*j.Spec.Parallelism), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobSpecCompletions() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_spec_completions", + "The desired number of successfully finished pods the job should be run with.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if j.Spec.Completions != nil { + ms = append(ms, &metric.Metric{ + Value: float64(*j.Spec.Completions), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobSpecActiveDeadlineSeconds() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_spec_active_deadline_seconds", + "The duration in seconds relative to the startTime that the job may be active before the system tries to terminate it.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if j.Spec.ActiveDeadlineSeconds != nil { + ms = append(ms, &metric.Metric{ + Value: float64(*j.Spec.ActiveDeadlineSeconds), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobStatusSucceeded() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_succeeded", + "The number of pods which reached Phase Succeeded.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: float64(j.Status.Succeeded), + }, + }, + } + }), + ) +} + +func createJobStatusFailed() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_failed", + "The number of pods which reached Phase Failed and the reason for failure.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + var ms []*metric.Metric + + if float64(j.Status.Failed) == 0 { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: float64(j.Status.Failed), + }, + }, + } + } + + for _, c := range j.Status.Conditions { + condition := c + if condition.Type == v1batch.JobFailed { + reasonKnown := false + for _, reason := range jobFailureReasons { + reasonKnown = reasonKnown || failureReason(&condition, reason) + + // for known reasons + ms = append(ms, &metric.Metric{ + LabelKeys: []string{"reason"}, + LabelValues: []string{reason}, + Value: boolFloat64(failureReason(&condition, reason)), + }) + } + // for unknown reasons + if !reasonKnown { + ms = append(ms, &metric.Metric{ + LabelKeys: []string{"reason"}, + LabelValues: []string{""}, + Value: float64(j.Status.Failed), + }) + } + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobStatusActive() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_active", + "The number of actively running pods.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: float64(j.Status.Active), + }, + }, + } + }), + ) +} + +func createJobComplete() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_complete", + "The job has completed its execution.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + for _, c := range j.Status.Conditions { + if c.Type == v1batch.JobComplete { + metrics := addConditionMetrics(c.Status) + for _, m := range metrics { + metric := m + metric.LabelKeys = []string{"condition"} + ms = append(ms, metric) + } + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobFailed() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_failed", + "The job has failed its execution.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + for _, c := range j.Status.Conditions { + if c.Type == v1batch.JobFailed { + metrics := addConditionMetrics(c.Status) + for _, m := range metrics { + metric := m + metric.LabelKeys = []string{"condition"} + ms = append(ms, metric) + } + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobStatusStartTime() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_start_time", + "StartTime represents time when the job was acknowledged by the Job Manager.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if j.Status.StartTime != nil { + ms = append(ms, &metric.Metric{ + + Value: float64(j.Status.StartTime.Unix()), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobStatusCompletionTime() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_completion_time", + "CompletionTime represents time when the job was completed.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + if j.Status.CompletionTime != nil { + ms = append(ms, &metric.Metric{ + + Value: float64(j.Status.CompletionTime.Unix()), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobOwner() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_owner", + "Information about the Job's owner.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + labelKeys := []string{"owner_kind", "owner_name", "owner_is_controller"} + + owners := j.GetOwnerReferences() + + if len(owners) == 0 { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: labelKeys, + LabelValues: []string{"", "", ""}, + Value: 1, + }, + }, + } + } + + ms := make([]*metric.Metric, len(owners)) + + for i, owner := range owners { + if owner.Controller != nil { + ms[i] = &metric.Metric{ + LabelKeys: labelKeys, + LabelValues: []string{owner.Kind, owner.Name, strconv.FormatBool(*owner.Controller)}, + Value: 1, + } + } else { + ms[i] = &metric.Metric{ + LabelKeys: labelKeys, + LabelValues: []string{owner.Kind, owner.Name, "false"}, + Value: 1, + } + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} diff --git a/internal/store/persistentvolume.go b/internal/store/persistentvolume.go index 35b7ea071a..7f146eaf9a 100644 --- a/internal/store/persistentvolume.go +++ b/internal/store/persistentvolume.go @@ -47,304 +47,337 @@ var ( func persistentVolumeMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ - *generator.NewFamilyGeneratorWithStability( - descPersistentVolumeClaimRefName, - descPersistentVolumeClaimRefHelp, - metric.Gauge, - basemetrics.STABLE, - "", - wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { - claimRef := p.Spec.ClaimRef - - if claimRef == nil { - return &metric.Family{ - Metrics: []*metric.Metric{}, - } - } + createPVClaimRef(), + createPVAnnotations(allowAnnotationsList), + createPVLabels(allowLabelsList), + createPVStatusPhase(), + createPVInfo(), + createPVCapacityBytes(), + createPVCreated(), + } +} + +func wrapPersistentVolumeFunc(f func(*v1.PersistentVolume) *metric.Family) func(interface{}) *metric.Family { + return func(obj interface{}) *metric.Family { + persistentVolume := obj.(*v1.PersistentVolume) + + metricFamily := f(persistentVolume) + + for _, m := range metricFamily.Metrics { + m.LabelKeys, m.LabelValues = mergeKeyValues(descPersistentVolumeLabelsDefaultLabels, []string{persistentVolume.Name}, m.LabelKeys, m.LabelValues) + } + + return metricFamily + } +} + +func createPersistentVolumeListWatch(kubeClient clientset.Interface, ns string, fieldSelector string) cache.ListerWatcher { + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + return kubeClient.CoreV1().PersistentVolumes().List(context.TODO(), opts) + }, + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + return kubeClient.CoreV1().PersistentVolumes().Watch(context.TODO(), opts) + }, + } +} + +func createPVClaimRef() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + descPersistentVolumeClaimRefName, + descPersistentVolumeClaimRefHelp, + metric.Gauge, + basemetrics.STABLE, + "", + wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + claimRef := p.Spec.ClaimRef + + if claimRef == nil { return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: []string{ - "name", - "claim_namespace", - }, - LabelValues: []string{ - p.Spec.ClaimRef.Name, - p.Spec.ClaimRef.Namespace, - }, - Value: 1, - }, - }, + Metrics: []*metric.Metric{}, } - }), - ), - *generator.NewFamilyGeneratorWithStability( - descPersistentVolumeAnnotationsName, - descPersistentVolumeAnnotationsHelp, - metric.Gauge, - basemetrics.ALPHA, - "", - wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { - annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", p.Annotations, allowAnnotationsList) - return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: annotationKeys, - LabelValues: annotationValues, - Value: 1, + } + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: []string{ + "name", + "claim_namespace", }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - descPersistentVolumeLabelsName, - descPersistentVolumeLabelsHelp, - metric.Gauge, - basemetrics.STABLE, - "", - wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { - labelKeys, labelValues := createPrometheusLabelKeysValues("label", p.Labels, allowLabelsList) - return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: labelKeys, - LabelValues: labelValues, - Value: 1, + LabelValues: []string{ + p.Spec.ClaimRef.Name, + p.Spec.ClaimRef.Namespace, }, + Value: 1, }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_persistentvolume_status_phase", - "The phase indicates if a volume is available, bound to a claim, or released by a claim.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { - phase := p.Status.Phase - - if phase == "" { - return &metric.Family{ - Metrics: []*metric.Metric{}, - } - } + }, + } + }), + ) +} - // Set current phase to 1, others to 0 if it is set. - ms := []*metric.Metric{ - { - LabelValues: []string{string(v1.VolumePending)}, - Value: boolFloat64(phase == v1.VolumePending), - }, +func createPVAnnotations(allowAnnotationsList []string) generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + descPersistentVolumeAnnotationsName, + descPersistentVolumeAnnotationsHelp, + metric.Gauge, + basemetrics.ALPHA, + "", + wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", p.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ { - LabelValues: []string{string(v1.VolumeAvailable)}, - Value: boolFloat64(phase == v1.VolumeAvailable), - }, - { - LabelValues: []string{string(v1.VolumeBound)}, - Value: boolFloat64(phase == v1.VolumeBound), - }, - { - LabelValues: []string{string(v1.VolumeReleased)}, - Value: boolFloat64(phase == v1.VolumeReleased), + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, }, + }, + } + }), + ) +} + +func createPVLabels(allowLabelsList []string) generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + descPersistentVolumeLabelsName, + descPersistentVolumeLabelsHelp, + metric.Gauge, + basemetrics.STABLE, + "", + wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + labelKeys, labelValues := createPrometheusLabelKeysValues("label", p.Labels, allowLabelsList) + return &metric.Family{ + Metrics: []*metric.Metric{ { - LabelValues: []string{string(v1.VolumeFailed)}, - Value: boolFloat64(phase == v1.VolumeFailed), + LabelKeys: labelKeys, + LabelValues: labelValues, + Value: 1, }, - } + }, + } + }), + ) +} - for _, m := range ms { - m.LabelKeys = []string{"phase"} - } +func createPVStatusPhase() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_persistentvolume_status_phase", + "The phase indicates if a volume is available, bound to a claim, or released by a claim.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + phase := p.Status.Phase + if phase == "" { return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_persistentvolume_info", - "Information about persistentvolume.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { - var ( - gcePDDiskName, - ebsVolumeID, - azureDiskName, - fcWWIDs, fcLun, fcTargetWWNs, - iscsiTargetPortal, iscsiIQN, iscsiLun, iscsiInitiatorName, - nfsServer, nfsPath, - csiDriver, csiVolumeHandle, - localFS, localPath, - hostPath, hostPathType string - ) - - switch { - case p.Spec.PersistentVolumeSource.GCEPersistentDisk != nil: - gcePDDiskName = p.Spec.PersistentVolumeSource.GCEPersistentDisk.PDName - case p.Spec.PersistentVolumeSource.AWSElasticBlockStore != nil: - ebsVolumeID = p.Spec.PersistentVolumeSource.AWSElasticBlockStore.VolumeID - case p.Spec.PersistentVolumeSource.AzureDisk != nil: - azureDiskName = p.Spec.PersistentVolumeSource.AzureDisk.DiskName - case p.Spec.PersistentVolumeSource.FC != nil: - if p.Spec.PersistentVolumeSource.FC.Lun != nil { - fcLun = strconv.FormatInt(int64(*p.Spec.PersistentVolumeSource.FC.Lun), 10) - } - for _, wwn := range p.Spec.PersistentVolumeSource.FC.TargetWWNs { - if len(fcTargetWWNs) != 0 { - fcTargetWWNs += "," - } - fcTargetWWNs += wwn - } - for _, wwid := range p.Spec.PersistentVolumeSource.FC.WWIDs { - if len(fcWWIDs) != 0 { - fcWWIDs += "," - } - fcWWIDs += wwid - } - case p.Spec.PersistentVolumeSource.ISCSI != nil: - iscsiTargetPortal = p.Spec.PersistentVolumeSource.ISCSI.TargetPortal - iscsiIQN = p.Spec.PersistentVolumeSource.ISCSI.IQN - iscsiLun = strconv.FormatInt(int64(p.Spec.PersistentVolumeSource.ISCSI.Lun), 10) - if p.Spec.PersistentVolumeSource.ISCSI.InitiatorName != nil { - iscsiInitiatorName = *p.Spec.PersistentVolumeSource.ISCSI.InitiatorName - } - case p.Spec.PersistentVolumeSource.NFS != nil: - nfsServer = p.Spec.PersistentVolumeSource.NFS.Server - nfsPath = p.Spec.PersistentVolumeSource.NFS.Path - case p.Spec.PersistentVolumeSource.CSI != nil: - csiDriver = p.Spec.PersistentVolumeSource.CSI.Driver - csiVolumeHandle = p.Spec.PersistentVolumeSource.CSI.VolumeHandle - case p.Spec.PersistentVolumeSource.Local != nil: - localPath = p.Spec.PersistentVolumeSource.Local.Path - if p.Spec.PersistentVolumeSource.Local.FSType != nil { - localFS = *p.Spec.PersistentVolumeSource.Local.FSType - } - case p.Spec.PersistentVolumeSource.HostPath != nil: - hostPath = p.Spec.PersistentVolumeSource.HostPath.Path - if p.Spec.PersistentVolumeSource.HostPath.Type != nil { - hostPathType = string(*p.Spec.PersistentVolumeSource.HostPath.Type) - } + Metrics: []*metric.Metric{}, } + } - return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: []string{ - "storageclass", - "gce_persistent_disk_name", - "ebs_volume_id", - "azure_disk_name", - "fc_wwids", - "fc_lun", - "fc_target_wwns", - "iscsi_target_portal", - "iscsi_iqn", - "iscsi_lun", - "iscsi_initiator_name", - "nfs_server", - "nfs_path", - "csi_driver", - "csi_volume_handle", - "local_path", - "local_fs", - "host_path", - "host_path_type", - }, - LabelValues: []string{ - p.Spec.StorageClassName, - gcePDDiskName, - ebsVolumeID, - azureDiskName, - fcWWIDs, - fcLun, - fcTargetWWNs, - iscsiTargetPortal, - iscsiIQN, - iscsiLun, - iscsiInitiatorName, - nfsServer, - nfsPath, - csiDriver, - csiVolumeHandle, - localPath, - localFS, - hostPath, - hostPathType, - }, - Value: 1, - }, - }, + // Set current phase to 1, others to 0 if it is set. + ms := []*metric.Metric{ + { + LabelValues: []string{string(v1.VolumePending)}, + Value: boolFloat64(phase == v1.VolumePending), + }, + { + LabelValues: []string{string(v1.VolumeAvailable)}, + Value: boolFloat64(phase == v1.VolumeAvailable), + }, + { + LabelValues: []string{string(v1.VolumeBound)}, + Value: boolFloat64(phase == v1.VolumeBound), + }, + { + LabelValues: []string{string(v1.VolumeReleased)}, + Value: boolFloat64(phase == v1.VolumeReleased), + }, + { + LabelValues: []string{string(v1.VolumeFailed)}, + Value: boolFloat64(phase == v1.VolumeFailed), + }, + } + + for _, m := range ms { + m.LabelKeys = []string{"phase"} + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createPVInfo() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_persistentvolume_info", + "Information about persistentvolume.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + var ( + gcePDDiskName, + ebsVolumeID, + azureDiskName, + fcWWIDs, fcLun, fcTargetWWNs, + iscsiTargetPortal, iscsiIQN, iscsiLun, iscsiInitiatorName, + nfsServer, nfsPath, + csiDriver, csiVolumeHandle, + localFS, localPath, + hostPath, hostPathType string + ) + + switch { + case p.Spec.PersistentVolumeSource.GCEPersistentDisk != nil: + gcePDDiskName = p.Spec.PersistentVolumeSource.GCEPersistentDisk.PDName + case p.Spec.PersistentVolumeSource.AWSElasticBlockStore != nil: + ebsVolumeID = p.Spec.PersistentVolumeSource.AWSElasticBlockStore.VolumeID + case p.Spec.PersistentVolumeSource.AzureDisk != nil: + azureDiskName = p.Spec.PersistentVolumeSource.AzureDisk.DiskName + case p.Spec.PersistentVolumeSource.FC != nil: + if p.Spec.PersistentVolumeSource.FC.Lun != nil { + fcLun = strconv.FormatInt(int64(*p.Spec.PersistentVolumeSource.FC.Lun), 10) } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_persistentvolume_capacity_bytes", - "Persistentvolume capacity in bytes.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { - storage := p.Spec.Capacity[v1.ResourceStorage] - return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: float64(storage.Value()), - }, - }, + fcTargetWWNs, fcWWIDs = getWWNsAndIDs(p.Spec.PersistentVolumeSource.FC, fcTargetWWNs, fcWWIDs) + case p.Spec.PersistentVolumeSource.ISCSI != nil: + iscsiTargetPortal = p.Spec.PersistentVolumeSource.ISCSI.TargetPortal + iscsiIQN = p.Spec.PersistentVolumeSource.ISCSI.IQN + iscsiLun = strconv.FormatInt(int64(p.Spec.PersistentVolumeSource.ISCSI.Lun), 10) + if p.Spec.PersistentVolumeSource.ISCSI.InitiatorName != nil { + iscsiInitiatorName = *p.Spec.PersistentVolumeSource.ISCSI.InitiatorName } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_persistentvolume_created", - "Unix creation timestamp", - metric.Gauge, - basemetrics.ALPHA, - "", - wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { - ms := []*metric.Metric{} - - if !p.CreationTimestamp.IsZero() { - ms = append(ms, &metric.Metric{ - LabelKeys: []string{}, - LabelValues: []string{}, - Value: float64(p.CreationTimestamp.Unix()), - }) + case p.Spec.PersistentVolumeSource.NFS != nil: + nfsServer = p.Spec.PersistentVolumeSource.NFS.Server + nfsPath = p.Spec.PersistentVolumeSource.NFS.Path + case p.Spec.PersistentVolumeSource.CSI != nil: + csiDriver = p.Spec.PersistentVolumeSource.CSI.Driver + csiVolumeHandle = p.Spec.PersistentVolumeSource.CSI.VolumeHandle + case p.Spec.PersistentVolumeSource.Local != nil: + localPath = p.Spec.PersistentVolumeSource.Local.Path + if p.Spec.PersistentVolumeSource.Local.FSType != nil { + localFS = *p.Spec.PersistentVolumeSource.Local.FSType } - - return &metric.Family{ - Metrics: ms, + case p.Spec.PersistentVolumeSource.HostPath != nil: + hostPath = p.Spec.PersistentVolumeSource.HostPath.Path + if p.Spec.PersistentVolumeSource.HostPath.Type != nil { + hostPathType = string(*p.Spec.PersistentVolumeSource.HostPath.Type) } - }), - ), - } + } + + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: []string{ + "storageclass", + "gce_persistent_disk_name", + "ebs_volume_id", + "azure_disk_name", + "fc_wwids", + "fc_lun", + "fc_target_wwns", + "iscsi_target_portal", + "iscsi_iqn", + "iscsi_lun", + "iscsi_initiator_name", + "nfs_server", + "nfs_path", + "csi_driver", + "csi_volume_handle", + "local_path", + "local_fs", + "host_path", + "host_path_type", + }, + LabelValues: []string{ + p.Spec.StorageClassName, + gcePDDiskName, + ebsVolumeID, + azureDiskName, + fcWWIDs, + fcLun, + fcTargetWWNs, + iscsiTargetPortal, + iscsiIQN, + iscsiLun, + iscsiInitiatorName, + nfsServer, + nfsPath, + csiDriver, + csiVolumeHandle, + localPath, + localFS, + hostPath, + hostPathType, + }, + Value: 1, + }, + }, + } + }), + ) } -func wrapPersistentVolumeFunc(f func(*v1.PersistentVolume) *metric.Family) func(interface{}) *metric.Family { - return func(obj interface{}) *metric.Family { - persistentVolume := obj.(*v1.PersistentVolume) +func createPVCapacityBytes() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_persistentvolume_capacity_bytes", + "Persistentvolume capacity in bytes.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + storage := p.Spec.Capacity[v1.ResourceStorage] + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: float64(storage.Value()), + }, + }, + } + }), + ) +} - metricFamily := f(persistentVolume) +func createPVCreated() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_persistentvolume_created", + "Unix creation timestamp", + metric.Gauge, + basemetrics.ALPHA, + "", + wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + ms := []*metric.Metric{} - for _, m := range metricFamily.Metrics { - m.LabelKeys, m.LabelValues = mergeKeyValues(descPersistentVolumeLabelsDefaultLabels, []string{persistentVolume.Name}, m.LabelKeys, m.LabelValues) - } + if !p.CreationTimestamp.IsZero() { + ms = append(ms, &metric.Metric{ + LabelKeys: []string{}, + LabelValues: []string{}, + Value: float64(p.CreationTimestamp.Unix()), + }) + } - return metricFamily - } + return &metric.Family{ + Metrics: ms, + } + }), + ) } -func createPersistentVolumeListWatch(kubeClient clientset.Interface, ns string, fieldSelector string) cache.ListerWatcher { - return &cache.ListWatch{ - ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { - return kubeClient.CoreV1().PersistentVolumes().List(context.TODO(), opts) - }, - WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { - return kubeClient.CoreV1().PersistentVolumes().Watch(context.TODO(), opts) - }, +func getWWNsAndIDs(fc *v1.FCVolumeSource, fcTargetWWNs string, fcWWIDs string) (string, string) { + for _, wwn := range fc.TargetWWNs { + if len(fcTargetWWNs) != 0 { + fcTargetWWNs += "," + } + fcTargetWWNs += wwn + } + for _, wwid := range fc.WWIDs { + if len(fcWWIDs) != 0 { + fcWWIDs += "," + } + fcWWIDs += wwid } + return fcTargetWWNs, fcWWIDs } From 37cbe2885fc1b4615d40afbc23092cafbca776d7 Mon Sep 17 00:00:00 2001 From: "Rao, B V Chalapathi" Date: Wed, 7 Jun 2023 20:18:43 +0530 Subject: [PATCH 2/2] KSM Cyclomatic fix for Job and PV files reverting the Persistent volume changes Changes to be committed: modified: internal/store/job.go modified: internal/store/persistentvolume.go --- internal/store/job.go | 762 +++++++++++++++++++++++------------------- 1 file changed, 411 insertions(+), 351 deletions(-) diff --git a/internal/store/job.go b/internal/store/job.go index 1c0e04c987..fa734192a6 100644 --- a/internal/store/job.go +++ b/internal/store/job.go @@ -44,357 +44,21 @@ var ( func jobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ - *generator.NewFamilyGeneratorWithStability( - descJobAnnotationsName, - descJobAnnotationsHelp, - metric.Gauge, - basemetrics.ALPHA, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", j.Annotations, allowAnnotationsList) - return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: annotationKeys, - LabelValues: annotationValues, - Value: 1, - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - descJobLabelsName, - descJobLabelsHelp, - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) - return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: labelKeys, - LabelValues: labelValues, - Value: 1, - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_info", - "Information about job.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: 1, - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_created", - "Unix creation timestamp", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if !j.CreationTimestamp.IsZero() { - ms = append(ms, &metric.Metric{ - Value: float64(j.CreationTimestamp.Unix()), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_spec_parallelism", - "The maximum desired number of pods the job should run at any given time.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if j.Spec.Parallelism != nil { - ms = append(ms, &metric.Metric{ - Value: float64(*j.Spec.Parallelism), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_spec_completions", - "The desired number of successfully finished pods the job should be run with.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if j.Spec.Completions != nil { - ms = append(ms, &metric.Metric{ - Value: float64(*j.Spec.Completions), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_spec_active_deadline_seconds", - "The duration in seconds relative to the startTime that the job may be active before the system tries to terminate it.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if j.Spec.ActiveDeadlineSeconds != nil { - ms = append(ms, &metric.Metric{ - Value: float64(*j.Spec.ActiveDeadlineSeconds), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_succeeded", - "The number of pods which reached Phase Succeeded.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: float64(j.Status.Succeeded), - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_failed", - "The number of pods which reached Phase Failed and the reason for failure.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - var ms []*metric.Metric - - if float64(j.Status.Failed) == 0 { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: float64(j.Status.Failed), - }, - }, - } - } - - for _, c := range j.Status.Conditions { - condition := c - if condition.Type == v1batch.JobFailed { - reasonKnown := false - for _, reason := range jobFailureReasons { - reasonKnown = reasonKnown || failureReason(&condition, reason) - - // for known reasons - ms = append(ms, &metric.Metric{ - LabelKeys: []string{"reason"}, - LabelValues: []string{reason}, - Value: boolFloat64(failureReason(&condition, reason)), - }) - } - // for unknown reasons - if !reasonKnown { - ms = append(ms, &metric.Metric{ - LabelKeys: []string{"reason"}, - LabelValues: []string{""}, - Value: float64(j.Status.Failed), - }) - } - } - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_active", - "The number of actively running pods.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: float64(j.Status.Active), - }, - }, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_complete", - "The job has completed its execution.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - for _, c := range j.Status.Conditions { - if c.Type == v1batch.JobComplete { - metrics := addConditionMetrics(c.Status) - for _, m := range metrics { - metric := m - metric.LabelKeys = []string{"condition"} - ms = append(ms, metric) - } - } - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_failed", - "The job has failed its execution.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - for _, c := range j.Status.Conditions { - if c.Type == v1batch.JobFailed { - metrics := addConditionMetrics(c.Status) - for _, m := range metrics { - metric := m - metric.LabelKeys = []string{"condition"} - ms = append(ms, metric) - } - } - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_start_time", - "StartTime represents time when the job was acknowledged by the Job Manager.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - - if j.Status.StartTime != nil { - ms = append(ms, &metric.Metric{ - - Value: float64(j.Status.StartTime.Unix()), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_status_completion_time", - "CompletionTime represents time when the job was completed.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - ms := []*metric.Metric{} - if j.Status.CompletionTime != nil { - ms = append(ms, &metric.Metric{ - - Value: float64(j.Status.CompletionTime.Unix()), - }) - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), - *generator.NewFamilyGeneratorWithStability( - "kube_job_owner", - "Information about the Job's owner.", - metric.Gauge, - basemetrics.STABLE, - "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { - labelKeys := []string{"owner_kind", "owner_name", "owner_is_controller"} - - owners := j.GetOwnerReferences() - - if len(owners) == 0 { - return &metric.Family{ - Metrics: []*metric.Metric{ - { - LabelKeys: labelKeys, - LabelValues: []string{"", "", ""}, - Value: 1, - }, - }, - } - } - - ms := make([]*metric.Metric, len(owners)) - - for i, owner := range owners { - if owner.Controller != nil { - ms[i] = &metric.Metric{ - LabelKeys: labelKeys, - LabelValues: []string{owner.Kind, owner.Name, strconv.FormatBool(*owner.Controller)}, - Value: 1, - } - } else { - ms[i] = &metric.Metric{ - LabelKeys: labelKeys, - LabelValues: []string{owner.Kind, owner.Name, "false"}, - Value: 1, - } - } - } - - return &metric.Family{ - Metrics: ms, - } - }), - ), + createJobAnnotations(allowAnnotationsList), + createJobLabels(allowLabelsList), + createJobInfo(), + createJobCreated(), + createJobSpecParallelism(), + createJobSpecCompletions(), + createJobSpecActiveDeadlineSeconds(), + createJobStatusSucceeded(), + createJobStatusFailed(), + createJobStatusActive(), + createJobComplete(), + createJobFailed(), + createJobStatusStartTime(), + createJobStatusCompletionTime(), + createJobOwner(), } } @@ -431,3 +95,399 @@ func failureReason(jc *v1batch.JobCondition, reason string) bool { } return jc.Reason == reason } + +func createJobAnnotations(allowAnnotationsList []string) generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + descJobAnnotationsName, + descJobAnnotationsHelp, + metric.Gauge, + basemetrics.ALPHA, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", j.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ) +} + +func createJobLabels(allowLabelsList []string) generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + descJobLabelsName, + descJobLabelsHelp, + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: labelKeys, + LabelValues: labelValues, + Value: 1, + }, + }, + } + }), + ) +} + +func createJobInfo() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_info", + "Information about job.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: 1, + }, + }, + } + }), + ) +} + +func createJobCreated() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_created", + "Unix creation timestamp", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if !j.CreationTimestamp.IsZero() { + ms = append(ms, &metric.Metric{ + Value: float64(j.CreationTimestamp.Unix()), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobSpecParallelism() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_spec_parallelism", + "The maximum desired number of pods the job should run at any given time.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if j.Spec.Parallelism != nil { + ms = append(ms, &metric.Metric{ + Value: float64(*j.Spec.Parallelism), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobSpecCompletions() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_spec_completions", + "The desired number of successfully finished pods the job should be run with.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if j.Spec.Completions != nil { + ms = append(ms, &metric.Metric{ + Value: float64(*j.Spec.Completions), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobSpecActiveDeadlineSeconds() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_spec_active_deadline_seconds", + "The duration in seconds relative to the startTime that the job may be active before the system tries to terminate it.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if j.Spec.ActiveDeadlineSeconds != nil { + ms = append(ms, &metric.Metric{ + Value: float64(*j.Spec.ActiveDeadlineSeconds), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobStatusSucceeded() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_succeeded", + "The number of pods which reached Phase Succeeded.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: float64(j.Status.Succeeded), + }, + }, + } + }), + ) +} + +func createJobStatusFailed() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_failed", + "The number of pods which reached Phase Failed and the reason for failure.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + var ms []*metric.Metric + + if float64(j.Status.Failed) == 0 { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: float64(j.Status.Failed), + }, + }, + } + } + + for _, c := range j.Status.Conditions { + condition := c + if condition.Type == v1batch.JobFailed { + reasonKnown := false + for _, reason := range jobFailureReasons { + reasonKnown = reasonKnown || failureReason(&condition, reason) + + // for known reasons + ms = append(ms, &metric.Metric{ + LabelKeys: []string{"reason"}, + LabelValues: []string{reason}, + Value: boolFloat64(failureReason(&condition, reason)), + }) + } + // for unknown reasons + if !reasonKnown { + ms = append(ms, &metric.Metric{ + LabelKeys: []string{"reason"}, + LabelValues: []string{""}, + Value: float64(j.Status.Failed), + }) + } + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobStatusActive() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_active", + "The number of actively running pods.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: float64(j.Status.Active), + }, + }, + } + }), + ) +} + +func createJobComplete() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_complete", + "The job has completed its execution.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + for _, c := range j.Status.Conditions { + if c.Type == v1batch.JobComplete { + metrics := addConditionMetrics(c.Status) + for _, m := range metrics { + metric := m + metric.LabelKeys = []string{"condition"} + ms = append(ms, metric) + } + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobFailed() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_failed", + "The job has failed its execution.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + for _, c := range j.Status.Conditions { + if c.Type == v1batch.JobFailed { + metrics := addConditionMetrics(c.Status) + for _, m := range metrics { + metric := m + metric.LabelKeys = []string{"condition"} + ms = append(ms, metric) + } + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobStatusStartTime() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_start_time", + "StartTime represents time when the job was acknowledged by the Job Manager.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + + if j.Status.StartTime != nil { + ms = append(ms, &metric.Metric{ + + Value: float64(j.Status.StartTime.Unix()), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobStatusCompletionTime() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_status_completion_time", + "CompletionTime represents time when the job was completed.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + ms := []*metric.Metric{} + if j.Status.CompletionTime != nil { + ms = append(ms, &metric.Metric{ + + Value: float64(j.Status.CompletionTime.Unix()), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createJobOwner() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_job_owner", + "Information about the Job's owner.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + labelKeys := []string{"owner_kind", "owner_name", "owner_is_controller"} + + owners := j.GetOwnerReferences() + + if len(owners) == 0 { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: labelKeys, + LabelValues: []string{"", "", ""}, + Value: 1, + }, + }, + } + } + + ms := make([]*metric.Metric, len(owners)) + + for i, owner := range owners { + if owner.Controller != nil { + ms[i] = &metric.Metric{ + LabelKeys: labelKeys, + LabelValues: []string{owner.Kind, owner.Name, strconv.FormatBool(*owner.Controller)}, + Value: 1, + } + } else { + ms[i] = &metric.Metric{ + LabelKeys: labelKeys, + LabelValues: []string{owner.Kind, owner.Name, "false"}, + Value: 1, + } + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +}