mirror of https://github.com/fluxcd/cli-utils.git
				
				
				
			fix: Inventory.SetObjectStatus
Fixes https://github.com/kubernetes-sigs/cli-utils/issues/554
This commit is contained in:
		
							parent
							
								
									e06456e4a1
								
							
						
					
					
						commit
						ca8fcbec60
					
				| 
						 | 
				
			
			@ -57,10 +57,11 @@ func TestInvSetTask(t *testing.T) {
 | 
			
		|||
			expectedObjs:  object.ObjMetadataSet{},
 | 
			
		||||
		},
 | 
			
		||||
		"one apply objs, one prune failures; one inventory": {
 | 
			
		||||
			// aritifical use case: applies and prunes are mutually exclusive
 | 
			
		||||
			// aritifical use case: applies and prunes are mutually exclusive.
 | 
			
		||||
			// Delete failure overwrites apply success in object status.
 | 
			
		||||
			appliedObjs:   object.ObjMetadataSet{id3},
 | 
			
		||||
			failedDeletes: object.ObjMetadataSet{id3},
 | 
			
		||||
			expectedObjs:  object.ObjMetadataSet{id3},
 | 
			
		||||
			expectedObjs:  object.ObjMetadataSet{},
 | 
			
		||||
		},
 | 
			
		||||
		"two apply objs, two prune failures; three inventory": {
 | 
			
		||||
			// aritifical use case: applies and prunes are mutually exclusive
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,8 +32,9 @@ func (tc *Manager) Inventory() *actuation.Inventory {
 | 
			
		|||
// ObjectStatus retrieves the status of an object with the specified ID.
 | 
			
		||||
// The returned status is a pointer and can be updated in-place for efficiency.
 | 
			
		||||
func (tc *Manager) ObjectStatus(id object.ObjMetadata) (*actuation.ObjectStatus, bool) {
 | 
			
		||||
	ref := ObjectReferenceFromObjMetadata(id)
 | 
			
		||||
	for i, objStatus := range tc.inventory.Status.Objects {
 | 
			
		||||
		if ObjMetadataEqualObjectReference(id, objStatus.ObjectReference) {
 | 
			
		||||
		if objStatus.ObjectReference == ref {
 | 
			
		||||
			return &(tc.inventory.Status.Objects[i]), true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -65,14 +66,14 @@ func (tc *Manager) ObjectsWithReconcileStatus(status actuation.ReconcileStatus)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// SetObjectStatus updates or adds an ObjectStatus record to the inventory.
 | 
			
		||||
func (tc *Manager) SetObjectStatus(id object.ObjMetadata, objStatus actuation.ObjectStatus) {
 | 
			
		||||
	for i, objStatus := range tc.inventory.Status.Objects {
 | 
			
		||||
		if ObjMetadataEqualObjectReference(id, objStatus.ObjectReference) {
 | 
			
		||||
			tc.inventory.Status.Objects[i] = objStatus
 | 
			
		||||
func (tc *Manager) SetObjectStatus(newObjStatus actuation.ObjectStatus) {
 | 
			
		||||
	for i, oldObjStatus := range tc.inventory.Status.Objects {
 | 
			
		||||
		if oldObjStatus.ObjectReference == newObjStatus.ObjectReference {
 | 
			
		||||
			tc.inventory.Status.Objects[i] = newObjStatus
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	tc.inventory.Status.Objects = append(tc.inventory.Status.Objects, objStatus)
 | 
			
		||||
	tc.inventory.Status.Objects = append(tc.inventory.Status.Objects, newObjStatus)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsSuccessfulApply returns true if the object apply was successful
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +90,7 @@ func (tc *Manager) IsSuccessfulApply(id object.ObjMetadata) bool {
 | 
			
		|||
// resource identified by the provided id. Currently, we keep information
 | 
			
		||||
// about the generation of the resource after the apply operation completed.
 | 
			
		||||
func (tc *Manager) AddSuccessfulApply(id object.ObjMetadata, uid types.UID, gen int64) {
 | 
			
		||||
	tc.SetObjectStatus(id, actuation.ObjectStatus{
 | 
			
		||||
	tc.SetObjectStatus(actuation.ObjectStatus{
 | 
			
		||||
		ObjectReference: ObjectReferenceFromObjMetadata(id),
 | 
			
		||||
		Strategy:        actuation.ActuationStrategyApply,
 | 
			
		||||
		Actuation:       actuation.ActuationSucceeded,
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +156,7 @@ func (tc *Manager) IsSuccessfulDelete(id object.ObjMetadata) bool {
 | 
			
		|||
// object was scheduled to be deleted asynchronously, which might cause further
 | 
			
		||||
// updates by finalizers. The UID will change if the object is re-created.
 | 
			
		||||
func (tc *Manager) AddSuccessfulDelete(id object.ObjMetadata, uid types.UID) {
 | 
			
		||||
	tc.SetObjectStatus(id, actuation.ObjectStatus{
 | 
			
		||||
	tc.SetObjectStatus(actuation.ObjectStatus{
 | 
			
		||||
		ObjectReference: ObjectReferenceFromObjMetadata(id),
 | 
			
		||||
		Strategy:        actuation.ActuationStrategyDelete,
 | 
			
		||||
		Actuation:       actuation.ActuationSucceeded,
 | 
			
		||||
| 
						 | 
				
			
			@ -183,7 +184,7 @@ func (tc *Manager) IsFailedApply(id object.ObjMetadata) bool {
 | 
			
		|||
 | 
			
		||||
// AddFailedApply registers that the object failed to apply
 | 
			
		||||
func (tc *Manager) AddFailedApply(id object.ObjMetadata) {
 | 
			
		||||
	tc.SetObjectStatus(id, actuation.ObjectStatus{
 | 
			
		||||
	tc.SetObjectStatus(actuation.ObjectStatus{
 | 
			
		||||
		ObjectReference: ObjectReferenceFromObjMetadata(id),
 | 
			
		||||
		Strategy:        actuation.ActuationStrategyApply,
 | 
			
		||||
		Actuation:       actuation.ActuationFailed,
 | 
			
		||||
| 
						 | 
				
			
			@ -208,7 +209,7 @@ func (tc *Manager) IsFailedDelete(id object.ObjMetadata) bool {
 | 
			
		|||
 | 
			
		||||
// AddFailedDelete registers that the object failed to delete
 | 
			
		||||
func (tc *Manager) AddFailedDelete(id object.ObjMetadata) {
 | 
			
		||||
	tc.SetObjectStatus(id, actuation.ObjectStatus{
 | 
			
		||||
	tc.SetObjectStatus(actuation.ObjectStatus{
 | 
			
		||||
		ObjectReference: ObjectReferenceFromObjMetadata(id),
 | 
			
		||||
		Strategy:        actuation.ActuationStrategyDelete,
 | 
			
		||||
		Actuation:       actuation.ActuationFailed,
 | 
			
		||||
| 
						 | 
				
			
			@ -234,7 +235,7 @@ func (tc *Manager) IsSkippedApply(id object.ObjMetadata) bool {
 | 
			
		|||
 | 
			
		||||
// AddSkippedApply registers that the object apply was skipped
 | 
			
		||||
func (tc *Manager) AddSkippedApply(id object.ObjMetadata) {
 | 
			
		||||
	tc.SetObjectStatus(id, actuation.ObjectStatus{
 | 
			
		||||
	tc.SetObjectStatus(actuation.ObjectStatus{
 | 
			
		||||
		ObjectReference: ObjectReferenceFromObjMetadata(id),
 | 
			
		||||
		Strategy:        actuation.ActuationStrategyApply,
 | 
			
		||||
		Actuation:       actuation.ActuationSkipped,
 | 
			
		||||
| 
						 | 
				
			
			@ -259,7 +260,7 @@ func (tc *Manager) IsSkippedDelete(id object.ObjMetadata) bool {
 | 
			
		|||
 | 
			
		||||
// AddSkippedDelete registers that the object delete was skipped
 | 
			
		||||
func (tc *Manager) AddSkippedDelete(id object.ObjMetadata) {
 | 
			
		||||
	tc.SetObjectStatus(id, actuation.ObjectStatus{
 | 
			
		||||
	tc.SetObjectStatus(actuation.ObjectStatus{
 | 
			
		||||
		ObjectReference: ObjectReferenceFromObjMetadata(id),
 | 
			
		||||
		Strategy:        actuation.ActuationStrategyDelete,
 | 
			
		||||
		Actuation:       actuation.ActuationSkipped,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,67 @@
 | 
			
		|||
// Copyright 2020 The Kubernetes Authors.
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
package inventory
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/require"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
	"sigs.k8s.io/cli-utils/pkg/apis/actuation"
 | 
			
		||||
	"sigs.k8s.io/cli-utils/pkg/object"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestObjectStatusGetSet(t *testing.T) {
 | 
			
		||||
	manager := NewManager()
 | 
			
		||||
 | 
			
		||||
	id := object.ObjMetadata{
 | 
			
		||||
		GroupKind: schema.GroupKind{
 | 
			
		||||
			Group: "group",
 | 
			
		||||
			Kind:  "kind",
 | 
			
		||||
		},
 | 
			
		||||
		Name:      "name",
 | 
			
		||||
		Namespace: "namespace",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Test get before set
 | 
			
		||||
	outStatus, found := manager.ObjectStatus(id)
 | 
			
		||||
	require.False(t, found)
 | 
			
		||||
	require.Nil(t, outStatus)
 | 
			
		||||
 | 
			
		||||
	// Test get after set
 | 
			
		||||
	inStatus1 := actuation.ObjectStatus{
 | 
			
		||||
		ObjectReference: ObjectReferenceFromObjMetadata(id),
 | 
			
		||||
		Strategy:        actuation.ActuationStrategyApply,
 | 
			
		||||
		Actuation:       actuation.ActuationPending,
 | 
			
		||||
		Reconcile:       actuation.ReconcilePending,
 | 
			
		||||
	}
 | 
			
		||||
	manager.SetObjectStatus(inStatus1)
 | 
			
		||||
	outStatus, found = manager.ObjectStatus(id)
 | 
			
		||||
	require.True(t, found)
 | 
			
		||||
	require.Equal(t, &inStatus1, outStatus)
 | 
			
		||||
 | 
			
		||||
	// Test get after re-set
 | 
			
		||||
	inStatus2 := actuation.ObjectStatus{
 | 
			
		||||
		ObjectReference: ObjectReferenceFromObjMetadata(id),
 | 
			
		||||
		Strategy:        actuation.ActuationStrategyApply,
 | 
			
		||||
		Actuation:       actuation.ActuationSucceeded,
 | 
			
		||||
		Reconcile:       actuation.ReconcilePending,
 | 
			
		||||
	}
 | 
			
		||||
	manager.SetObjectStatus(inStatus2)
 | 
			
		||||
	outStatus, found = manager.ObjectStatus(id)
 | 
			
		||||
	require.True(t, found)
 | 
			
		||||
	require.Equal(t, &inStatus2, outStatus)
 | 
			
		||||
 | 
			
		||||
	// Test get after set via returned pointer
 | 
			
		||||
	outStatus.Reconcile = actuation.ReconcileFailed
 | 
			
		||||
	outStatus, found = manager.ObjectStatus(id)
 | 
			
		||||
	require.True(t, found)
 | 
			
		||||
	expStatus := actuation.ObjectStatus{
 | 
			
		||||
		ObjectReference: ObjectReferenceFromObjMetadata(id),
 | 
			
		||||
		Strategy:        actuation.ActuationStrategyApply,
 | 
			
		||||
		Actuation:       actuation.ActuationSucceeded,
 | 
			
		||||
		Reconcile:       actuation.ReconcileFailed,
 | 
			
		||||
	}
 | 
			
		||||
	require.Equal(t, &expStatus, outStatus)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -9,14 +9,6 @@ import (
 | 
			
		|||
	"sigs.k8s.io/cli-utils/pkg/object"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ObjMetadataEqualObjectReference compares an ObjMetadata with a ObjectReference
 | 
			
		||||
func ObjMetadataEqualObjectReference(id object.ObjMetadata, ref actuation.ObjectReference) bool {
 | 
			
		||||
	return id.GroupKind.Group == ref.Group &&
 | 
			
		||||
		id.GroupKind.Kind == ref.Kind &&
 | 
			
		||||
		id.Namespace == ref.Namespace &&
 | 
			
		||||
		id.Name == ref.Name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ObjectReferenceFromObjMetadata converts an ObjMetadata to a ObjectReference
 | 
			
		||||
func ObjectReferenceFromObjMetadata(id object.ObjMetadata) actuation.ObjectReference {
 | 
			
		||||
	return actuation.ObjectReference{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue