/
rhmicr_metrics.go
110 lines (93 loc) · 3.6 KB
/
rhmicr_metrics.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package common
import (
goctx "context"
"fmt"
"regexp"
"strings"
corev1 "k8s.io/api/core/v1"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
func TestRHMICRMetrics(t TestingTB, ctx *TestingContext) {
rhmi, err := GetRHMI(ctx.Client, true)
if err != nil {
t.Fatalf("error getting RHMI CR: %v", err)
}
rhmiOperatorPod, err := getRHMIOperatorPod(ctx)
if err != nil {
t.Fatalf("error getting rhmi-operator pod: %v", err)
}
output, err := execToPod("curl --silent localhost:8383/metrics",
rhmiOperatorPod.Name,
RHOAMOperatorNamespace,
"rhmi-operator",
ctx)
if err != nil {
t.Fatalf("failed to exec to prometheus pod: %v", err)
}
// check if rhoam_status is present
rhoamStatusMetricPresent := regexp.MustCompile(`rhoam_status{.*}`)
if !rhoamStatusMetricPresent.MatchString(output) {
t.Fatalf("rhoam_status metric is not present. Metrics output:\n%v", output)
}
// check if the metric labels matches rhmi CR
stringRHOAMStatus := rhoamStatusMetricPresent.FindString(output)
labels := parsePrometheusMetricToMap(stringRHOAMStatus, "rhoam_status")
if labels["stage"] != string(rhmi.Status.Stage) {
t.Fatalf("rhoam_status metric stage does not match current stage: %s != %s", labels["stage"], string(rhmi.Status.Stage))
}
// check if rhoam_spec is present
rhoamInfoMetricPresent := regexp.MustCompile(`rhoam_spec{.*}`)
if !rhoamInfoMetricPresent.MatchString(output) {
t.Fatalf("rhoam_spec metric is not present. Metrics output:\n%v", output)
}
// check if rhmi_info metric labels matches with rhmi installation CR
doInfoLabelsMatch := false
matches := rhoamInfoMetricPresent.FindAllString(output, -1)
for _, match := range matches {
infoLabels := parsePrometheusMetricToMap(match, "rhoam_spec")
if infoLabels["use_cluster_storage"] == rhmi.Spec.UseClusterStorage &&
infoLabels["master_url"] == rhmi.Spec.MasterURL &&
infoLabels["installation_type"] == rhmi.Spec.Type &&
infoLabels["operator_name"] == rhmi.GetName() &&
infoLabels["namespace"] == rhmi.GetNamespace() &&
infoLabels["namespace_prefix"] == rhmi.Spec.NamespacePrefix &&
infoLabels["operators_in_product_namespace"] == fmt.Sprintf("%t", rhmi.Spec.OperatorsInProductNamespace) &&
infoLabels["routing_subdomain"] == rhmi.Spec.RoutingSubdomain &&
infoLabels["self_signed_certs"] == fmt.Sprintf("%t", rhmi.Spec.SelfSignedCerts) {
doInfoLabelsMatch = true
break
}
}
if !doInfoLabelsMatch {
t.Fatalf("rhmi_info metric labels do not match with rhmi CR. Labels:\n%v", matches)
}
}
func getRHMIOperatorPod(ctx *TestingContext) (*corev1.Pod, error) {
listOptions := []k8sclient.ListOption{
k8sclient.MatchingLabels(map[string]string{
"name": "rhmi-operator",
}),
k8sclient.InNamespace(RHOAMOperatorNamespace),
}
rhmiOperatorPod := &corev1.PodList{}
err := ctx.Client.List(goctx.TODO(), rhmiOperatorPod, listOptions...)
if err != nil {
return nil, fmt.Errorf("error listing rhmi-operator pod: %v", err)
}
if len(rhmiOperatorPod.Items) == 0 {
return nil, fmt.Errorf("%v pod doesn't exist in namespace: %v (err: %v)", podName, RHOAMOperatorNamespace, err)
}
return &rhmiOperatorPod.Items[0], nil
}
func parsePrometheusMetricToMap(metric, metricName string) map[string]string {
// remove unwanted part of the string
metric = strings.ReplaceAll(metric, fmt.Sprintf("%s{", metricName), "")
metric = strings.ReplaceAll(metric, "}", "")
labelsWithValue := strings.Split(metric, ",")
parsedStrings := map[string]string{}
for _, labelAndValue := range labelsWithValue {
value := strings.Split(labelAndValue, "=")
parsedStrings[value[0]] = strings.ReplaceAll(value[1], "\"", "")
}
return parsedStrings
}