Skip to content

Commit c5610a5

Browse files
authored
Merge branch 'main' into update-e2e-test-versions
2 parents e36db92 + 3748aa9 commit c5610a5

File tree

8 files changed

+308
-189
lines changed

8 files changed

+308
-189
lines changed

controllers/change_coordinators_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@ import (
2424
"context"
2525
"math"
2626

27-
"k8s.io/utils/ptr"
28-
2927
fdbv1beta2 "github.com/FoundationDB/fdb-kubernetes-operator/v2/api/v1beta2"
3028
"github.com/FoundationDB/fdb-kubernetes-operator/v2/internal"
3129
"github.com/FoundationDB/fdb-kubernetes-operator/v2/pkg/fdbadminclient/mock"
3230
. "github.com/onsi/ginkgo/v2"
3331
. "github.com/onsi/gomega"
3432
corev1 "k8s.io/api/core/v1"
33+
"k8s.io/utils/ptr"
3534
)
3635

3736
var _ = Describe("Change coordinators", func() {

controllers/metrics.go

Lines changed: 6 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* This source file is part of the FoundationDB open source project
55
*
6-
* Copyright 2021 Apple Inc. and the FoundationDB project authors
6+
* Copyright 2021-2025 Apple Inc. and the FoundationDB project authors
77
*
88
* Licensed under the Apache License, Version 2.0 (the "License");
99
* you may not use this file except in compliance with the License.
@@ -24,84 +24,11 @@ import (
2424
"context"
2525

2626
fdbv1beta2 "github.com/FoundationDB/fdb-kubernetes-operator/v2/api/v1beta2"
27+
internalMetrics "github.com/FoundationDB/fdb-kubernetes-operator/v2/internal/metrics"
2728
"github.com/prometheus/client_golang/prometheus"
2829
"sigs.k8s.io/controller-runtime/pkg/metrics"
2930
)
3031

31-
var (
32-
descClusterDefaultLabels = []string{"namespace", "name"}
33-
34-
descClusterCreated = prometheus.NewDesc(
35-
"fdb_operator_cluster_created_time",
36-
"Creation time in unix timestamp for Fdb Cluster.",
37-
descClusterDefaultLabels,
38-
nil,
39-
)
40-
41-
descClusterStatus = prometheus.NewDesc(
42-
"fdb_operator_cluster_status",
43-
"status of the Fdb Cluster.",
44-
append(descClusterDefaultLabels, "status_type"),
45-
nil,
46-
)
47-
48-
descClusterLastReconciled = prometheus.NewDesc(
49-
"fdb_operator_cluster_latest_reconciled_status",
50-
"the latest generation that was reconciled.",
51-
descClusterDefaultLabels,
52-
nil,
53-
)
54-
55-
descProcessGroupsToRemove = prometheus.NewDesc(
56-
"fdb_operator_process_groups_to_remove_total",
57-
"the count of process groups that should be removed from the cluster.",
58-
descClusterDefaultLabels,
59-
nil,
60-
)
61-
62-
descProcessGroupsToRemoveWithoutExclusion = prometheus.NewDesc(
63-
"fdb_operator_process_group_to_remove_without_exclusion_total",
64-
"the count of process groups that should be removed from the cluster without excluding.",
65-
descClusterDefaultLabels,
66-
nil,
67-
)
68-
69-
descClusterReconciled = prometheus.NewDesc(
70-
"fdb_operator_cluster_reconciled_status",
71-
"status if the Fdb Cluster is reconciled.",
72-
descClusterDefaultLabels,
73-
nil,
74-
)
75-
76-
descProcessGroupStatus = prometheus.NewDesc(
77-
"fdb_operator_process_group_total",
78-
"the count of Fdb process groups in a specific condition.",
79-
append(descClusterDefaultLabels, "process_class", "condition"),
80-
nil,
81-
)
82-
83-
descProcessGroupMarkedRemoval = prometheus.NewDesc(
84-
"fdb_operator_process_group_marked_removal",
85-
"the count of Fdb process groups that are marked for removal.",
86-
append(descClusterDefaultLabels, "process_class"),
87-
nil,
88-
)
89-
90-
descProcessGroupMarkedExcluded = prometheus.NewDesc(
91-
"fdb_operator_process_group_marked_excluded",
92-
"the count of Fdb process groups that are marked as excluded.",
93-
append(descClusterDefaultLabels, "process_class"),
94-
nil,
95-
)
96-
97-
desDesiredProcessGroups = prometheus.NewDesc(
98-
"fdb_operator_desired_process_group_total",
99-
"the count of the desired Fdb process groups",
100-
append(descClusterDefaultLabels, "process_class"),
101-
nil,
102-
)
103-
)
104-
10532
type fdbClusterCollector struct {
10633
reconciler *FoundationDBClusterReconciler
10734
}
@@ -112,8 +39,8 @@ func newFDBClusterCollector(reconciler *FoundationDBClusterReconciler) *fdbClust
11239

11340
// Describe implements the prometheus.Collector interface
11441
func (c *fdbClusterCollector) Describe(ch chan<- *prometheus.Desc) {
115-
ch <- descClusterCreated
116-
ch <- descClusterStatus
42+
ch <- internalMetrics.DescClusterCreated
43+
ch <- internalMetrics.DescClusterStatus
11744
}
11845

11946
// Collect implements the prometheus.Collector interface
@@ -124,118 +51,14 @@ func (c *fdbClusterCollector) Collect(ch chan<- prometheus.Metric) {
12451
return
12552
}
12653
for _, cluster := range clusters.Items {
127-
collectMetrics(ch, &cluster)
128-
}
129-
}
130-
131-
func collectMetrics(ch chan<- prometheus.Metric, cluster *fdbv1beta2.FoundationDBCluster) {
132-
addConstMetric := func(desc *prometheus.Desc, t prometheus.ValueType, v float64, lv ...string) {
133-
lv = append([]string{cluster.Namespace, cluster.Name}, lv...)
134-
ch <- prometheus.MustNewConstMetric(desc, t, v, lv...)
135-
}
136-
addGauge := func(desc *prometheus.Desc, v float64, lv ...string) {
137-
addConstMetric(desc, prometheus.GaugeValue, v, lv...)
138-
}
139-
// These are the correct metrics with the prefix "fdb_operator"
140-
addGauge(descClusterCreated, float64(cluster.CreationTimestamp.Unix()))
141-
addGauge(descClusterStatus, boolFloat64(cluster.Status.Health.Healthy), "health")
142-
addGauge(descClusterStatus, boolFloat64(cluster.Status.Health.Available), "available")
143-
addGauge(descClusterStatus, boolFloat64(cluster.Status.Health.FullReplication), "replication")
144-
addGauge(
145-
descClusterStatus,
146-
float64(cluster.Status.Health.DataMovementPriority),
147-
"datamovementpriority",
148-
)
149-
addGauge(descClusterLastReconciled, float64(cluster.Status.Generations.Reconciled))
150-
addGauge(
151-
descClusterReconciled,
152-
boolFloat64(cluster.ObjectMeta.Generation == cluster.Status.Generations.Reconciled),
153-
)
154-
addGauge(descProcessGroupsToRemove, float64(len(cluster.Spec.ProcessGroupsToRemove)))
155-
addGauge(
156-
descProcessGroupsToRemoveWithoutExclusion,
157-
float64(len(cluster.Spec.ProcessGroupsToRemoveWithoutExclusion)),
158-
)
159-
160-
// Calculate the process group metrics
161-
conditionMap, removals, exclusions := getProcessGroupMetrics(cluster)
162-
163-
for pclass, conditionMap := range conditionMap {
164-
for condition, count := range conditionMap {
165-
addGauge(descProcessGroupStatus, float64(count), string(pclass), string(condition))
166-
}
167-
168-
addGauge(descProcessGroupMarkedRemoval, float64(removals[pclass]), string(pclass))
169-
addGauge(descProcessGroupMarkedExcluded, float64(exclusions[pclass]), string(pclass))
170-
}
171-
172-
counts, err := cluster.GetProcessCountsWithDefaults()
173-
if err != nil {
174-
return
175-
}
176-
177-
for processCount, count := range counts.Map() {
178-
addGauge(desDesiredProcessGroups, float64(count), string(processCount))
54+
internalMetrics.CollectMetrics(ch, &cluster)
17955
}
18056
}
18157

182-
func getProcessGroupMetrics(
183-
cluster *fdbv1beta2.FoundationDBCluster,
184-
) (map[fdbv1beta2.ProcessClass]map[fdbv1beta2.ProcessGroupConditionType]int, map[fdbv1beta2.ProcessClass]int, map[fdbv1beta2.ProcessClass]int) {
185-
metricMap := map[fdbv1beta2.ProcessClass]map[fdbv1beta2.ProcessGroupConditionType]int{}
186-
removals := map[fdbv1beta2.ProcessClass]int{}
187-
exclusions := map[fdbv1beta2.ProcessClass]int{}
188-
189-
for _, processGroup := range cluster.Status.ProcessGroups {
190-
if _, exits := metricMap[processGroup.ProcessClass]; !exits {
191-
metricMap[processGroup.ProcessClass] = map[fdbv1beta2.ProcessGroupConditionType]int{}
192-
removals[processGroup.ProcessClass] = 0
193-
exclusions[processGroup.ProcessClass] = 0
194-
}
195-
196-
if processGroup.IsMarkedForRemoval() {
197-
removals[processGroup.ProcessClass]++
198-
}
199-
200-
if processGroup.IsExcluded() {
201-
exclusions[processGroup.ProcessClass]++
202-
}
203-
204-
if len(processGroup.ProcessGroupConditions) == 0 {
205-
metricMap[processGroup.ProcessClass][fdbv1beta2.ReadyCondition]++
206-
}
207-
208-
for _, condition := range processGroup.ProcessGroupConditions {
209-
metricMap[processGroup.ProcessClass][condition.ProcessGroupConditionType]++
210-
}
211-
}
212-
213-
// Ensure that all conditions are present
214-
for pClass := range metricMap {
215-
if _, exits := metricMap[pClass]; !exits {
216-
metricMap[pClass] = map[fdbv1beta2.ProcessGroupConditionType]int{}
217-
}
218-
219-
for _, condition := range fdbv1beta2.AllProcessGroupConditionTypes() {
220-
if _, exists := metricMap[pClass][condition]; !exists {
221-
metricMap[pClass][condition] = 0
222-
}
223-
}
224-
}
225-
226-
return metricMap, removals, exclusions
227-
}
228-
22958
// InitCustomMetrics initializes the metrics collectors for the operator.
23059
func InitCustomMetrics(reconciler *FoundationDBClusterReconciler) {
23160
metrics.Registry.MustRegister(
23261
newFDBClusterCollector(reconciler),
62+
internalMetrics.CoordinatorChangesCounter,
23363
)
23464
}
235-
236-
func boolFloat64(b bool) float64 {
237-
if b {
238-
return 1
239-
}
240-
return 0
241-
}

fdbclient/admin_client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import (
3535
"strings"
3636
"time"
3737

38+
"github.com/FoundationDB/fdb-kubernetes-operator/v2/internal/metrics"
39+
3840
fdbv1beta2 "github.com/FoundationDB/fdb-kubernetes-operator/v2/api/v1beta2"
3941
"github.com/FoundationDB/fdb-kubernetes-operator/v2/internal"
4042
"github.com/FoundationDB/fdb-kubernetes-operator/v2/pkg/fdbadminclient"
@@ -779,6 +781,9 @@ func (client *cliAdminClient) ChangeCoordinators(
779781
}
780782
}
781783

784+
// Increment the coordinator changes counter for this cluster
785+
metrics.CoordinatorChangesCounter.WithLabelValues(client.Cluster.Namespace, client.Cluster.Name).
786+
Inc()
782787
return getConnectionStringFromDB(client.fdbLibClient, client.getTimeout())
783788
}
784789

