Skip to content

Commit faeeef5

Browse files
feat: make ServiceMonitor API group configurable
Add apiGroup to ServiceMonitorConfig so clusters using Azure Managed Prometheus on AKS can target azmonitoring.coreos.com. Defaults to monitoring.coreos.com and updates RBAC for the alternate API group. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent c258f83 commit faeeef5

5 files changed

Lines changed: 108 additions & 7 deletions

File tree

api/nvidia/v1/clusterpolicy_types.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ type ServiceMonitorConfig struct {
176176
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true
177177
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="Relabelings allows to rewrite labels on metric sets"
178178
Relabelings []*promv1.RelabelConfig `json:"relabelings,omitempty"`
179+
180+
// APIGroup is the API group used for ServiceMonitor CRDs.
181+
// Defaults to monitoring.coreos.com. Set to azmonitoring.coreos.com on AKS
182+
// clusters using Azure Managed Prometheus.
183+
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true
184+
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="API group for ServiceMonitor CRDs"
185+
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.x-descriptors="urn:alm:descriptor:com.tectonic.ui:text"
186+
APIGroup string `json:"apiGroup,omitempty"`
179187
}
180188

181189
// The Alias for backward compatibility
@@ -2446,6 +2454,21 @@ func (sm *ServiceMonitorConfig) IsEnabled() bool {
24462454
return *sm.Enabled
24472455
}
24482456

