Refactor: Move inventory helpers to internal package
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
This commit is contained in:
		
							parent
							
								
									cfe35399e0
								
							
						
					
					
						commit
						484cbcc14c
					
				|  | @ -63,6 +63,7 @@ import ( | |||
| 	kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" | ||||
| 	"github.com/fluxcd/kustomize-controller/internal/decryptor" | ||||
| 	"github.com/fluxcd/kustomize-controller/internal/generator" | ||||
| 	"github.com/fluxcd/kustomize-controller/internal/inventory" | ||||
| ) | ||||
| 
 | ||||
| // +kubebuilder:rbac:groups=kustomize.toolkit.fluxcd.io,resources=kustomizations,verbs=get;list;watch;create;update;patch;delete
 | ||||
|  | @ -440,8 +441,8 @@ func (r *KustomizationReconciler) reconcile( | |||
| 	} | ||||
| 
 | ||||
| 	// create an inventory of objects to be reconciled
 | ||||
| 	newInventory := NewInventory() | ||||
| 	err = AddObjectsToInventory(newInventory, changeSet) | ||||
| 	newInventory := inventory.New() | ||||
| 	err = inventory.AddChangeSet(newInventory, changeSet) | ||||
| 	if err != nil { | ||||
| 		return kustomizev1.KustomizationNotReady( | ||||
| 			kustomization, | ||||
|  | @ -454,7 +455,7 @@ func (r *KustomizationReconciler) reconcile( | |||
| 	// detect stale objects which are subject to garbage collection
 | ||||
| 	var staleObjects []*unstructured.Unstructured | ||||
| 	if oldStatus.Inventory != nil { | ||||
| 		diffObjects, err := DiffInventory(oldStatus.Inventory, newInventory) | ||||
| 		diffObjects, err := inventory.Diff(oldStatus.Inventory, newInventory) | ||||
| 		if err != nil { | ||||
| 			return kustomizev1.KustomizationNotReady( | ||||
| 				kustomization, | ||||
|  | @ -467,7 +468,7 @@ func (r *KustomizationReconciler) reconcile( | |||
| 		// TODO: remove this workaround after kustomize-controller 0.18 release
 | ||||
| 		// skip objects that were wrongly marked as namespaced
 | ||||
| 		// https://github.com/fluxcd/kustomize-controller/issues/466
 | ||||
| 		newObjects, _ := ListObjectsInInventory(newInventory) | ||||
| 		newObjects, _ := inventory.List(newInventory) | ||||
| 		for _, obj := range diffObjects { | ||||
| 			preserve := false | ||||
| 			if obj.GetNamespace() != "" { | ||||
|  | @ -846,7 +847,7 @@ func (r *KustomizationReconciler) checkHealth(ctx context.Context, manager *ssa. | |||
| 	checkStart := time.Now() | ||||
| 	var err error | ||||
| 	if !kustomization.Spec.Wait { | ||||
| 		objects, err = referenceToObjMetadataSet(kustomization.Spec.HealthChecks) | ||||
| 		objects, err = inventory.ReferenceToObjMetadataSet(kustomization.Spec.HealthChecks) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | @ -932,7 +933,7 @@ func (r *KustomizationReconciler) finalize(ctx context.Context, kustomization ku | |||
| 		!kustomization.Spec.Suspend && | ||||
| 		kustomization.Status.Inventory != nil && | ||||
| 		kustomization.Status.Inventory.Entries != nil { | ||||
| 		objects, _ := ListObjectsInInventory(kustomization.Status.Inventory) | ||||
| 		objects, _ := inventory.List(kustomization.Status.Inventory) | ||||
| 
 | ||||
| 		impersonation := runtimeClient.NewImpersonator( | ||||
| 			r.Client, | ||||
|  |  | |||
|  | @ -14,28 +14,29 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| package controllers | ||||
| package inventory | ||||
| 
 | ||||
| import ( | ||||
| 	"sort" | ||||
| 
 | ||||
| 	"github.com/fluxcd/pkg/apis/meta" | ||||
| 	"github.com/fluxcd/pkg/ssa" | ||||
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| 	"sigs.k8s.io/cli-utils/pkg/object" | ||||
| 
 | ||||
| 	"github.com/fluxcd/pkg/apis/meta" | ||||
| 	"github.com/fluxcd/pkg/ssa" | ||||
| 
 | ||||
| 	kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" | ||||
| ) | ||||
| 
 | ||||
| func NewInventory() *kustomizev1.ResourceInventory { | ||||
| func New() *kustomizev1.ResourceInventory { | ||||
| 	return &kustomizev1.ResourceInventory{ | ||||
| 		Entries: []kustomizev1.ResourceRef{}, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // AddObjectsToInventory extracts the metadata from the given objects and adds it to the inventory.
 | ||||
| func AddObjectsToInventory(inv *kustomizev1.ResourceInventory, set *ssa.ChangeSet) error { | ||||
| // AddChangeSet extracts the metadata from the given objects and adds it to the inventory.
 | ||||
| func AddChangeSet(inv *kustomizev1.ResourceInventory, set *ssa.ChangeSet) error { | ||||
| 	if set == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | @ -50,8 +51,8 @@ func AddObjectsToInventory(inv *kustomizev1.ResourceInventory, set *ssa.ChangeSe | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // ListObjectsInInventory returns the inventory entries as unstructured.Unstructured objects.
 | ||||
| func ListObjectsInInventory(inv *kustomizev1.ResourceInventory) ([]*unstructured.Unstructured, error) { | ||||
| // List returns the inventory entries as unstructured.Unstructured objects.
 | ||||
| func List(inv *kustomizev1.ResourceInventory) ([]*unstructured.Unstructured, error) { | ||||
| 	objects := make([]*unstructured.Unstructured, 0) | ||||
| 
 | ||||
| 	if inv.Entries == nil { | ||||
|  | @ -79,8 +80,8 @@ func ListObjectsInInventory(inv *kustomizev1.ResourceInventory) ([]*unstructured | |||
| 	return objects, nil | ||||
| } | ||||
| 
 | ||||
| // ListMetaInInventory returns the inventory entries as object.ObjMetadata objects.
 | ||||
| func ListMetaInInventory(inv *kustomizev1.ResourceInventory) (object.ObjMetadataSet, error) { | ||||
| // ListMetadata returns the inventory entries as object.ObjMetadata objects.
 | ||||
| func ListMetadata(inv *kustomizev1.ResourceInventory) (object.ObjMetadataSet, error) { | ||||
| 	var metas []object.ObjMetadata | ||||
| 	for _, e := range inv.Entries { | ||||
| 		m, err := object.ParseObjMetadata(e.ID) | ||||
|  | @ -93,8 +94,8 @@ func ListMetaInInventory(inv *kustomizev1.ResourceInventory) (object.ObjMetadata | |||
| 	return metas, nil | ||||
| } | ||||
| 
 | ||||
| // DiffInventory returns the slice of objects that do not exist in the target inventory.
 | ||||
| func DiffInventory(inv *kustomizev1.ResourceInventory, target *kustomizev1.ResourceInventory) ([]*unstructured.Unstructured, error) { | ||||
| // Diff returns the slice of objects that do not exist in the target inventory.
 | ||||
| func Diff(inv *kustomizev1.ResourceInventory, target *kustomizev1.ResourceInventory) ([]*unstructured.Unstructured, error) { | ||||
| 	versionOf := func(i *kustomizev1.ResourceInventory, objMetadata object.ObjMetadata) string { | ||||
| 		for _, entry := range i.Entries { | ||||
| 			if entry.ID == objMetadata.String() { | ||||
|  | @ -105,12 +106,12 @@ func DiffInventory(inv *kustomizev1.ResourceInventory, target *kustomizev1.Resou | |||
| 	} | ||||
| 
 | ||||
| 	objects := make([]*unstructured.Unstructured, 0) | ||||
| 	aList, err := ListMetaInInventory(inv) | ||||
| 	aList, err := ListMetadata(inv) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	bList, err := ListMetaInInventory(target) | ||||
| 	bList, err := ListMetadata(target) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -136,7 +137,8 @@ func DiffInventory(inv *kustomizev1.ResourceInventory, target *kustomizev1.Resou | |||
| 	return objects, nil | ||||
| } | ||||
| 
 | ||||
| func referenceToObjMetadataSet(cr []meta.NamespacedObjectKindReference) (object.ObjMetadataSet, error) { | ||||
| // ReferenceToObjMetadataSet transforms a NamespacedObjectKindReference to an ObjMetadataSet.
 | ||||
| func ReferenceToObjMetadataSet(cr []meta.NamespacedObjectKindReference) (object.ObjMetadataSet, error) { | ||||
| 	var objects []object.ObjMetadata | ||||
| 
 | ||||
| 	for _, c := range cr { | ||||
|  | @ -0,0 +1,93 @@ | |||
| /* | ||||
| Copyright 2022 The Flux authors | ||||
| 
 | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
| 
 | ||||
|     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| 
 | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| package inventory | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	. "github.com/onsi/gomega" | ||||
| 	"sigs.k8s.io/cli-utils/pkg/object" | ||||
| 
 | ||||
| 	"github.com/fluxcd/pkg/ssa" | ||||
| ) | ||||
| 
 | ||||
| func Test_Inventory(t *testing.T) { | ||||
| 	g := NewWithT(t) | ||||
| 
 | ||||
| 	set1, err := readManifest("testdata/inventory1.yaml") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	inv1 := New() | ||||
| 	err = AddChangeSet(inv1, set1) | ||||
| 	g.Expect(err).ToNot(HaveOccurred()) | ||||
| 
 | ||||
| 	set2, err := readManifest("testdata/inventory2.yaml") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	inv2 := New() | ||||
| 	err = AddChangeSet(inv2, set2) | ||||
| 	g.Expect(err).ToNot(HaveOccurred()) | ||||
| 
 | ||||
| 	t.Run("lists objects in inventory", func(t *testing.T) { | ||||
| 		unList, err := List(inv1) | ||||
| 		g.Expect(err).ToNot(HaveOccurred()) | ||||
| 		g.Expect(len(unList)).To(BeIdenticalTo(len(inv1.Entries))) | ||||
| 
 | ||||
| 		mList, err := ListMetadata(inv1) | ||||
| 		g.Expect(err).ToNot(HaveOccurred()) | ||||
| 		g.Expect(len(mList)).To(BeIdenticalTo(len(inv1.Entries))) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("diff objects in inventory", func(t *testing.T) { | ||||
| 		unList, err := Diff(inv2, inv1) | ||||
| 		g.Expect(err).ToNot(HaveOccurred()) | ||||
| 		g.Expect(len(unList)).To(BeIdenticalTo(1)) | ||||
| 		g.Expect(unList[0].GetName()).To(BeIdenticalTo("test2")) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func readManifest(manifest string) (*ssa.ChangeSet, error) { | ||||
| 	data, err := os.ReadFile(manifest) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	objects, err := ssa.ReadObjects(strings.NewReader(string(data))) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	cs := ssa.NewChangeSet() | ||||
| 
 | ||||
| 	for _, o := range objects { | ||||
| 		cse := ssa.ChangeSetEntry{ | ||||
| 			ObjMetadata:  object.UnstructuredToObjMetadata(o), | ||||
| 			GroupVersion: o.GroupVersionKind().Version, | ||||
| 			Subject:      ssa.FmtUnstructured(o), | ||||
| 			Action:       string(ssa.CreatedAction), | ||||
| 		} | ||||
| 		cs.Add(cse) | ||||
| 	} | ||||
| 
 | ||||
| 	return cs, nil | ||||
| } | ||||
|  | @ -0,0 +1,12 @@ | |||
| apiVersion: v1 | ||||
| kind: Namespace | ||||
| metadata: | ||||
|   name: test | ||||
| --- | ||||
| apiVersion: v1 | ||||
| kind: ConfigMap | ||||
| metadata: | ||||
|   name: test1 | ||||
|   namespace: test | ||||
| data: | ||||
|   key: value1 | ||||
|  | @ -0,0 +1,20 @@ | |||
| apiVersion: v1 | ||||
| kind: Namespace | ||||
| metadata: | ||||
|   name: test | ||||
| --- | ||||
| apiVersion: v1 | ||||
| kind: ConfigMap | ||||
| metadata: | ||||
|   name: test1 | ||||
|   namespace: test | ||||
| data: | ||||
|   key: value1 | ||||
| --- | ||||
| apiVersion: v1 | ||||
| kind: ConfigMap | ||||
| metadata: | ||||
|   name: test2 | ||||
|   namespace: test | ||||
| data: | ||||
|   key: value2 | ||||
		Loading…
	
		Reference in New Issue