diff --git a/cmd/apply/cmdapply.go b/cmd/apply/cmdapply.go index c1d1918c..7347def2 100644 --- a/cmd/apply/cmdapply.go +++ b/cmd/apply/cmdapply.go @@ -132,10 +132,11 @@ func (r *ApplyRunner) RunE(cmd *cobra.Command, args []string) error { return err } - inv, objs, err := r.loader.InventoryInfo(objs) + invObj, objs, err := inventory.SplitUnstructureds(objs) if err != nil { return err } + inv := inventory.WrapInventoryInfoObj(invObj) if r.PreProcess != nil { inventoryPolicy, err = r.PreProcess(inv, common.DryRunNone) @@ -143,6 +144,7 @@ func (r *ApplyRunner) RunE(cmd *cobra.Command, args []string) error { return err } } + statusPoller, err := factory.NewStatusPoller(r.factory) if err != nil { return err diff --git a/cmd/destroy/cmddestroy.go b/cmd/destroy/cmddestroy.go index 7b1600bb..85a43d76 100644 --- a/cmd/destroy/cmddestroy.go +++ b/cmd/destroy/cmddestroy.go @@ -102,10 +102,11 @@ func (r *DestroyRunner) RunE(cmd *cobra.Command, args []string) error { if err != nil { return err } - inv, _, err := r.loader.InventoryInfo(objs) + invObj, _, err := inventory.SplitUnstructureds(objs) if err != nil { return err } + inv := inventory.WrapInventoryInfoObj(invObj) if r.PreProcess != nil { inventoryPolicy, err = r.PreProcess(inv, common.DryRunNone) diff --git a/cmd/preview/cmdpreview.go b/cmd/preview/cmdpreview.go index 785d2efe..6e71807b 100644 --- a/cmd/preview/cmdpreview.go +++ b/cmd/preview/cmdpreview.go @@ -117,10 +117,11 @@ func (r *PreviewRunner) RunE(cmd *cobra.Command, args []string) error { return err } - inv, objs, err := r.loader.InventoryInfo(objs) + invObj, objs, err := inventory.SplitUnstructureds(objs) if err != nil { return err } + inv := inventory.WrapInventoryInfoObj(invObj) if r.PreProcess != nil { inventoryPolicy, err = r.PreProcess(inv, drs) diff --git a/cmd/status/cmdstatus.go b/cmd/status/cmdstatus.go index 8cafe866..c373e38e 100644 --- a/cmd/status/cmdstatus.go +++ b/cmd/status/cmdstatus.go @@ -86,10 +86,11 @@ func (r *StatusRunner) runE(cmd *cobra.Command, args []string) error { return err } - inv, _, err := r.loader.InventoryInfo(objs) + invObj, _, err := inventory.SplitUnstructureds(objs) if err != nil { return err } + inv := inventory.WrapInventoryInfoObj(invObj) invClient, err := r.invFactory.NewInventoryClient(r.factory) if err != nil { diff --git a/cmd/status/cmdstatus_test.go b/cmd/status/cmdstatus_test.go index 71cdc2f0..c988963b 100644 --- a/cmd/status/cmdstatus_test.go +++ b/cmd/status/cmdstatus_test.go @@ -64,10 +64,6 @@ func TestStatusCommand(t *testing.T) { expectedErrMsg string expectedOutput string }{ - "no inventory template": { - input: "", - expectedErrMsg: "Package uninitialized. Please run \"init\" command.", - }, "no inventory in live state": { input: inventoryTemplate, expectedOutput: "no resources found in the inventory\n", diff --git a/pkg/inventory/inventory.go b/pkg/inventory/inventory.go index c37d8d5d..b87d2856 100644 --- a/pkg/inventory/inventory.go +++ b/pkg/inventory/inventory.go @@ -98,7 +98,9 @@ func ValidateNoInventory(objs object.UnstructuredSet) error { // splitUnstructureds takes a set of unstructured.Unstructured objects and // splits it into one set that contains the inventory object templates and -// another one that contains the remaining resources. +// another one that contains the remaining resources. If there is no inventory +// object the first return value is nil. Returns an error if there are +// more than one inventory objects. func SplitUnstructureds(objs object.UnstructuredSet) (*unstructured.Unstructured, object.UnstructuredSet, error) { invs := make(object.UnstructuredSet, 0) resources := make(object.UnstructuredSet, 0) @@ -109,14 +111,16 @@ func SplitUnstructureds(objs object.UnstructuredSet) (*unstructured.Unstructured resources = append(resources, obj) } } - if len(invs) == 0 { - return nil, resources, NoInventoryObjError{} + var inv *unstructured.Unstructured + var err error + if len(invs) == 1 { + inv = invs[0] } else if len(invs) > 1 { - return nil, resources, MultipleInventoryObjError{ + err = MultipleInventoryObjError{ InventoryObjectTemplates: invs, } } - return invs[0], resources, nil + return inv, resources, err } // addSuffixToName adds the passed suffix (usually a hash) as a suffix diff --git a/pkg/inventory/inventory_test.go b/pkg/inventory/inventory_test.go index 566a93b0..8910f309 100644 --- a/pkg/inventory/inventory_test.go +++ b/pkg/inventory/inventory_test.go @@ -241,47 +241,52 @@ func TestRetrieveInventoryLabel(t *testing.T) { func TestSplitUnstructureds(t *testing.T) { tests := map[string]struct { - allObjs []*unstructured.Unstructured - invObj *unstructured.Unstructured - objs []*unstructured.Unstructured - isError bool + allObjs []*unstructured.Unstructured + expectedInv *unstructured.Unstructured + expectedObjs []*unstructured.Unstructured + isError bool }{ - "No objects is an error": { - allObjs: []*unstructured.Unstructured{}, - invObj: nil, - objs: []*unstructured.Unstructured{}, - isError: true, + "No objects is returns nil and no objects": { + allObjs: []*unstructured.Unstructured{}, + expectedInv: nil, + expectedObjs: []*unstructured.Unstructured{}, + isError: false, }, - "Only inventory object is true": { - allObjs: []*unstructured.Unstructured{inventoryObj}, - invObj: inventoryObj, - objs: []*unstructured.Unstructured{}, - isError: false, + "Only inventory object returns inv and no objects": { + allObjs: []*unstructured.Unstructured{inventoryObj}, + expectedInv: inventoryObj, + expectedObjs: []*unstructured.Unstructured{}, + isError: false, }, - "Missing inventory object is false": { - allObjs: []*unstructured.Unstructured{pod1}, - invObj: nil, - objs: []*unstructured.Unstructured{pod1}, - isError: true, + "Single object returns nil inventory and object": { + allObjs: []*unstructured.Unstructured{pod1}, + expectedInv: nil, + expectedObjs: []*unstructured.Unstructured{pod1}, + isError: false, }, - "Multiple non-inventory objects is false": { - allObjs: []*unstructured.Unstructured{pod1, pod2, pod3}, - invObj: nil, - objs: []*unstructured.Unstructured{pod1, pod2, pod3}, - isError: true, + "Multiple non-inventory objects returns nil inventory and objs": { + allObjs: []*unstructured.Unstructured{pod1, pod2, pod3}, + expectedInv: nil, + expectedObjs: []*unstructured.Unstructured{pod1, pod2, pod3}, + isError: false, }, - "Inventory object with multiple others is true": { - allObjs: []*unstructured.Unstructured{pod1, pod2, inventoryObj, pod3}, - invObj: inventoryObj, - objs: []*unstructured.Unstructured{pod1, pod2, pod3}, - isError: false, + "Inventory object with multiple others splits correctly": { + allObjs: []*unstructured.Unstructured{pod1, pod2, inventoryObj, pod3}, + expectedInv: inventoryObj, + expectedObjs: []*unstructured.Unstructured{pod1, pod2, pod3}, + isError: false, + }, + "Multiple inventory objects returns error": { + allObjs: []*unstructured.Unstructured{pod1, legacyInvObj, inventoryObj, pod3}, + expectedInv: nil, + expectedObjs: []*unstructured.Unstructured{}, + isError: true, }, } for name, tc := range tests { t.Run(name, func(t *testing.T) { - invObj, infos, err := SplitUnstructureds(tc.allObjs) - inv := WrapInventoryInfoObj(invObj) + actualInv, actualObjs, err := SplitUnstructureds(tc.allObjs) if !tc.isError && err != nil { t.Fatalf("unexpected error received: %s", err) } @@ -291,13 +296,11 @@ func TestSplitUnstructureds(t *testing.T) { } return } - - if tc.invObj.GetName() != inv.Name() || - tc.invObj.GetNamespace() != inv.Namespace() { - t.Errorf("expected inventory (%v); got (%v)", tc.invObj, inv) + if tc.expectedInv != actualInv { + t.Errorf("expected inventory object (%v), got (%v)", tc.expectedInv, actualInv) } - if len(tc.objs) != len(infos) { - t.Errorf("expected %d objects; got %d", len(tc.objs), len(infos)) + if len(tc.expectedObjs) != len(actualObjs) { + t.Errorf("expected %d objects; got %d", len(tc.expectedObjs), len(actualObjs)) } }) } diff --git a/pkg/manifestreader/manifestloader.go b/pkg/manifestreader/manifestloader.go index 9645043a..e89cd3b6 100644 --- a/pkg/manifestreader/manifestloader.go +++ b/pkg/manifestreader/manifestloader.go @@ -6,20 +6,16 @@ package manifestreader import ( "io" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/kubectl/pkg/cmd/util" - "sigs.k8s.io/cli-utils/pkg/inventory" ) // ManifestLoader is an interface for reading -// and parsing the resources and inventory info. +// and parsing the resources type ManifestLoader interface { - InventoryInfo([]*unstructured.Unstructured) (inventory.InventoryInfo, []*unstructured.Unstructured, error) ManifestReader(reader io.Reader, path string) (ManifestReader, error) } // manifestLoader implements the ManifestLoader interface -// for ConfigMap as the inventory object. type manifestLoader struct { factory util.Factory } @@ -31,12 +27,6 @@ func NewManifestLoader(f util.Factory) ManifestLoader { } } -// InventoryInfo returns the InventoryInfo from a list of Unstructured objects. -func (f *manifestLoader) InventoryInfo(objs []*unstructured.Unstructured) (inventory.InventoryInfo, []*unstructured.Unstructured, error) { - invObj, objs, err := inventory.SplitUnstructureds(objs) - return inventory.WrapInventoryInfoObj(invObj), objs, err -} - func (f *manifestLoader) ManifestReader(reader io.Reader, path string) (ManifestReader, error) { // Fetch the namespace from the configloader. The source of this // either the namespace flag or the context. If the namespace is provided