2457+
// GetAPIGroup returns the API group for ServiceMonitor CRDs.
2458+
func (sm *ServiceMonitorConfig) GetAPIGroup() string {
2459+
if sm != nil && sm.APIGroup != "" {
2460+
return sm.APIGroup
2461+
}
2462+
return DefaultMonitoringAPIGroup
2463+
}
2464+
2465+
const (
2466+
// DefaultMonitoringAPIGroup is the default Prometheus Operator API group.
2467+
DefaultMonitoringAPIGroup = "monitoring.coreos.com"
2468+
// AzureMonitoringAPIGroup is used by Azure Managed Prometheus on AKS.
2469+
AzureMonitoringAPIGroup = "azmonitoring.coreos.com"
2470+
)
2471+
24492472
// IsNLSEnabled returns true if NLS should be used for licensing the driver
24502473
func (l *DriverLicensingConfigSpec) IsNLSEnabled() bool {
24512474
if l.NLSEnabled == nil {

config/rbac/role.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ rules:
117117
- patch
118118
- update
119119
- watch
120+
- apiGroups:
121+
- azmonitoring.coreos.com
122+
resources:
123+
- servicemonitors
124+
verbs:
125+
- create
126+
- delete
127+
- get
128+
- list
129+
- patch
130+
- update
131+
- watch
120132
- apiGroups:
121133
- node.k8s.io
122134
resources:

controllers/object_controls.go

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ import (
3939
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
4040
apierrors "k8s.io/apimachinery/pkg/api/errors"
4141
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
42+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
43+
"k8s.io/apimachinery/pkg/runtime"
4244
"k8s.io/apimachinery/pkg/runtime/schema"
4345
"k8s.io/apimachinery/pkg/types"
4446
"k8s.io/apimachinery/pkg/util/intstr"
@@ -5049,6 +5051,59 @@ func applyServiceMonitorCustomEdits(desiredState *gpuv1.ServiceMonitorConfig, cu
50495051
}
50505052
}
50515053

5054+
func serviceMonitorCRDName(apiGroup string) string {
5055+
if apiGroup == "" {
5056+
apiGroup = gpuv1.DefaultMonitoringAPIGroup
5057+
}
5058+
return fmt.Sprintf("servicemonitors.%s", apiGroup)
5059+
}
5060+
5061+
func serviceMonitorGVK(apiGroup string) schema.GroupVersionKind {
5062+
if apiGroup == "" {
5063+
apiGroup = gpuv1.DefaultMonitoringAPIGroup
5064+
}
5065+
return schema.GroupVersionKind{Group: apiGroup, Version: "v1", Kind: "ServiceMonitor"}
5066+
}
5067+
5068+
func serviceMonitorConfigForState(n ClusterPolicyController, state string) *gpuv1.ServiceMonitorConfig {
5069+
switch state {
5070+
case "state-dcgm-exporter":
5071+
if n.singleton.Spec.DCGMExporter.ServiceMonitor != nil {
5072+
return n.singleton.Spec.DCGMExporter.ServiceMonitor
5073+
}
5074+
case "state-operator-metrics":
5075+
if n.singleton.Spec.Operator.Metrics.ServiceMonitor != nil {
5076+
return n.singleton.Spec.Operator.Metrics.ServiceMonitor
5077+
}
5078+
}
5079+
return nil
5080+
}
5081+
5082+
func serviceMonitorAPIGroupForState(n ClusterPolicyController, state string) string {
5083+
if sm := serviceMonitorConfigForState(n, state); sm != nil {
5084+
return sm.GetAPIGroup()
5085+
}
5086+
return gpuv1.DefaultMonitoringAPIGroup
5087+
}
5088+
5089+
func toUnstructuredServiceMonitor(sm *promv1.ServiceMonitor, apiGroup string) (*unstructured.Unstructured, error) {
5090+
objMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(sm)
5091+
if err != nil {
5092+
return nil, err
5093+
}
5094+
u := &unstructured.Unstructured{Object: objMap}
5095+
u.SetGroupVersionKind(serviceMonitorGVK(apiGroup))
5096+
return u, nil
5097+
}
5098+
5099+
func deleteServiceMonitor(ctx context.Context, c client.Client, sm *promv1.ServiceMonitor, apiGroup string) error {
5100+
u, err := toUnstructuredServiceMonitor(sm, apiGroup)
5101+
if err != nil {
5102+
return err
5103+
}
5104+
return c.Delete(ctx, u)
5105+
}
5106+
50525107
// ServiceMonitor creates ServiceMonitor object
50535108
func ServiceMonitor(n ClusterPolicyController) (gpuv1.State, error) {
50545109
ctx := n.ctx
@@ -5058,8 +5113,11 @@ func ServiceMonitor(n ClusterPolicyController) (gpuv1.State, error) {
50585113

50595114
logger := n.logger.WithValues("ServiceMonitor", obj.Name, "Namespace", obj.Namespace)
50605115

5116+
apiGroup := serviceMonitorAPIGroupForState(n, n.stateNames[state])
5117+
crdName := serviceMonitorCRDName(apiGroup)
5118+
50615119
// Check if ServiceMonitor is a valid kind
5062-
serviceMonitorCRDExists, err := crdExists(n, ServiceMonitorCRDName)
5120+
serviceMonitorCRDExists, err := crdExists(n, crdName)
50635121
if err != nil {
50645122
return gpuv1.NotReady, err
50655123
}
@@ -5069,7 +5127,7 @@ func ServiceMonitor(n ClusterPolicyController) (gpuv1.State, error) {
50695127
if !serviceMonitorCRDExists {
50705128
return gpuv1.Ready, nil
50715129
}
5072-
err := n.client.Delete(ctx, obj)
5130+
err := deleteServiceMonitor(ctx, n.client, obj, apiGroup)
50735131
if err != nil && !apierrors.IsNotFound(err) {
50745132
logger.Info("Couldn't delete", "Error", err)
50755133
return gpuv1.NotReady, err
@@ -5084,7 +5142,7 @@ func ServiceMonitor(n ClusterPolicyController) (gpuv1.State, error) {
50845142
if !serviceMonitorCRDExists {
50855143
return gpuv1.Ready, nil
50865144
}
5087-
err := n.client.Delete(ctx, obj)
5145+
err := deleteServiceMonitor(ctx, n.client, obj, apiGroup)
50885146
if err != nil && !apierrors.IsNotFound(err) {
50895147
logger.Info("Couldn't delete", "Error", err)
50905148
return gpuv1.NotReady, err
@@ -5138,11 +5196,17 @@ func ServiceMonitor(n ClusterPolicyController) (gpuv1.State, error) {
51385196
return gpuv1.NotReady, err
51395197
}
51405198

5141-
found := &promv1.ServiceMonitor{}
5199+
desired, err := toUnstructuredServiceMonitor(obj, apiGroup)
5200+
if err != nil {
5201+
return gpuv1.NotReady, err
5202+
}
5203+
5204+
found := &unstructured.Unstructured{}
5205+
found.SetGroupVersionKind(serviceMonitorGVK(apiGroup))
51425206
err = n.client.Get(ctx, types.NamespacedName{Namespace: obj.Namespace, Name: obj.Name}, found)
51435207
if err != nil && apierrors.IsNotFound(err) {
51445208
logger.Info("Not found, creating...")
5145-
err = n.client.Create(ctx, obj)
5209+
err = n.client.Create(ctx, desired)
51465210
if err != nil {
51475211
logger.Info("Couldn't create", "Error", err)
51485212
return gpuv1.NotReady, err
@@ -5153,9 +5217,9 @@ func ServiceMonitor(n ClusterPolicyController) (gpuv1.State, error) {
51535217
}
51545218

51555219
logger.Info("Found Resource, updating...")
5156-
obj.ResourceVersion = found.ResourceVersion
5220+
desired.SetResourceVersion(found.GetResourceVersion())
51575221

5158-
err = n.client.Update(ctx, obj)
5222+
err = n.client.Update(ctx, desired)
51595223
if err != nil {
51605224
logger.Info("Couldn't update", "Error", err)
51615225
return gpuv1.NotReady, err

deployments/gpu-operator/templates/role.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ rules:
7373
- delete
7474
- apiGroups:
7575
- monitoring.coreos.com
76+
- azmonitoring.coreos.com
7677
resources:
7778
- servicemonitors
7879
- prometheusrules

deployments/gpu-operator/values.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ dcgmExporter:
322322
internalTrafficPolicy: Cluster
323323
serviceMonitor:
324324
enabled: true
325+
# apiGroup: azmonitoring.coreos.com # required for Azure Managed Prometheus on AKS
325326
interval: 15s
326327
scrapeTimeout: 10s
327328
honorLabels: false

0 commit comments

Comments
 (0)