Skip to content

Commit

Permalink
Terminal condition sets ResourceSynced=False
Browse files Browse the repository at this point in the history
This patch updates the `resourceReconciler.ensureConditions()` method to
set the `ACK.ResourceSynced` Condition value to `False` when a Terminal
error has been returned from the resource manager. Previously, the
`ACK.ResourceSynced` Condition value was erroneously being set to `True`
due to a misunderstanding of what `ACK.ResourceSynced` means.

`ACK.ResourceSynced` is a Condition that informs the Kubernetes user
*whether the desired state of a resource matches the latest observed
state of the resource*. In the case of a Terminal error, the desired
state of a resource will *never* match the latest observed state of the
resource because there is something invalid about the desired resource
state.

Further, this patch changes the default value for `ACK.ResourceSynced`
Condition to be `Unknown` instead of `False` for any non-Terminal
reconciler error. The reasoning behind this change is that for
non-Terminal errors, we simply do not know whether the desired resource
state matches the latest observed state or not.

Signed-off-by: Jay Pipes <jaypipes@gmail.com>
  • Loading branch information
jaypipes committed Jun 15, 2022
1 parent 71e60cc commit 266e802
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 15 deletions.
5 changes: 3 additions & 2 deletions pkg/condition/condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ var (
NotManagedReason = "This resource already exists but is not managed by ACK. " +
"To bring the resource under ACK management, you should explicitly adopt " +
"the resource by creating a services.k8s.aws/AdoptedResource"
NotSyncedMessage = "Resource not synced"
SyncedMessage = "Resource synced successfully"
UnknownSyncedMessage = "Unable to determine if desired resource state matches latest observed state"
NotSyncedMessage = "Resource not synced"
SyncedMessage = "Resource synced successfully"
)

// Synced returns the Condition in the resource's Conditions collection that is
Expand Down
18 changes: 11 additions & 7 deletions pkg/runtime/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,15 +326,19 @@ func (r *resourceReconciler) ensureConditions(
if reconcileErr != nil {
condReason = reconcileErr.Error()
if reconcileErr == ackerr.Terminal {
// A terminal condition by its very nature indicates a stable state
// for a resource being synced. The resource is considered synced
// because its state will not change.
condStatus = corev1.ConditionTrue
condMessage = ackcondition.SyncedMessage
} else {
// For any other reconciler error, set synced condition to false
// A terminal condition is a stable state for a resource.
// Terminal conditions indicate that without changes to the
// desired state of a resource, the resource's desired state
// will never match the latest observed state. Thus,
// ACK.ResourceSynced must be False.
condStatus = corev1.ConditionFalse
condMessage = ackcondition.NotSyncedMessage
} else {
// For any other reconciler error, set synced condition to
// unknown, since we don't know whether the resource's desired
// state matches the resource's latest observed state.
condStatus = corev1.ConditionUnknown
condMessage = ackcondition.UnknownSyncedMessage
}
}
ackcondition.SetSynced(res, condStatus, &condMessage, &condReason)
Expand Down
13 changes: 7 additions & 6 deletions pkg/runtime/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,9 +994,10 @@ func TestReconcilerUpdate_ErrorInLateInitialization(t *testing.T) {
hasSynced = true
// Even though mocked IsSynced method returns (true, nil),
// the reconciler error from late initialization correctly causes
// the ResourceSynced condition to be False
assert.Equal(corev1.ConditionFalse, condition.Status)
assert.Equal(ackcondition.NotSyncedMessage, *condition.Message)
// the ResourceSynced condition to be Unknown since the reconciler
// error is not a Terminal error.
assert.Equal(corev1.ConditionUnknown, condition.Status)
assert.Equal(ackcondition.UnknownSyncedMessage, *condition.Message)
assert.Equal(requeueError.Error(), *condition.Reason)
}
assert.True(hasSynced)
Expand Down Expand Up @@ -1112,9 +1113,9 @@ func TestReconcilerUpdate_ResourceNotManaged(t *testing.T) {
}
hasSynced = true
// The terminal error from reconciler correctly causes
// the ResourceSynced condition to be True
assert.Equal(corev1.ConditionTrue, condition.Status)
assert.Equal(ackcondition.SyncedMessage, *condition.Message)
// the ResourceSynced condition to be False
assert.Equal(corev1.ConditionFalse, condition.Status)
assert.Equal(ackcondition.NotSyncedMessage, *condition.Message)
}
assert.True(hasSynced)
})
Expand Down

0 comments on commit 266e802

Please sign in to comment.