Skip to content

Commit 7e46612

Browse files
authored
use different metric to get deployment name for replicaset (#1421)
1 parent a657b7c commit 7e46612

4 files changed

Lines changed: 130 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Unreleased
99

10+
### bugfix
11+
- Use different metric to get deployment name for ReplicaSet @jamescripter [#1421](https://github.com/newrelic/nri-kubernetes/pull/1421)
12+
1013
### bugfix
1114
- Account for counter resets when computing deltas for CPU CFS periods @jamescripter [#1375](https://github.com/newrelic/nri-kubernetes/pull/1375)
1215

src/ksm/metric/metric.go

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,55 @@ package metric
22

33
import (
44
"errors"
5+
"fmt"
56
"strings"
67

78
"github.com/newrelic/nri-kubernetes/v3/src/definition"
89
"github.com/newrelic/nri-kubernetes/v3/src/prometheus"
910
)
1011

11-
// GetDeploymentNameForReplicaSet returns the name of the deployment has created
12-
// a ReplicaSet.
12+
const deploymentOwnerKind = "Deployment"
13+
14+
var (
15+
ErrOwnerKindInvalid = errors.New("failed to convert owner_kind of ReplicaSet to string")
16+
ErrNotOwnedByDeployment = errors.New("owner_kind of ReplicaSet is not " + deploymentOwnerKind)
17+
ErrOwnerNameInvalid = errors.New("failed to convert owner_name of ReplicaSet to string")
18+
ErrOwnerNameEmpty = errors.New("owner_name of ReplicaSet is empty")
19+
)
20+
21+
// GetDeploymentNameForReplicaSet returns the name of the deployment that owns
22+
// a ReplicaSet, an error if the owner is not a deployment.
1323
func GetDeploymentNameForReplicaSet() definition.FetchFunc {
1424
return func(groupLabel, entityID string, groups definition.RawGroups) (definition.FetchedValue, error) {
15-
replicasetName, err := prometheus.FromLabelValue("kube_replicaset_created", "replicaset")(groupLabel, entityID, groups)
25+
ownerKindRawVal, err := prometheus.FromLabelValue("kube_replicaset_owner", "owner_kind")(groupLabel, entityID, groups)
1626
if err != nil {
17-
return nil, err
27+
return nil, fmt.Errorf("failed to fetch owner_kind of ReplicaSet: %w", err)
28+
}
29+
30+
ownerKind, ok := ownerKindRawVal.(string)
31+
if !ok {
32+
return nil, ErrOwnerKindInvalid
33+
}
34+
35+
if ownerKind != deploymentOwnerKind {
36+
return nil, ErrNotOwnedByDeployment
37+
}
38+
39+
ownerNameRawVal, err := prometheus.FromLabelValue("kube_replicaset_owner", "owner_name")(groupLabel, entityID, groups)
40+
if err != nil {
41+
return nil, fmt.Errorf("failed to fetch owner_name of ReplicaSet: %w", err)
42+
}
43+
44+
ownerName, ok := ownerNameRawVal.(string)
45+
if !ok {
46+
return nil, ErrOwnerNameInvalid
1847
}
1948

20-
if replicasetName.(string) == "" {
21-
return nil, errors.New("error generating deployment name for replica set. replicaset field is empty")
49+
if ownerName == "" {
50+
return nil, ErrOwnerNameEmpty
2251
}
2352

24-
return replicasetNameToDeploymentName(replicasetName.(string)), nil
53+
return ownerName, nil
2554
}
2655
}
2756

src/ksm/metric/metric_test.go

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ var rawGroupWithReplicaSet = definition.RawGroups{
6262
"replicaset": "kube-state-metrics-4044341274",
6363
},
6464
},
65+
"kube_replicaset_owner": prometheus.Metric{
66+
Value: prometheus.GaugeValue(1),
67+
Labels: map[string]string{
68+
"namespace": "kube-system",
69+
"replicaset": "kube-state-metrics-4044341274",
70+
"owner_kind": "Deployment",
71+
"owner_name": "kube-state-metrics",
72+
"owner_is_controller": "true",
73+
},
74+
},
6575
},
6676
},
6777
}
@@ -73,22 +83,98 @@ func TestGetDeploymentNameForReplicaSet_ValidName(t *testing.T) {
7383
assert.Equal(t, expectedValue, fetchedValue)
7484
}
7585

76-
func TestGetDeploymentNameForReplicaSet_ErrorOnEmptyData(t *testing.T) {
86+
func TestGetDeploymentNameForReplicaSet_ErrorOnNonDeploymentOwnerKind(t *testing.T) {
87+
t.Parallel()
88+
raw := definition.RawGroups{
89+
"replicaset": {
90+
"kube-state-metrics-4044341274": definition.RawMetrics{
91+
"kube_replicaset_owner": prometheus.Metric{
92+
Value: prometheus.GaugeValue(1),
93+
Labels: map[string]string{
94+
"namespace": "kube-system",
95+
"replicaset": "kube-state-metrics-4044341274",
96+
"owner_kind": "Rollout", // like argo rollout
97+
"owner_name": "rollout-jf9sdja",
98+
"owner_is_controller": "true",
99+
},
100+
},
101+
},
102+
},
103+
}
104+
fetchedValue, err := GetDeploymentNameForReplicaSet()("replicaset", "kube-state-metrics-4044341274", raw)
105+
assert.EqualError(t, err, "owner_kind of ReplicaSet is not "+deploymentOwnerKind)
106+
assert.Empty(t, fetchedValue)
107+
}
108+
109+
func TestGetDeploymentNameForReplicaSet_ErrorOnEmptyOwnerName(t *testing.T) {
110+
t.Parallel()
111+
raw := definition.RawGroups{
112+
"replicaset": {
113+
"kube-state-metrics-4044341274": definition.RawMetrics{
114+
"kube_replicaset_owner": prometheus.Metric{
115+
Value: prometheus.GaugeValue(1),
116+
Labels: map[string]string{
117+
"namespace": "kube-system",
118+
"replicaset": "kube-state-metrics-4044341274",
119+
"owner_kind": "Deployment",
120+
"owner_name": "",
121+
"owner_is_controller": "true",
122+
},
123+
},
124+
},
125+
},
126+
}
127+
fetchedValue, err := GetDeploymentNameForReplicaSet()("replicaset", "kube-state-metrics-4044341274", raw)
128+
assert.EqualError(t, err, "owner_name of ReplicaSet is empty")
129+
assert.Empty(t, fetchedValue)
130+
}
131+
132+
func TestGetDeploymentNameForReplicaSet_ErrorOnMissingOwnerMetric(t *testing.T) {
133+
t.Parallel()
77134
raw := definition.RawGroups{
78135
"replicaset": {
79136
"kube-state-metrics-4044341274": definition.RawMetrics{
80137
"kube_replicaset_created": prometheus.Metric{
81-
Value: prometheus.GaugeValue(1507117436),
138+
Value: prometheus.GaugeValue(1),
139+
Labels: map[string]string{
140+
"namespace": "kube-system",
141+
"replicaset": "kube-state-metrics-4044341274",
142+
},
143+
},
144+
},
145+
},
146+
}
147+
fetchedValue, err := GetDeploymentNameForReplicaSet()("replicaset", "kube-state-metrics-4044341274", raw)
148+
assert.EqualError(t, err, "failed to fetch owner_kind of ReplicaSet: metric \"kube_replicaset_owner\" not found")
149+
assert.Empty(t, fetchedValue)
150+
}
151+
152+
func TestGetDeploymentNameForReplicaSet_ErrorOnMissingOwnerNameMetric(t *testing.T) {
153+
t.Parallel()
154+
raw := definition.RawGroups{
155+
"replicaset": {
156+
"kube-state-metrics-4044341274": definition.RawMetrics{
157+
"kube_replicaset_created": prometheus.Metric{
158+
Value: prometheus.GaugeValue(1),
159+
Labels: map[string]string{
160+
"namespace": "kube-system",
161+
"replicaset": "kube-state-metrics-4044341274",
162+
},
163+
},
164+
"kube_replicaset_owner": prometheus.Metric{
165+
Value: prometheus.GaugeValue(1),
82166
Labels: map[string]string{
83167
"namespace": "kube-system",
84-
"replicaset": "",
168+
"replicaset": "kube-state-metrics-4044341274",
169+
"owner_kind": "Deployment",
170+
// unexpected: this metric should have owner_name but it's missing
85171
},
86172
},
87173
},
88174
},
89175
}
90176
fetchedValue, err := GetDeploymentNameForReplicaSet()("replicaset", "kube-state-metrics-4044341274", raw)
91-
assert.EqualError(t, err, "error generating deployment name for replica set. replicaset field is empty")
177+
assert.EqualError(t, err, "failed to fetch owner_name of ReplicaSet: label \"owner_name\" not found on metric \"kube_replicaset_owner\": label not found on metric")
92178
assert.Empty(t, fetchedValue)
93179
}
94180

src/metric/definition.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ var KSMSpecs = definition.SpecGroups{
685685
// namespace is here for backwards compatibility, we should use the namespaceName
686686
{Name: "namespace", ValueFunc: prometheus.FromLabelValue("kube_replicaset_created", "namespace"), Type: sdkMetric.ATTRIBUTE},
687687
{Name: "namespaceName", ValueFunc: prometheus.FromLabelValue("kube_replicaset_created", "namespace"), Type: sdkMetric.ATTRIBUTE},
688-
{Name: "deploymentName", ValueFunc: ksmMetric.GetDeploymentNameForReplicaSet(), Type: sdkMetric.ATTRIBUTE},
688+
{Name: "deploymentName", ValueFunc: ksmMetric.GetDeploymentNameForReplicaSet(), Type: sdkMetric.ATTRIBUTE, Optional: true},
689689
{Name: "label.*", ValueFunc: prometheus.FromMetricWithPrefixedLabels("kube_replicaset_labels", "label"), Type: sdkMetric.ATTRIBUTE},
690690
{Name: "ownerName", ValueFunc: prometheus.FromLabelValue("kube_replicaset_owner", "owner_name"), Type: sdkMetric.ATTRIBUTE},
691691
{Name: "ownerKind", ValueFunc: prometheus.FromLabelValue("kube_replicaset_owner", "owner_kind"), Type: sdkMetric.ATTRIBUTE},

0 commit comments

Comments
 (0)