diff --git a/pkg/action/install.go b/pkg/action/install.go index 8ae84a699..b47b9f439 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -162,12 +162,24 @@ func (i *Install) installCRDs(crds []chart.CRD) error { // We do these one file at a time in the order they were read. totalItems := []*resource.Info{} for _, obj := range crds { + if obj.File == nil { + return fmt.Errorf("failed to install CRD %s: file is empty", obj.Name) + } + + if obj.File.Data == nil { + return fmt.Errorf("failed to install CRD %s: file data is empty", obj.Name) + } + // Read in the resources res, err := i.cfg.KubeClient.Build(bytes.NewBuffer(obj.File.Data), false) if err != nil { return errors.Wrapf(err, "failed to install CRD %s", obj.Name) } + if len(res) == 0 { + return fmt.Errorf("failed to install CRD %s: resources are empty", obj.Name) + } + // Send them to Kube if _, err := i.cfg.KubeClient.Create(res); err != nil { // If the error is CRD already exists, continue. diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index 8f4cb4c5d..c3cc395ba 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -916,6 +916,59 @@ func TestInstallCRDsWithNilRESTClientGetter(t *testing.T) { require.NoError(t, err) } +func TestInstallCRDsRejectsInvalidInput(t *testing.T) { + tests := []struct { + name string + crd chart.CRD + dummyResources kube.ResourceList + wantErr string + }{ + { + name: "nil file", + crd: chart.CRD{ + Name: "test-crd", + }, + wantErr: "file is empty", + }, + { + name: "nil file data", + crd: chart.CRD{ + Name: "test-crd", + File: &chart.File{Name: "crds/test-crd.yaml"}, + }, + wantErr: "file data is empty", + }, + { + name: "empty resources", + crd: chart.CRD{ + Name: "test-crd", + File: &chart.File{ + Name: "crds/test-crd.yaml", + Data: []byte("kind: CustomResourceDefinition"), + }, + }, + dummyResources: kube.ResourceList{}, + wantErr: "resources are empty", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := actionConfigFixture(t) + if tt.dummyResources != nil { + config.KubeClient = &kubefake.FailingKubeClient{ + PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, + DummyResources: tt.dummyResources, + } + } + instAction := NewInstall(config) + + err := instAction.installCRDs([]chart.CRD{tt.crd}) + require.ErrorContains(t, err, tt.wantErr) + }) + } +} + func TestInstallWithLabels(t *testing.T) { is := assert.New(t) instAction := installAction(t)