From a106f7c33b0751e64bf16a7e683ef32f6c07f837 Mon Sep 17 00:00:00 2001 From: Evan Cordell Date: Thu, 12 Dec 2019 08:05:37 -0500 Subject: [PATCH] feat(resolver): fallback to csv parsing if grcp api does not contain the information required --- pkg/controller/registry/resolver/operators.go | 36 +++++++++--- .../registry/resolver/operators_test.go | 55 +++++++++++++++++++ 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/pkg/controller/registry/resolver/operators.go b/pkg/controller/registry/resolver/operators.go index 82b0c56b46..ea9d0165b5 100644 --- a/pkg/controller/registry/resolver/operators.go +++ b/pkg/controller/registry/resolver/operators.go @@ -257,7 +257,6 @@ func NewOperatorFromBundle(bundle *api.Bundle, replaces string, startingCSV stri if err != nil { v = nil } - provided := APISet{} for _, gvk := range bundle.ProvidedApis { provided[registry.APIKey{Plural: gvk.Plural, Group: gvk.Group, Kind: gvk.Kind, Version: gvk.Version}] = struct{}{} @@ -266,6 +265,34 @@ func NewOperatorFromBundle(bundle *api.Bundle, replaces string, startingCSV stri for _, gvk := range bundle.RequiredApis { required[registry.APIKey{Plural: gvk.Plural, Group: gvk.Group, Kind: gvk.Kind, Version: gvk.Version}] = struct{}{} } + sourceInfo := &OperatorSourceInfo{ + Package: bundle.PackageName, + Channel: bundle.ChannelName, + StartingCSV: startingCSV, + Catalog: sourceKey, + } + + // legacy support - if the grpc api doesn't contain the information we need, fallback to csv parsing + if len(required) == 0 && len(provided) == 0 { + // fallback to csv parsing + if bundle.CsvJson == "" { + return nil, fmt.Errorf("couldn't parse bundle") + } + + csv := &v1alpha1.ClusterServiceVersion{} + if err := json.Unmarshal([]byte(bundle.CsvJson), csv); err != nil { + return nil, err + } + + op, err := NewOperatorFromV1Alpha1CSV(csv) + if err != nil { + return nil, err + } + op.sourceInfo = sourceInfo + op.bundle = bundle + op.replaces = r + return op, nil + } return &Operator{ name: csv.GetName(), @@ -274,12 +301,7 @@ func NewOperatorFromBundle(bundle *api.Bundle, replaces string, startingCSV stri providedAPIs: provided, requiredAPIs: required, bundle: bundle, - sourceInfo: &OperatorSourceInfo{ - Package: bundle.PackageName, - Channel: bundle.ChannelName, - StartingCSV: startingCSV, - Catalog: sourceKey, - }, + sourceInfo: sourceInfo, }, nil } diff --git a/pkg/controller/registry/resolver/operators_test.go b/pkg/controller/registry/resolver/operators_test.go index b2686a3f49..e99c0946a6 100644 --- a/pkg/controller/registry/resolver/operators_test.go +++ b/pkg/controller/registry/resolver/operators_test.go @@ -1019,6 +1019,14 @@ func TestNewOperatorFromBundle(t *testing.T) { }, } + bundleWithAPIsUnextracted := &api.Bundle{ + CsvName: "testBundle", + PackageName: "testPackage", + ChannelName: "testChannel", + CsvJson: string(csvJsonWithApis), + Object: []string{string(csvJsonWithApis), string(crdJson)}, + } + type args struct { bundle *api.Bundle sourceKey CatalogKey @@ -1119,6 +1127,53 @@ func TestNewOperatorFromBundle(t *testing.T) { }, }, }, + { + name: "BundleCsvFallback", + args: args{ + bundle: bundleWithAPIsUnextracted, + sourceKey: CatalogKey{Name: "source", Namespace: "testNamespace"}, + replaces: "replaced", + }, + want: &Operator{ + name: "testCSV", + providedAPIs: APISet{ + opregistry.APIKey{ + Group: "crd.group.com", + Version: "v1", + Kind: "OwnedCRD", + Plural: "owneds", + }: struct{}{}, + opregistry.APIKey{ + Group: "apis.group.com", + Version: "v1", + Kind: "OwnedAPI", + Plural: "ownedapis", + }: struct{}{}, + }, + requiredAPIs: APISet{ + opregistry.APIKey{ + Group: "crd.group.com", + Version: "v1", + Kind: "RequiredCRD", + Plural: "requireds", + }: struct{}{}, + opregistry.APIKey{ + Group: "apis.group.com", + Version: "v1", + Kind: "RequiredAPI", + Plural: "requiredapis", + }: struct{}{}, + }, + bundle: bundleWithAPIsUnextracted, + replaces: "replaced", + version: &version.Version, + sourceInfo: &OperatorSourceInfo{ + Package: "testPackage", + Channel: "testChannel", + Catalog: CatalogKey{"source", "testNamespace"}, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {