diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 38c8b93f2..546801423 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -41,6 +41,7 @@ import ( "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/strategicpatch" "k8s.io/apimachinery/pkg/watch" "k8s.io/cli-runtime/pkg/genericclioptions" @@ -373,16 +374,17 @@ func perform(infos ResourceList, fn func(*resource.Info) error) error { return ErrNoObjectsVisited } + errorList := make([]error, 0) errs := make(chan error) go batchPerform(infos, fn, errs) for range infos { err := <-errs if err != nil { - return err + errorList = append(errorList, err) } } - return nil + return utilerrors.NewAggregate(errorList) } // getManagedFieldsManager returns the manager string. If one was set it will be returned. diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index de5358aee..664a52b43 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -18,10 +18,12 @@ package kube import ( "bytes" + "fmt" "io" "io/ioutil" "net/http" "strings" + "sync" "testing" v1 "k8s.io/api/core/v1" @@ -265,19 +267,32 @@ func TestPerform(t *testing.T) { name: "Valid input", reader: strings.NewReader(guestbookManifest), count: 6, - }, { + }, + { name: "Empty manifests", reader: strings.NewReader(""), err: true, errMessage: "no objects visited", }, + { + name: "Error manifests", + reader: strings.NewReader(testErrorManifest), + count: 2, + err: true, + errMessage: "[resource endpoints/my-service already exists, resource services/redis-master already exists]", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { results := []*resource.Info{} - + resourceMap := sync.Map{} fn := func(info *resource.Info) error { + _, exist := resourceMap.Load(info.ObjectName()) + if exist { + return fmt.Errorf("resource %s already exists", info.ObjectName()) + } + resourceMap.Store(info.ObjectName(), struct{}{}) results = append(results, info) return nil } @@ -520,3 +535,59 @@ spec: ports: - containerPort: 80 ` + +const testErrorManifest = ` +kind: Endpoints +apiVersion: v1 +metadata: + name: my-service +subsets: + - addresses: + - ip: "1.2.3.4" + ports: + - port: 9376 +--- +kind: Endpoints +apiVersion: v1 +metadata: + name: my-service +subsets: + - addresses: + - ip: "1.2.3.4" + ports: + - port: 9376 +--- +apiVersion: v1 +kind: Service +metadata: + name: redis-master + labels: + app: redis + tier: backend + role: master +spec: + ports: + - port: 6379 + targetPort: 6379 + selector: + app: redis + tier: backend + role: master +--- +apiVersion: v1 +kind: Service +metadata: + name: redis-master + labels: + app: redis + tier: backend + role: master +spec: + ports: + - port: 6379 + targetPort: 6379 + selector: + app: redis + tier: backend + role: master +`