fdbclient/admin_client_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ import (
2929
"time"
3030

3131
fdbv1beta2 "github.com/FoundationDB/fdb-kubernetes-operator/v2/api/v1beta2"
32+
"github.com/FoundationDB/fdb-kubernetes-operator/v2/internal/metrics"
3233
"github.com/go-logr/logr"
3334
. "github.com/onsi/ginkgo/v2"
3435
. "github.com/onsi/gomega"
36+
"github.com/prometheus/client_golang/prometheus"
37+
dto "github.com/prometheus/client_model/go"
3538
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3639
"k8s.io/apimachinery/pkg/types"
3740
"k8s.io/utils/ptr"
@@ -1263,4 +1266,70 @@ protocol fdb00b071010000`,
12631266
Entry("when it is passed in", ptr.To(uint64(1234567890123)), "1234567890123"),
12641267
Entry("when it is not passed in", nil, ""),
12651268
)
1269+
1270+
When("changing the coordinators", func() {
1271+
var cliClient *cliAdminClient
1272+
var mockRunner *mockCommandRunner
1273+
1274+
BeforeEach(func() {
1275+
mockRunner = &mockCommandRunner{
1276+
mockedError: nil,
1277+
mockedOutput: []string{""},
1278+
}
1279+
1280+
cliClient = &cliAdminClient{
1281+
Cluster: &fdbv1beta2.FoundationDBCluster{
1282+
ObjectMeta: metav1.ObjectMeta{
1283+
Name: "test",
1284+
Namespace: "test",
1285+
},
1286+
Spec: fdbv1beta2.FoundationDBClusterSpec{
1287+
Version: "7.3.1",
1288+
},
1289+
Status: fdbv1beta2.FoundationDBClusterStatus{
1290+
RunningVersion: "7.3.1",
1291+
ConnectionString: "abc:dfg@test:4500",
1292+
},
1293+
},
1294+
log: logr.Discard(),
1295+
cmdRunner: mockRunner,
1296+
fdbLibClient: &mockFdbLibClient{
1297+
mockedOutput: []byte("abc:xyz@127.0.01:4500"),
1298+
},
1299+
}
1300+
1301+
_, err := cliClient.ChangeCoordinators([]fdbv1beta2.ProcessAddress{
1302+
{
1303+
IPAddress: net.ParseIP("127.0.0.1"),
1304+
Port: 4500,
1305+
},
1306+
})
1307+
Expect(err).NotTo(HaveOccurred())
1308+
})
1309+
1310+
It("should change the coordinators and increment the counter", func() {
1311+
Expect(mockRunner.receivedArgs).To(HaveLen(1))
1312+
Expect(
1313+
mockRunner.receivedArgs[0][:2],
1314+
).To(Equal([]string{"--exec", "coordinators 127.0.0.1:4500"}))
1315+
1316+
// The counter should have been incremented since a coordinator change occurred
1317+
// in the JustBeforeEach block above
1318+
counterValue := getCounterValue(
1319+
metrics.CoordinatorChangesCounter,
1320+
"test",
1321+
"test",
1322+
)
1323+
Expect(
1324+
counterValue,
1325+
).To(BeNumerically(">", 0), "coordinator changes counter should be incremented after a coordinator change")
1326+
})
1327+
})
12661328
})
1329+
1330+
// getCounterValue extracts the current value of a prometheus counter for specific labels
1331+
func getCounterValue(counter *prometheus.CounterVec, namespace, name string) float64 {
1332+
metric := &dto.Metric{}
1333+
Expect(counter.WithLabelValues(namespace, name).Write(metric)).To(Succeed())
1334+
return metric.Counter.GetValue()
1335+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ require (
3636

3737
require (
3838
github.com/pkg/errors v0.9.1
39+
github.com/prometheus/client_model v0.6.2
3940
github.com/robfig/cron/v3 v3.0.1
4041
)
4142

@@ -86,7 +87,6 @@ require (
8687
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
8788
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
8889
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
89-
github.com/prometheus/client_model v0.6.2 // indirect
9090
github.com/prometheus/procfs v0.15.1 // indirect
9191
github.com/russross/blackfriday/v2 v2.1.0 // indirect
9292
github.com/sagikazarmark/locafero v0.7.0 // indirect

0 commit comments

Comments
 (0)