From b1122a3e0b0f64a9e9748ae3794f4e99db6a6e1e Mon Sep 17 00:00:00 2001 From: Sean Sullivan Date: Tue, 14 Jan 2020 15:34:47 -0800 Subject: [PATCH] Adds PrependGroupingObject() as apply pre-processor --- cmd/kubectl/kubectlcobra/commands.go | 26 ++++++++++ cmd/kubectl/kubectlcobra/commands_test.go | 58 +++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 cmd/kubectl/kubectlcobra/commands_test.go diff --git a/cmd/kubectl/kubectlcobra/commands.go b/cmd/kubectl/kubectlcobra/commands.go index fd365e2b0..ade1205cc 100644 --- a/cmd/kubectl/kubectlcobra/commands.go +++ b/cmd/kubectl/kubectlcobra/commands.go @@ -6,6 +6,7 @@ package kubectlcobra import ( "flag" + "fmt" "os" "strings" @@ -80,6 +81,7 @@ func updateHelp(names []string, c *cobra.Command) { func NewCmdApply(baseName string, f util.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { o := apply.NewApplyOptions(ioStreams) so := newStatusOptions(f, ioStreams) + o.PreProcessorFn = PrependGroupingObject(o) cmd := &cobra.Command{ Use: "apply (-f FILENAME | -k DIRECTORY)", @@ -118,3 +120,27 @@ func NewCmdApply(baseName string, f util.Factory, ioStreams genericclioptions.IO return cmd } + +// PrependGroupingObject orders the objects to apply so the "grouping" +// object stores the inventory, and it is first to be applied. +func PrependGroupingObject(o *apply.ApplyOptions) func() error { + return func() error { + if o == nil { + return fmt.Errorf("ApplyOptions are nil") + } + infos, err := o.GetObjects() + if err != nil { + return err + } + _, exists := findGroupingObject(infos) + if exists { + if err := addInventoryToGroupingObj(infos); err != nil { + return err + } + if !sortGroupingObject(infos) { + return err + } + } + return nil + } +} diff --git a/cmd/kubectl/kubectlcobra/commands_test.go b/cmd/kubectl/kubectlcobra/commands_test.go new file mode 100644 index 000000000..4d6b5ee5d --- /dev/null +++ b/cmd/kubectl/kubectlcobra/commands_test.go @@ -0,0 +1,58 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +// package kubectlcobra contains cobra commands from kubectl +package kubectlcobra + +import ( + "testing" + + "k8s.io/cli-runtime/pkg/resource" + "k8s.io/kubectl/pkg/cmd/apply" +) + +func TestPrependGroupingObject(t *testing.T) { + tests := []struct { + infos []*resource.Info + }{ + { + infos: []*resource.Info{copyGroupingInfo()}, + }, + { + infos: []*resource.Info{pod1Info, pod3Info, copyGroupingInfo()}, + }, + { + infos: []*resource.Info{pod1Info, pod2Info, copyGroupingInfo(), pod3Info}, + }, + } + + for _, test := range tests { + applyOptions := createApplyOptions(test.infos) + f := PrependGroupingObject(applyOptions) + err := f() + if err != nil { + t.Errorf("Error running pre-processor callback: %s", err) + } + infos, _ := applyOptions.GetObjects() + if len(test.infos) != len(infos) { + t.Fatalf("Wrong number of objects after prepending grouping object") + } + groupingInfo := infos[0] + if !isGroupingObject(groupingInfo.Object) { + t.Fatalf("First object is not the grouping object") + } + inventory, _ := retrieveInventoryFromGroupingObj(infos) + if len(inventory) != (len(infos) - 1) { + t.Errorf("Wrong number of inventory items stored in grouping object") + } + } + +} + +// createApplyOptions is a helper function to assemble the ApplyOptions +// with the passed objects (infos). +func createApplyOptions(infos []*resource.Info) *apply.ApplyOptions { + applyOptions := &apply.ApplyOptions{} + applyOptions.SetObjects(infos) + return applyOptions +}