Skip to content

Commit 90f9295

Browse files
authored
feat(managedmetric)!: new target spec field (#89)
BREAKING CHANGE: the new target GVK type replaces the single GVK fields to implement a consistent API across all metric types Users have to migrate any existing ManagedMetrics manually when upgrading the operator. On-behalf-of: @SAP christopher.junk@sap.com Signed-off-by: Christopher Junk <christopher.junk@sap.com>
1 parent 2a5a7ca commit 90f9295

File tree

5 files changed

+55
-41
lines changed

5 files changed

+55
-41
lines changed

api/v1alpha1/managedmetric_types.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ limitations under the License.
1717
package v1alpha1
1818

1919
import (
20-
"fmt"
21-
2220
"k8s.io/apimachinery/pkg/api/meta"
2321
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2422
)
@@ -30,12 +28,9 @@ type ManagedMetricSpec struct {
3028
// Sets the description that will be used to identify the metric in Dynatrace(or other providers)
3129
// +optional
3230
Description string `json:"description,omitempty"`
33-
// Decide which kind the metric should keep track of (needs to be plural version)
34-
Kind string `json:"kind,omitempty"`
35-
// Define the group of your object that should be instrumented (without version at the end)
36-
Group string `json:"group,omitempty"`
37-
// Define version of the object you want to intrsument
38-
Version string `json:"version,omitempty"`
31+
// Defines which managed resources to observe
32+
// +optional
33+
Target *GroupVersionKind `json:"target,omitempty"`
3934
// Define labels of your object to adapt filters of the query
4035
// +optional
4136
LabelSelector string `json:"labelSelector,omitempty"`
@@ -92,10 +87,10 @@ type ManagedMetricStatus struct {
9287

9388
// GvkToString returns group, version and kind as a string
9489
func (r *ManagedMetric) GvkToString() string {
95-
if r.Spec.Group == "" {
96-
return fmt.Sprintf("/%s, Kind=%s", r.Spec.Version, r.Spec.Kind)
90+
if r.Spec.Target != nil {
91+
return r.Spec.Target.GVK().String()
9792
}
98-
return fmt.Sprintf("%s/%s, Kind=%s", r.Spec.Group, r.Spec.Version, r.Spec.Kind)
93+
return ""
9994
}
10095

10196
// SetConditions sets the conditions for the ManagedMetric

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/metrics-operator/embedded/crds/metrics.openmcp.cloud_managedmetrics.yaml

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,10 @@ spec:
6969
description: Define fields of your object to adapt filters of the
7070
query
7171
type: string
72-
group:
73-
description: Define the group of your object that should be instrumented
74-
(without version at the end)
75-
type: string
7672
interval:
7773
default: 10m
7874
description: Define in what interval the query should be recorded
7975
type: string
80-
kind:
81-
description: Decide which kind the metric should keep track of (needs
82-
to be plural version)
83-
type: string
8476
labelSelector:
8577
description: Define labels of your object to adapt filters of the
8678
query
@@ -98,9 +90,19 @@ spec:
9890
namespace:
9991
type: string
10092
type: object
101-
version:
102-
description: Define version of the object you want to intrsument
103-
type: string
93+
target:
94+
description: Defines which managed resources to observe
95+
properties:
96+
group:
97+
description: Define the group of your object that should be instrumented
98+
type: string
99+
kind:
100+
description: Define the kind of the object that should be instrumented
101+
type: string
102+
version:
103+
description: Define version of the object you want to be instrumented
104+
type: string
105+
type: object
104106
type: object
105107
status:
106108
description: ManagedMetricStatus defines the observed state of ManagedMetric

internal/orchestrator/managedhandler.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,9 @@ func (h *ManagedHandler) getManagedResources(ctx context.Context) ([]Managed, er
174174
if !crdv.Served {
175175
continue
176176
}
177-
// only use the metric target version if provided
178-
if h.metric.Spec.Version != "" && crdv.Name != h.metric.Spec.Version {
177+
// drop versions that don't match the user provided target
178+
target := h.metric.Spec.Target
179+
if target != nil && target.Version != "" && target.Version != crdv.Name {
179180
continue
180181
}
181182
versionsToRetrieve = append(versionsToRetrieve, crdv.Name)
@@ -249,17 +250,26 @@ type ClusterResourceStatus struct {
249250
}
250251

251252
func (h *ManagedHandler) matchesGroupVersionKind(crd apiextensionsv1.CustomResourceDefinition) bool {
253+
target := h.metric.Spec.Target
254+
// if the user does not specify a GVK target, any managed CRD is considered a match
255+
if target == nil {
256+
return true
257+
}
258+
// CRDs may define multi-version APIs
259+
// we consider a version to be a match if it exists in a CRD
252260
crdVersions := make([]string, 0, len(crd.Spec.Versions))
253261
for _, version := range crd.Spec.Versions {
254262
crdVersions = append(crdVersions, version.Name)
255263
}
256-
if h.metric.Spec.Version != "" && !slices.Contains(crdVersions, h.metric.Spec.Version) {
264+
// if the user specifies a target, we consider each GVK attribute and check if it matches the user value
265+
// if the user does not specify a single GVK part, that part is considered unconditional and always a match
266+
if target.Version != "" && !slices.Contains(crdVersions, target.Version) {
257267
return false
258268
}
259-
if h.metric.Spec.Group != "" && crd.Spec.Group != h.metric.Spec.Group {
269+
if target.Group != "" && target.Group != crd.Spec.Group {
260270
return false
261271
}
262-
if h.metric.Spec.Kind != "" && crd.Spec.Names.Kind != h.metric.Spec.Kind {
272+
if target.Kind != "" && target.Kind != crd.Spec.Names.Kind {
263273
return false
264274
}
265275
return true

internal/orchestrator/managedhandler_test.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ func TestGetManagedResources(t *testing.T) {
7171

7272
tests := []struct {
7373
name string
74-
filter schema.GroupVersionKind
74+
gvkTarget schema.GroupVersionKind
7575
clusterCRDs []string
7676
clusterResources []string
7777
wantResources []string
7878
}{
7979
{
80-
name: "fully qualified target spec",
81-
filter: k8sObjectGVK,
80+
name: "fully qualified target spec",
81+
gvkTarget: k8sObjectGVK,
8282
clusterCRDs: []string{
8383
managedAndServedCRD(k8sObjectGVK),
8484
managedAndServedCRD(k8sObjectCollectionGVK),
@@ -95,7 +95,7 @@ func TestGetManagedResources(t *testing.T) {
9595
},
9696
{
9797
name: "group version target",
98-
filter: schema.GroupVersionKind{
98+
gvkTarget: schema.GroupVersionKind{
9999
Group: k8sObjectGVK.Group,
100100
Version: k8sObjectGVK.Version,
101101
},
@@ -118,7 +118,7 @@ func TestGetManagedResources(t *testing.T) {
118118
},
119119
{
120120
name: "version target",
121-
filter: schema.GroupVersionKind{
121+
gvkTarget: schema.GroupVersionKind{
122122
Version: k8sObjectGVK.Version,
123123
},
124124
clusterCRDs: []string{
@@ -140,8 +140,8 @@ func TestGetManagedResources(t *testing.T) {
140140
),
141141
},
142142
{
143-
name: "unqualified target",
144-
filter: schema.GroupVersionKind{},
143+
name: "unqualified target",
144+
gvkTarget: schema.GroupVersionKind{},
145145
clusterCRDs: []string{
146146
managedAndServedCRD(k8sObjectGVK),
147147
managedAndServedCRD(k8sObjectCollectionGVK),
@@ -162,8 +162,8 @@ func TestGetManagedResources(t *testing.T) {
162162
),
163163
},
164164
{
165-
name: "unmanaged custom resources get filtered out",
166-
filter: schema.GroupVersionKind{},
165+
name: "unmanaged custom resources get filtered out",
166+
gvkTarget: schema.GroupVersionKind{},
167167
clusterCRDs: []string{
168168
unmanagedCRD(k8sObjectGVK),
169169
managedAndServedCRD(k8sObjectCollectionGVK),
@@ -182,8 +182,8 @@ func TestGetManagedResources(t *testing.T) {
182182
),
183183
},
184184
{
185-
name: "unserved custom resources are not retrievable",
186-
filter: schema.GroupVersionKind{},
185+
name: "unserved custom resources are not retrievable",
186+
gvkTarget: schema.GroupVersionKind{},
187187
clusterCRDs: []string{
188188
unservedCRD(k8sObjectGVK),
189189
managedAndServedCRD(k8sObjectCollectionGVK),
@@ -211,9 +211,11 @@ func TestGetManagedResources(t *testing.T) {
211211
dCli: setupFakeDynamicClient(t, tt.clusterResources),
212212
metric: v1alpha1.ManagedMetric{
213213
Spec: v1alpha1.ManagedMetricSpec{
214-
Kind: tt.filter.Kind,
215-
Group: tt.filter.Group,
216-
Version: tt.filter.Version,
214+
Target: &v1alpha1.GroupVersionKind{
215+
Group: tt.gvkTarget.Group,
216+
Version: tt.gvkTarget.Version,
217+
Kind: tt.gvkTarget.Kind,
218+
},
217219
},
218220
},
219221
}

0 commit comments

Comments
 (0)