diff --git a/api/v1alpha1/datasource_types.go b/api/v1alpha1/datasource_types.go index fff321c48..6ab7d962e 100644 --- a/api/v1alpha1/datasource_types.go +++ b/api/v1alpha1/datasource_types.go @@ -232,7 +232,7 @@ type DatasourceStatus struct { // When the datasource was last successfully synced. LastSynced metav1.Time `json:"lastSynced,omitempty"` // The number of objects currently stored for this datasource. - NumberOfObjects int64 `json:"numberOfObjects,omitempty"` + NumberOfObjects *int64 `json:"numberOfObjects,omitempty"` // Planned time for the next sync. NextSyncTime metav1.Time `json:"nextSyncTime,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 9f654186a..0fa21d2bb 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -353,6 +353,11 @@ func (in *DatasourceSpec) DeepCopy() *DatasourceSpec { func (in *DatasourceStatus) DeepCopyInto(out *DatasourceStatus) { *out = *in in.LastSynced.DeepCopyInto(&out.LastSynced) + if in.NumberOfObjects != nil { + in, out := &in.NumberOfObjects, &out.NumberOfObjects + *out = new(int64) + **out = **in + } in.NextSyncTime.DeepCopyInto(&out.NextSyncTime) if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions diff --git a/helm/bundles/cortex-cinder/templates/alerts.yaml b/helm/bundles/cortex-cinder/templates/alerts.yaml index 4beea8b53..941c33546 100644 --- a/helm/bundles/cortex-cinder/templates/alerts.yaml +++ b/helm/bundles/cortex-cinder/templates/alerts.yaml @@ -156,7 +156,7 @@ spec: time the service will have a less recent view of the datacenter. - alert: CortexCinderSyncObjectsDroppedToZero - expr: cortex_sync_objects{service="cortex-cinder-metrics"} == 0 + expr: cortex_sync_objects{service="cortex-cinder-metrics"} == 0 and (cortex_sync_objects{service="cortex-cinder-metrics"} offset 1h > 0) for: 60m labels: context: syncobjects diff --git a/helm/bundles/cortex-manila/templates/alerts.yaml b/helm/bundles/cortex-manila/templates/alerts.yaml index ef36fe983..769730c1e 100644 --- a/helm/bundles/cortex-manila/templates/alerts.yaml +++ b/helm/bundles/cortex-manila/templates/alerts.yaml @@ -162,7 +162,7 @@ spec: time the service will have a less recent view of the datacenter. - alert: CortexManilaSyncObjectsDroppedToZero - expr: cortex_sync_objects{service="cortex-manila-metrics"} == 0 + expr: cortex_sync_objects{service="cortex-manila-metrics"} == 0 and (cortex_sync_objects{service="cortex-manila-metrics"} offset 1h > 0) for: 60m labels: context: syncobjects diff --git a/helm/bundles/cortex-nova/templates/alerts.yaml b/helm/bundles/cortex-nova/templates/alerts.yaml index 840e969f2..76fe545e1 100644 --- a/helm/bundles/cortex-nova/templates/alerts.yaml +++ b/helm/bundles/cortex-nova/templates/alerts.yaml @@ -179,7 +179,7 @@ spec: time the service will have a less recent view of the datacenter. - alert: CortexNovaSyncObjectsDroppedToZero - expr: cortex_sync_objects{service="cortex-nova-metrics", datasource!="openstack_migrations"} == 0 + expr: cortex_sync_objects{service="cortex-nova-metrics", datasource!="openstack_migrations"} == 0 and (cortex_sync_objects{service="cortex-nova-metrics", datasource!="openstack_migrations"} offset 1h > 0) for: 60m labels: context: syncobjects diff --git a/internal/knowledge/datasources/plugins/openstack/controller.go b/internal/knowledge/datasources/plugins/openstack/controller.go index 96d056a15..07277ce79 100644 --- a/internal/knowledge/datasources/plugins/openstack/controller.go +++ b/internal/knowledge/datasources/plugins/openstack/controller.go @@ -95,7 +95,7 @@ func (r *OpenStackDatasourceReconciler) Reconcile(ctx context.Context, req ctrl. log.Info("skipping datasource, not an openstack datasource", "name", datasource.Name) return ctrl.Result{}, nil } - if datasource.Status.NextSyncTime.After(time.Now()) && datasource.Status.NumberOfObjects != 0 { + if datasource.Status.NextSyncTime.After(time.Now()) && datasource.Status.NumberOfObjects != nil { if _, seen := r.reconciledOnce.Load(req.NamespacedName); seen { log.Info("skipping datasource sync, not yet time", "name", datasource.Name) return ctrl.Result{RequeueAfter: time.Until(datasource.Status.NextSyncTime.Time)}, nil @@ -262,7 +262,7 @@ func (r *OpenStackDatasourceReconciler) Reconcile(ctx context.Context, req ctrl. datasource.Status.LastSynced = metav1.NewTime(time.Now()) nextTime := time.Now().Add(datasource.Spec.OpenStack.SyncInterval.Duration) datasource.Status.NextSyncTime = metav1.NewTime(nextTime) - datasource.Status.NumberOfObjects = nResults + datasource.Status.NumberOfObjects = &nResults patch := client.MergeFrom(old) if err := r.Status().Patch(ctx, datasource, patch); err != nil { log.Error(err, "failed to patch datasource status", "name", datasource.Name) diff --git a/internal/knowledge/datasources/plugins/openstack/controller_test.go b/internal/knowledge/datasources/plugins/openstack/controller_test.go index 899e83237..a809e099b 100644 --- a/internal/knowledge/datasources/plugins/openstack/controller_test.go +++ b/internal/knowledge/datasources/plugins/openstack/controller_test.go @@ -495,11 +495,11 @@ func TestUpdatePredicateIgnoresStatusConditionChanges(t *testing.T) { name: "status NumberOfObjects changes - should trigger reconcile", oldObj: &v1alpha1.Datasource{ ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, - Status: v1alpha1.DatasourceStatus{NumberOfObjects: 10}, + Status: v1alpha1.DatasourceStatus{NumberOfObjects: new(int64(10))}, }, newObj: &v1alpha1.Datasource{ ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, - Status: v1alpha1.DatasourceStatus{NumberOfObjects: 20}, + Status: v1alpha1.DatasourceStatus{NumberOfObjects: new(int64(20))}, }, expected: true, }, diff --git a/internal/knowledge/datasources/plugins/prometheus/controller.go b/internal/knowledge/datasources/plugins/prometheus/controller.go index dab9ea3b3..bccc1fcf1 100644 --- a/internal/knowledge/datasources/plugins/prometheus/controller.go +++ b/internal/knowledge/datasources/plugins/prometheus/controller.go @@ -71,7 +71,7 @@ func (r *PrometheusDatasourceReconciler) Reconcile(ctx context.Context, req ctrl log.Info("skipping datasource, not a prometheus datasource", "name", datasource.Name) return ctrl.Result{}, nil } - if datasource.Status.NextSyncTime.After(time.Now()) && datasource.Status.NumberOfObjects != 0 { + if datasource.Status.NextSyncTime.After(time.Now()) && datasource.Status.NumberOfObjects != nil { if _, seen := r.reconciledOnce.Load(req.NamespacedName); seen { log.Info("skipping datasource sync, not yet time", "name", datasource.Name) return ctrl.Result{RequeueAfter: time.Until(datasource.Status.NextSyncTime.Time)}, nil @@ -201,7 +201,7 @@ func (r *PrometheusDatasourceReconciler) Reconcile(ctx context.Context, req ctrl }) datasource.Status.LastSynced = metav1.NewTime(time.Now()) datasource.Status.NextSyncTime = metav1.NewTime(nextSync) - datasource.Status.NumberOfObjects = nResults + datasource.Status.NumberOfObjects = &nResults patch := client.MergeFrom(old) if err := r.Status().Patch(ctx, datasource, patch); err != nil { log.Error(err, "failed to patch datasource status", "name", datasource.Name) diff --git a/internal/knowledge/kpis/controller_test.go b/internal/knowledge/kpis/controller_test.go index 708a19cd0..0aeb96485 100644 --- a/internal/knowledge/kpis/controller_test.go +++ b/internal/knowledge/kpis/controller_test.go @@ -333,7 +333,7 @@ func TestController_Reconcile(t *testing.T) { }, }, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 1, + NumberOfObjects: new(int64(1)), Conditions: []metav1.Condition{ { Type: v1alpha1.DatasourceConditionReady, @@ -393,7 +393,7 @@ func TestController_Reconcile(t *testing.T) { }, }, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 0, + NumberOfObjects: new(int64(0)), Conditions: []metav1.Condition{ { Type: v1alpha1.DatasourceConditionReady, @@ -622,7 +622,7 @@ func TestController_handleKPIChange(t *testing.T) { DatabaseSecretRef: corev1.SecretReference{Name: "db-secret", Namespace: "default"}, }, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 1, + NumberOfObjects: new(int64(1)), Conditions: []metav1.Condition{ { Type: v1alpha1.DatasourceConditionReady, @@ -638,7 +638,7 @@ func TestController_handleKPIChange(t *testing.T) { DatabaseSecretRef: corev1.SecretReference{Name: "db-secret", Namespace: "default"}, }, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 0, + NumberOfObjects: new(int64(0)), Conditions: []metav1.Condition{ { Type: v1alpha1.DatasourceConditionReady, @@ -703,7 +703,7 @@ func TestController_handleKPIChange(t *testing.T) { DatabaseSecretRef: corev1.SecretReference{Name: "db-secret", Namespace: "default"}, }, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 1, + NumberOfObjects: new(int64(1)), Conditions: []metav1.Condition{ { Type: v1alpha1.DatasourceConditionReady, diff --git a/internal/knowledge/kpis/plugins/deployment/datasource_state_test.go b/internal/knowledge/kpis/plugins/deployment/datasource_state_test.go index d6e56bd35..e143bf5f9 100644 --- a/internal/knowledge/kpis/plugins/deployment/datasource_state_test.go +++ b/internal/knowledge/kpis/plugins/deployment/datasource_state_test.go @@ -49,7 +49,7 @@ func TestDatasourceStateKPI_Collect(t *testing.T) { ObjectMeta: v1.ObjectMeta{Name: "ds1"}, Spec: v1alpha1.DatasourceSpec{SchedulingDomain: "test-operator"}, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 10, + NumberOfObjects: new(int64(10)), Conditions: []v1.Condition{}, }, }, @@ -87,7 +87,7 @@ func TestDatasourceStateKPI_Collect(t *testing.T) { ObjectMeta: v1.ObjectMeta{Name: "ds-ready"}, Spec: v1alpha1.DatasourceSpec{SchedulingDomain: "test-operator"}, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 10, + NumberOfObjects: new(int64(10)), Conditions: []v1.Condition{}, }, }, @@ -127,7 +127,7 @@ func TestDatasourceStateKPI_Collect(t *testing.T) { ObjectMeta: v1.ObjectMeta{Name: "ds-correct-operator"}, Spec: v1alpha1.DatasourceSpec{SchedulingDomain: "test-operator"}, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 10, + NumberOfObjects: new(int64(10)), Conditions: []v1.Condition{}, }, }, @@ -135,7 +135,7 @@ func TestDatasourceStateKPI_Collect(t *testing.T) { ObjectMeta: v1.ObjectMeta{Name: "ds-wrong-operator"}, Spec: v1alpha1.DatasourceSpec{SchedulingDomain: "other-operator"}, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 10, + NumberOfObjects: new(int64(10)), Conditions: []v1.Condition{}, }, }, @@ -151,7 +151,7 @@ func TestDatasourceStateKPI_Collect(t *testing.T) { ObjectMeta: v1.ObjectMeta{Name: "ds-unknown"}, Spec: v1alpha1.DatasourceSpec{SchedulingDomain: "test-operator"}, Status: v1alpha1.DatasourceStatus{ - NumberOfObjects: 0, + NumberOfObjects: new(int64(0)), Conditions: []v1.Condition{}, }, },