diff --git a/pkg/apis/servicebinding/v1alpha3/servicebinding_lifecycle.go b/pkg/apis/servicebinding/v1alpha3/servicebinding_lifecycle.go index 45cf9d6e..92b0649d 100644 --- a/pkg/apis/servicebinding/v1alpha3/servicebinding_lifecycle.go +++ b/pkg/apis/servicebinding/v1alpha3/servicebinding_lifecycle.go @@ -19,12 +19,13 @@ const ( ServiceBindingConditionReady = "Ready" ServiceBindingConditionServiceAvailable = "ServiceAvailable" ServiceBindingConditionProjectionReady = "ProjectionReady" + InitializeConditionReason = "Unknown" ) -func (bs *ServiceBindingStatus) InitializeConditions() { - ready := metav1.Condition{Type: ServiceBindingConditionReady} - serviceAvailable := metav1.Condition{Type: ServiceBindingConditionServiceAvailable} - projectionReady := metav1.Condition{Type: ServiceBindingConditionProjectionReady} +func (bs *ServiceBindingStatus) InitializeConditions(now metav1.Time) { + ready := metav1.Condition{Type: ServiceBindingConditionReady, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: InitializeConditionReason} + serviceAvailable := metav1.Condition{Type: ServiceBindingConditionServiceAvailable, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: InitializeConditionReason} + projectionReady := metav1.Condition{Type: ServiceBindingConditionProjectionReady, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: InitializeConditionReason} for _, c := range bs.Conditions { switch c.Type { case ServiceBindingConditionReady: @@ -112,10 +113,6 @@ func (bs *ServiceBindingStatus) aggregateReadyCondition(now metav1.Time) { bs.Conditions[0].Status = metav1.ConditionUnknown bs.Conditions[0].Reason = fmt.Sprintf("%s%s", ServiceBindingConditionProjectionReady, bs.Conditions[2].Reason) bs.Conditions[0].Message = bs.Conditions[2].Message - } else { - bs.Conditions[0].Status = metav1.ConditionUnknown - bs.Conditions[0].Reason = "Unknown" - bs.Conditions[0].Message = "" } // update time when the status changes diff --git a/pkg/apis/servicebinding/v1alpha3/servicebinding_test.go b/pkg/apis/servicebinding/v1alpha3/servicebinding_test.go index 7cfeee34..6ac8e049 100644 --- a/pkg/apis/servicebinding/v1alpha3/servicebinding_test.go +++ b/pkg/apis/servicebinding/v1alpha3/servicebinding_test.go @@ -286,9 +286,9 @@ func TestServiceBindingStatus_PropagateServiceBindingProjectionStatus(t *testing projection: nil, expected: &ServiceBindingStatus{ Conditions: []metav1.Condition{ - {Type: ServiceBindingConditionReady}, - {Type: ServiceBindingConditionServiceAvailable}, - {Type: ServiceBindingConditionProjectionReady}, + {Type: ServiceBindingConditionReady, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: InitializeConditionReason}, + {Type: ServiceBindingConditionServiceAvailable, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: InitializeConditionReason}, + {Type: ServiceBindingConditionProjectionReady, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: InitializeConditionReason}, }, }, }, @@ -301,10 +301,15 @@ func TestServiceBindingStatus_PropagateServiceBindingProjectionStatus(t *testing { Type: ServiceBindingConditionReady, Status: metav1.ConditionUnknown, - Reason: "ProjectionReadyUnknown", + Reason: "ServiceAvailableUnknown", LastTransitionTime: now, }, - {Type: ServiceBindingConditionServiceAvailable}, + { + Type: ServiceBindingConditionServiceAvailable, + LastTransitionTime: now, + Status: metav1.ConditionUnknown, + Reason: InitializeConditionReason, + }, { Type: ServiceBindingConditionProjectionReady, Status: metav1.ConditionUnknown, @@ -334,11 +339,14 @@ func TestServiceBindingStatus_PropagateServiceBindingProjectionStatus(t *testing { Type: ServiceBindingConditionReady, Status: metav1.ConditionUnknown, - Reason: "Unknown", + Reason: "ServiceAvailableUnknown", LastTransitionTime: now, }, { - Type: ServiceBindingConditionServiceAvailable, + Type: ServiceBindingConditionServiceAvailable, + LastTransitionTime: now, + Status: metav1.ConditionUnknown, + Reason: InitializeConditionReason, }, { Type: ServiceBindingConditionProjectionReady, @@ -376,7 +384,10 @@ func TestServiceBindingStatus_PropagateServiceBindingProjectionStatus(t *testing LastTransitionTime: now, }, { - Type: ServiceBindingConditionServiceAvailable, + Type: ServiceBindingConditionServiceAvailable, + LastTransitionTime: now, + Status: metav1.ConditionUnknown, + Reason: InitializeConditionReason, }, { Type: ServiceBindingConditionProjectionReady, @@ -407,11 +418,14 @@ func TestServiceBindingStatus_PropagateServiceBindingProjectionStatus(t *testing { Type: ServiceBindingConditionReady, Status: metav1.ConditionUnknown, - Reason: "ProjectionReadyUnknown", + Reason: "ServiceAvailableUnknown", LastTransitionTime: now, }, { - Type: ServiceBindingConditionServiceAvailable, + Type: ServiceBindingConditionServiceAvailable, + LastTransitionTime: now, + Status: metav1.ConditionUnknown, + Reason: InitializeConditionReason, }, { Type: ServiceBindingConditionProjectionReady, @@ -426,9 +440,9 @@ func TestServiceBindingStatus_PropagateServiceBindingProjectionStatus(t *testing for _, c := range tests { t.Run(c.name, func(t *testing.T) { actual := c.seed.DeepCopy() - actual.InitializeConditions() + actual.InitializeConditions(now) actual.PropagateServiceBindingProjectionStatus(c.projection, now) - if diff := cmp.Diff(c.expected, actual); diff != "" { + if diff := cmp.Diff(c.expected, actual, cmpopts.IgnoreTypes(metav1.Time{})); diff != "" { t.Errorf("%s: PropagateServiceBindingProjectionStatus() (-expected, +actual): %s", c.name, diff) } }) @@ -442,7 +456,7 @@ func TestServiceBindingStatus_MarkServiceAvailable(t *testing.T) { { Type: ServiceBindingConditionReady, Status: metav1.ConditionUnknown, - Reason: "Unknown", + Reason: "ProjectionReadyUnknown", LastTransitionTime: now, }, { @@ -451,14 +465,14 @@ func TestServiceBindingStatus_MarkServiceAvailable(t *testing.T) { Reason: "Available", LastTransitionTime: now, }, - {Type: ServiceBindingConditionProjectionReady}, + {Type: ServiceBindingConditionProjectionReady, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: "Unknown"}, }, } actual := &ServiceBindingStatus{} - actual.InitializeConditions() + actual.InitializeConditions(now) actual.MarkServiceAvailable(now) - if diff := cmp.Diff(expected, actual); diff != "" { + if diff := cmp.Diff(expected, actual, cmpopts.IgnoreTypes(metav1.Time{})); diff != "" { t.Errorf("MarkServiceAvailable() (-expected, +actual): %s", diff) } } @@ -481,19 +495,20 @@ func TestServiceBindingStatus_MarkServiceUnavailable(t *testing.T) { Message: "the message", LastTransitionTime: now, }, - {Type: ServiceBindingConditionProjectionReady}, + {Type: ServiceBindingConditionProjectionReady, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: "Unknown"}, }, } actual := &ServiceBindingStatus{} - actual.InitializeConditions() + actual.InitializeConditions(now) actual.MarkServiceUnavailable("TheReason", "the message", now) - if diff := cmp.Diff(expected, actual); diff != "" { + if diff := cmp.Diff(expected, actual, cmpopts.IgnoreTypes(metav1.Time{})); diff != "" { t.Errorf("MarkServiceUnavailable() (-expected, +actual): %s", diff) } } func TestServiceBindingStatus_InitializeConditions(t *testing.T) { + now := metav1.Now() tests := []struct { name string seed *ServiceBindingStatus @@ -504,9 +519,9 @@ func TestServiceBindingStatus_InitializeConditions(t *testing.T) { seed: &ServiceBindingStatus{}, expected: &ServiceBindingStatus{ Conditions: []metav1.Condition{ - {Type: ServiceBindingConditionReady}, - {Type: ServiceBindingConditionServiceAvailable}, - {Type: ServiceBindingConditionProjectionReady}, + {Type: ServiceBindingConditionReady, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: "Unknown"}, + {Type: ServiceBindingConditionServiceAvailable, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: "Unknown"}, + {Type: ServiceBindingConditionProjectionReady, Status: metav1.ConditionUnknown, LastTransitionTime: now, Reason: "Unknown"}, }, }, }, @@ -549,7 +564,7 @@ func TestServiceBindingStatus_InitializeConditions(t *testing.T) { for _, c := range tests { t.Run(c.name, func(t *testing.T) { actual := c.seed.DeepCopy() - actual.InitializeConditions() + actual.InitializeConditions(now) if diff := cmp.Diff(c.expected, actual, cmpopts.IgnoreTypes(metav1.Time{})); diff != "" { t.Errorf("%s: InitializeConditions() (-expected, +actual): %s", c.name, diff) } @@ -572,11 +587,21 @@ func TestServiceBindingStatus_aggregateReadyCondition(t *testing.T) { { Type: ServiceBindingConditionReady, Status: "Unknown", + Reason: "ServiceAvailableUnknown", + LastTransitionTime: now, + }, + { + Type: ServiceBindingConditionServiceAvailable, + Status: "Unknown", + Reason: "Unknown", + LastTransitionTime: now, + }, + { + Type: ServiceBindingConditionProjectionReady, + Status: "Unknown", Reason: "Unknown", LastTransitionTime: now, }, - {Type: ServiceBindingConditionServiceAvailable}, - {Type: ServiceBindingConditionProjectionReady}, }, }, }, @@ -769,9 +794,9 @@ func TestServiceBindingStatus_aggregateReadyCondition(t *testing.T) { for _, c := range tests { t.Run(c.name, func(t *testing.T) { actual := c.seed.DeepCopy() - actual.InitializeConditions() + actual.InitializeConditions(now) actual.aggregateReadyCondition(now) - if diff := cmp.Diff(c.expected, actual); diff != "" { + if diff := cmp.Diff(c.expected, actual, cmpopts.IgnoreTypes(metav1.Time{})); diff != "" { t.Errorf("%s: aggregateReadyCondition() (-expected, +actual): %s", c.name, diff) } }) diff --git a/pkg/reconciler/servicebinding/servicebinding.go b/pkg/reconciler/servicebinding/servicebinding.go index fdce8b2f..47eb1c94 100644 --- a/pkg/reconciler/servicebinding/servicebinding.go +++ b/pkg/reconciler/servicebinding/servicebinding.go @@ -58,8 +58,8 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, binding *servicebindingv return nil } - binding.Status.InitializeConditions() now := r.now() + binding.Status.InitializeConditions(now) secretRef, err := r.provisionedSecret(ctx, logger, binding) if err != nil { diff --git a/pkg/reconciler/servicebinding/servicebinding_test.go b/pkg/reconciler/servicebinding/servicebinding_test.go index 0505ca06..0d57a43e 100644 --- a/pkg/reconciler/servicebinding/servicebinding_test.go +++ b/pkg/reconciler/servicebinding/servicebinding_test.go @@ -392,6 +392,63 @@ func TestReconcile(t *testing.T) { WantEvents: []string{ Eventf(corev1.EventTypeNormal, "Reconciled", "ServiceBinding reconciled: %q", key), }, + }, { + Name: "missing referenced service with no service projection", + Key: key, + Objects: []runtime.Object{ + &servicebindingv1alpha3.ServiceBinding{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + Generation: 1, + }, + Spec: servicebindingv1alpha3.ServiceBindingSpec{ + Name: name, + Workload: &workloadRef, + Service: &serviceRef, + }, + }, + }, + WantErr: true, + WantEvents: []string{ + Eventf(corev1.EventTypeWarning, "InternalError", "failed to get resource for bindings.labs.vmware.com/v1alpha1, Resource=provisionedservices: provisionedservices.bindings.labs.vmware.com %q not found", serviceRef.Name), + }, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: &servicebindingv1alpha3.ServiceBinding{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + Generation: 1, + }, + Spec: servicebindingv1alpha3.ServiceBindingSpec{ + Name: name, + Workload: &workloadRef, + Service: &serviceRef, + }, + Status: servicebindingv1alpha3.ServiceBindingStatus{ + Conditions: []metav1.Condition{ + { + Type: servicebindingv1alpha3.ServiceBindingConditionReady, + Status: metav1.ConditionUnknown, + LastTransitionTime: now, + Reason: "Unknown", + }, + { + Type: servicebindingv1alpha3.ServiceBindingConditionServiceAvailable, + Status: metav1.ConditionUnknown, + LastTransitionTime: now, + Reason: "Unknown", + }, + { + Type: servicebindingv1alpha3.ServiceBindingConditionProjectionReady, + Status: metav1.ConditionUnknown, + LastTransitionTime: now, + Reason: "Unknown", + }, + }, + }, + }, + }}, }, { Name: "missing referenced service", Key: key,