From 2b01c8fa1a179c7142bdf33668170f3eac5de7d7 Mon Sep 17 00:00:00 2001 From: Evan Cordell Date: Tue, 4 Feb 2020 16:56:05 -0500 Subject: [PATCH] feat(bbolt): serialization for capabilities/requirements --- pkg/boltdb/load.go | 37 +++++------ pkg/boltdb/migrate.go | 106 +++++++++++++++----------------- pkg/boltdb/migrate_test.go | 10 ++- pkg/boltdb/model/codec.go | 92 +++++++++++++++++++++++++++ pkg/boltdb/model/codec_test.go | 47 ++++++++++++++ pkg/boltdb/model/gvk.go | 37 +++++++++++ pkg/boltdb/{ => model}/types.go | 40 ++---------- pkg/boltdb/query.go | 64 +++++++++---------- 8 files changed, 289 insertions(+), 144 deletions(-) create mode 100644 pkg/boltdb/model/codec.go create mode 100644 pkg/boltdb/model/codec_test.go create mode 100644 pkg/boltdb/model/gvk.go rename pkg/boltdb/{ => model}/types.go (64%) diff --git a/pkg/boltdb/load.go b/pkg/boltdb/load.go index c93b2c434..53729ee17 100644 --- a/pkg/boltdb/load.go +++ b/pkg/boltdb/load.go @@ -2,6 +2,7 @@ package boltdb import ( "fmt" + "github.com/operator-framework/operator-registry/pkg/boltdb/model" "github.com/asdine/storm/v3" utilerrors "k8s.io/apimachinery/pkg/util/errors" @@ -49,8 +50,8 @@ func (s *StormLoader) AddOperatorBundle(bundle *registry.Bundle) error { } for image := range images { - err = tx.Save(&RelatedImage{ - ImageUser: ImageUser{ + err = tx.Save(&model.RelatedImage{ + ImageUser: model.ImageUser{ OperatorBundleName: opBundle.Name, Image: image, }, @@ -75,7 +76,7 @@ func (s *StormLoader) AddPackageChannels(manifest registry.PackageManifest) erro } defer tx.Rollback() - pkg := Package{ + pkg := model.Package{ Name: manifest.PackageName, DefaultChannel: manifest.DefaultChannelName, } @@ -86,11 +87,11 @@ func (s *StormLoader) AddPackageChannels(manifest registry.PackageManifest) erro var errs []error for _, channel := range manifest.Channels { // Get and store the update graph starting at the channel head - pkgChannel := PackageChannel{ + pkgChannel := model.PackageChannel{ ChannelName: channel.Name, PackageName: pkg.Name, } - err = tx.Save(&Channel{ + err = tx.Save(&model.Channel{ PackageChannel: pkgChannel, HeadOperatorBundleName: channel.CurrentCSVName, }) @@ -126,13 +127,13 @@ func (s *StormLoader) ClearNonDefaultBundles(packageName string) error { panic("implement me") } -func (s *StormLoader) updateGraph(pkgName, channelName, operatorBundleName string) (entries []ChannelEntry, err error) { - var head OperatorBundle +func (s *StormLoader) updateGraph(pkgName, channelName, operatorBundleName string) (entries []model.ChannelEntry, err error) { + var head model.OperatorBundle if err = s.db.One("Name", operatorBundleName, &head); err != nil { return } - pkgChannel := PackageChannel{ + pkgChannel := model.PackageChannel{ PackageName: pkgName, ChannelName: channelName, } @@ -145,8 +146,8 @@ func (s *StormLoader) updateGraph(pkgName, channelName, operatorBundleName strin return } - entry := ChannelEntry{ - ChannelReplacement: ChannelReplacement{ + entry := model.ChannelEntry{ + ChannelReplacement: model.ChannelReplacement{ PackageChannel: pkgChannel, BundleName: o.Name, Replaces: o.Replaces, @@ -189,7 +190,7 @@ func (s *StormLoader) updateGraph(pkgName, channelName, operatorBundleName strin return } -func newOperatorBundle(bundle *registry.Bundle) (*OperatorBundle, error) { +func newOperatorBundle(bundle *registry.Bundle) (*model.OperatorBundle, error) { // Add the core bundle csvName, bundleImage, csvBytes, bundleBytes, err := bundle.Serialize() if err != nil { @@ -223,24 +224,24 @@ func newOperatorBundle(bundle *registry.Bundle) (*OperatorBundle, error) { return nil, err } - capabilities := make([]Capability, 0) + capabilities := make([]model.Capability, 0) for api := range providedApis { - capabilities = append(capabilities, Capability{ - Name: GvkCapability, + capabilities = append(capabilities, model.Capability{ + Name: model.GvkCapability, Value: api.String(), }) } - requirements := make([]Requirement, 0) + requirements := make([]model.Requirement, 0) for api := range requiredApis { - requirements = append(requirements, Requirement{ + requirements = append(requirements, model.Requirement{ Optional: false, - Name: GvkCapability, + Name: model.GvkCapability, Selector: api.String(), }) } - opBundle := &OperatorBundle{ + opBundle := &model.OperatorBundle{ Name: csvName, Version: version, Replaces: replaces, diff --git a/pkg/boltdb/migrate.go b/pkg/boltdb/migrate.go index 2ef47205e..00bf2b8ad 100644 --- a/pkg/boltdb/migrate.go +++ b/pkg/boltdb/migrate.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/alicebob/sqlittle" "github.com/asdine/storm/v3" + "github.com/operator-framework/operator-registry/pkg/boltdb/model" bolt "go.etcd.io/bbolt" "os" ) @@ -35,9 +36,9 @@ func EnsureBolt(file string, backupFile string) error { // TODO: check if sqlite file is at latest migration - bdb, err := storm.Open(file) + bdb, err := storm.Open(file, storm.Codec(model.Codec)) if err != nil { - return nil + return err } if err := migrateSqliteToBolt(sqlDb, bdb); err != nil { @@ -83,10 +84,10 @@ func migrateSqliteToBolt(sqlDb *sqlittle.DB, bdb *storm.DB) error { return tx.Commit() } -func migrate(node storm.Node, sqlDb *sqlittle.DB, rowMigrator rowMigrator) error { +func migrate(node storm.Node, sqlDb *sqlittle.DB, rm rowMigrator) error { // migrate package table migrateError := make([]error, 0) - migrator, table, columns := rowMigrator(node, migrateError) + migrator, table, columns := rm(node, migrateError) if err := sqlDb.Select(table, migrator, columns...); err != nil { return err } @@ -110,7 +111,7 @@ func migratePackageRow(node storm.Node, errs []error) (sqlittle.RowCB, string, [ errs = append(errs, err) return } - pkg := Package{ + pkg := model.Package{ Name: name, DefaultChannel: defaultChannel, } @@ -135,8 +136,8 @@ func migrateChannelRow(node storm.Node, errs []error) (sqlittle.RowCB, string, [ return } fmt.Printf("migrating channel %s %s %s\n", name, pkgName, headBundleName) - ch := Channel{ - PackageChannel: PackageChannel{ + ch := model.Channel{ + PackageChannel: model.PackageChannel{ ChannelName: name, PackageName: pkgName, }, @@ -169,7 +170,7 @@ func migrateBundleRow(node storm.Node, errs []error) (sqlittle.RowCB, string, [] // TODO: replaces // TODO: skips - ob := OperatorBundle{ + ob := model.OperatorBundle{ Name: name, Version: version, //Replaces: , @@ -205,8 +206,8 @@ func migrateRelatedImageRow(node storm.Node, errs []error) (sqlittle.RowCB, stri errs = append(errs, err) return } - relatedImg := RelatedImage{ - ImageUser: ImageUser{ + relatedImg := model.RelatedImage{ + ImageUser: model.ImageUser{ Image: image, OperatorBundleName: operatorbundle_name, }, @@ -223,7 +224,7 @@ func migrateChannelEntries(sqlDb *sqlittle.DB, node storm.Node) error { table := "channel_entry" type unpack struct { - ChannelEntry + model.ChannelEntry replaces int64 } unpacks := make(map[int64]unpack, 0) @@ -241,9 +242,9 @@ func migrateChannelEntries(sqlDb *sqlittle.DB, node storm.Node) error { return } unpacks[entry_id] = unpack{ - ChannelEntry: ChannelEntry{ - ChannelReplacement: ChannelReplacement{ - PackageChannel: PackageChannel{ + ChannelEntry: model.ChannelEntry{ + ChannelReplacement: model.ChannelReplacement{ + PackageChannel: model.PackageChannel{ PackageName: package_name, ChannelName: channel_name, }, @@ -282,7 +283,7 @@ func migrateApiProviders(sqlDb *sqlittle.DB, node storm.Node) error { table := "api_provider" type unpack struct { - Capability + model.Capability channel_entry_id int64 operatorbundle_name string } @@ -300,14 +301,11 @@ func migrateApiProviders(sqlDb *sqlittle.DB, node storm.Node) error { return } unpacks = append(unpacks, unpack{ - Capability: Capability{ - Name: GvkCapability, - Value: Api{ - Group: groupName, - Version: version, - Kind: kind, - }.String(), - }, + Capability: model.NewApiCapability(&model.Api{ + Group: groupName, + Version: version, + Kind: kind, + }), channel_entry_id: channel_entry_id, }) } @@ -349,15 +347,15 @@ func migrateApiProviders(sqlDb *sqlittle.DB, node storm.Node) error { errs = append(errs, err) return } - capValue, err := ApiFromString(u.Value) - if err != nil { - errs = append(errs, err) + api, ok := u.Capability.Value.(*model.Api) + if !ok { + errs = append(errs, fmt.Errorf("couldn't parse gvk")) return } - if u.Name == GvkCapability && capValue.Group == groupName && capValue.Version == version && capValue.Kind == kind { - capValue.Plural = plural + if u.Name == model.GvkCapability && api.Group == groupName && api.Version == version && api.Kind == kind { + api.Plural = plural } - u.Value = capValue.String() + u.Value = api unpacks[i] = u }, "group_name", "version", "kind", "plural") if err != nil { @@ -370,25 +368,25 @@ func migrateApiProviders(sqlDb *sqlittle.DB, node storm.Node) error { } // connect provided apis to their owner operator bundles - bundleCapabilityFilter := make(map[string]map[string]struct{}) + bundleCapabilityFilter := make(map[string]map[model.Api]struct{}) for _, u := range unpacks { // Filter out duplicates if capabilities, ok := bundleCapabilityFilter[u.operatorbundle_name]; ok { - if _, ok := capabilities[u.Capability.Value]; ok { + if _, ok := capabilities[*u.Capability.Value.(*model.Api)]; ok { continue } } else { // initialize the set - capabilitySet := make(map[string]struct{}) + capabilitySet := make(map[model.Api]struct{}) bundleCapabilityFilter[u.operatorbundle_name] = capabilitySet } - var ob OperatorBundle + var ob model.OperatorBundle err := node.One("Name", u.operatorbundle_name, &ob) if err != nil { return err } if ob.Capabilities == nil { - ob.Capabilities = make([]Capability, 0) + ob.Capabilities = make([]model.Capability, 0) } ob.Capabilities = append(ob.Capabilities, u.Capability) if err := node.Save(&ob); err != nil { @@ -396,7 +394,7 @@ func migrateApiProviders(sqlDb *sqlittle.DB, node storm.Node) error { } // add unique item to filter once it's added to the set - bundleCapabilityFilter[u.operatorbundle_name][u.Capability.Value] = struct{}{} + bundleCapabilityFilter[u.operatorbundle_name][*u.Capability.Value.(*model.Api)] = struct{}{} } return nil @@ -407,7 +405,7 @@ func migrateApiRequirers(sqlDb *sqlittle.DB, node storm.Node) error { table := "api_requirer" type unpack struct { - Requirement + model.Requirement channel_entry_id int64 operatorbundle_name string } @@ -425,15 +423,11 @@ func migrateApiRequirers(sqlDb *sqlittle.DB, node storm.Node) error { return } unpacks = append(unpacks, unpack{ - Requirement: Requirement{ - Name: GvkCapability, - Selector: Api{ - Group: groupName, - Version: version, - Kind: kind, - }.String(), - Optional: false, - }, + Requirement: model.NewApiEqualityRequirement(&model.ApiEqualitySelector{ + Group: groupName, + Version: version, + Kind: kind, + }), channel_entry_id: channel_entry_id, }) } @@ -475,16 +469,16 @@ func migrateApiRequirers(sqlDb *sqlittle.DB, node storm.Node) error { errs = append(errs, err) return } - if u.Name == GvkCapability { - reqSelector, err := ApiFromString(u.Selector) - if err != nil { - errs = append(errs, err) + if u.Name == model.GvkCapability { + reqSelector, ok := u.Selector.(*model.ApiEqualitySelector) + if !ok { + errs = append(errs, fmt.Errorf("couldn't parse gvk selector")) return } if reqSelector.Group == groupName && reqSelector.Version == version && reqSelector.Kind == kind { reqSelector.Plural = plural } - u.Selector = reqSelector.String() + u.Selector = reqSelector unpacks[i] = u } else { err := fmt.Errorf("Unsupported requirement type: %s", u.Name) @@ -502,25 +496,25 @@ func migrateApiRequirers(sqlDb *sqlittle.DB, node storm.Node) error { } // connect required apis to their owner operator bundles - bundleRequirementFilter := make(map[string]map[string]struct{}) + bundleRequirementFilter := make(map[string]map[model.ApiEqualitySelector]struct{}) for _, u := range unpacks { // Filter out duplicates if capabilities, ok := bundleRequirementFilter[u.operatorbundle_name]; ok { - if _, ok := capabilities[u.Requirement.Selector]; ok { + if _, ok := capabilities[*u.Requirement.Selector.(*model.ApiEqualitySelector)]; ok { continue } } else { // initialize the set - capabilitySet := make(map[string]struct{}) + capabilitySet := make(map[model.ApiEqualitySelector]struct{}) bundleRequirementFilter[u.operatorbundle_name] = capabilitySet } - var ob OperatorBundle + var ob model.OperatorBundle err := node.One("Name", u.operatorbundle_name, &ob) if err != nil { return err } if ob.Requirements == nil { - ob.Requirements = make([]Requirement, 0) + ob.Requirements = make([]model.Requirement, 0) } ob.Requirements = append(ob.Requirements, u.Requirement) if err := node.Save(&ob); err != nil { @@ -528,7 +522,7 @@ func migrateApiRequirers(sqlDb *sqlittle.DB, node storm.Node) error { } // add unique item to filter once it's added to the set - bundleRequirementFilter[u.operatorbundle_name][u.Requirement.Selector] = struct{}{} + bundleRequirementFilter[u.operatorbundle_name][*u.Requirement.Selector.(*model.ApiEqualitySelector)] = struct{}{} } return nil diff --git a/pkg/boltdb/migrate_test.go b/pkg/boltdb/migrate_test.go index 4fc1910aa..355683529 100644 --- a/pkg/boltdb/migrate_test.go +++ b/pkg/boltdb/migrate_test.go @@ -4,16 +4,17 @@ import ( "context" "database/sql" "fmt" + "github.com/asdine/storm/v3" + "github.com/operator-framework/operator-registry/pkg/boltdb/model" + "github.com/operator-framework/operator-registry/pkg/registry/test" "math/rand" "os" "testing" "time" - "github.com/asdine/storm/v3" "github.com/stretchr/testify/require" "github.com/operator-framework/operator-registry/pkg/registry" - "github.com/operator-framework/operator-registry/pkg/registry/test" "github.com/operator-framework/operator-registry/pkg/sqlite" ) @@ -37,8 +38,11 @@ func TestEnsureBolt(t *testing.T) { require.NoError(t, db.Close()) require.NoError(t, EnsureBolt(dbName, backupName)) - bdb, err := storm.Open(dbName) + bdb, err := storm.Open(dbName, storm.Codec(model.Codec)) require.NoError(t, err) + tx, err := bdb.Begin(true) + + require.NoError(t, tx.Commit()) defer bdb.Close() t.Run("queriable", func(t *testing.T) { diff --git a/pkg/boltdb/model/codec.go b/pkg/boltdb/model/codec.go new file mode 100644 index 000000000..ee28665e3 --- /dev/null +++ b/pkg/boltdb/model/codec.go @@ -0,0 +1,92 @@ +package model + +import ( + "encoding/json" + "github.com/mitchellh/mapstructure" +) + +var Codec = new(capCodec) + +var capabilityTypeForName = map[string]func() interface{} {} +var requirementTypeForName = map[string]func() interface{} {} + +type capCodec int + +func (j capCodec) Marshal(v interface{}) ([]byte, error) { + return json.Marshal(v) +} + +func (j capCodec) Unmarshal(b []byte, v interface{}) error { + if err := json.Unmarshal(b, v); err != nil { + return err + } + + o, ok := v.(*OperatorBundle) + if ok { + return j.UnmarshalBundle(o) + } + + c, ok := v.(*Capability) + if ok { + return j.UnmarshalCapability(c) + } + + r, ok := v.(*Requirement) + if ok { + return j.UnmarshalRequirement(r) + } + + return nil +} + +func (j capCodec) UnmarshalBundle(o *OperatorBundle) error { + for i := range o.Capabilities{ + if err := j.UnmarshalCapability(&o.Capabilities[i]); err != nil { + return err + } + } + for i, r := range o.Requirements { + constructor, ok := requirementTypeForName[r.Name] + if !ok { + continue + } + o.Requirements[i].Selector = constructor() + if err := mapstructure.Decode(r.Selector, o.Requirements[i].Selector); err != nil { + return err + } + } + return nil +} + +func (j capCodec) UnmarshalCapability(c *Capability) error { + constructor, ok := capabilityTypeForName[c.Name] + if !ok { + return nil + } + val := c.Value + c.Value = constructor() + + if err := mapstructure.Decode(val, &c.Value); err != nil { + return err + } + + return nil +} + +func (j capCodec) UnmarshalRequirement(r *Requirement) error { + constructor, ok := requirementTypeForName[r.Name] + if !ok { + return nil + } + sel := r.Selector + r.Selector = constructor() + + if err := mapstructure.Decode(sel, &r.Selector); err != nil { + return err + } + return nil +} + +func (j capCodec) Name() string { + return "capability" +} \ No newline at end of file diff --git a/pkg/boltdb/model/codec_test.go b/pkg/boltdb/model/codec_test.go new file mode 100644 index 000000000..33611a8aa --- /dev/null +++ b/pkg/boltdb/model/codec_test.go @@ -0,0 +1,47 @@ +package model + +import ( + "fmt" + "math/rand" + "os" + "testing" + "time" + + "github.com/asdine/storm/v3" + "github.com/stretchr/testify/require" +) + +func init() { + rand.Seed(time.Now().UTC().UnixNano()) +} + +func TestInterfaceField(t *testing.T) { + dbName := fmt.Sprintf("test-%d.db", rand.Int()) + defer os.Remove(dbName) + + bdb, err := storm.Open(dbName, storm.Codec(Codec)) + require.NoError(t, err) + defer bdb.Close() + + tx, err := bdb.Begin(true) + require.NoError(t, err) + + api := Api{ + Group: "group", + Version: "v1alpha1", + Kind: "Kind", + Plural: "kinds", + } + capFake := Capability{ + Name: GvkCapability, + Value: &api, + } + o := OperatorBundle{Name: "Test", Capabilities: []Capability{capFake}} + require.NoError(t, tx.Save(&o)) + require.NoError(t, tx.Commit()) + + var out []OperatorBundle + require.NoError(t, bdb.All(&out)) + require.Equal(t, 1, len(out)) + require.EqualValues(t, capFake, out[0].Capabilities[0]) +} diff --git a/pkg/boltdb/model/gvk.go b/pkg/boltdb/model/gvk.go new file mode 100644 index 000000000..ff5306df1 --- /dev/null +++ b/pkg/boltdb/model/gvk.go @@ -0,0 +1,37 @@ +package model + +const GvkCapability = OperatorsNamespace + "gvk" + +func init() { + capabilityTypeForName[GvkCapability] = func() interface{} { return &Api{} } + requirementTypeForName[GvkCapability] = func() interface{} { return &ApiEqualitySelector{} } +} + +type Api struct { + Group string + Version string + Kind string + Plural string +} + +func NewApiCapability(api *Api) Capability { + return Capability{ + Name: GvkCapability, + Value: api, + } +} + +type ApiEqualitySelector struct { + Group string + Version string + Kind string + Plural string +} + +func NewApiEqualityRequirement(api *ApiEqualitySelector) Requirement { + return Requirement{ + Name: GvkCapability, + Selector: api, + Optional: false, + } +} diff --git a/pkg/boltdb/types.go b/pkg/boltdb/model/types.go similarity index 64% rename from pkg/boltdb/types.go rename to pkg/boltdb/model/types.go index 8c57d3f49..ebc6cd894 100644 --- a/pkg/boltdb/types.go +++ b/pkg/boltdb/model/types.go @@ -1,14 +1,6 @@ -package boltdb +package model -import ( - "fmt" - "strings" -) - -const ( - KubeApiNamespace = "io.operators." - GvkCapability = KubeApiNamespace + "gvk" -) +const OperatorsNamespace = "io.operators." type OperatorBundle struct { Name string `storm:"id"` @@ -23,39 +15,15 @@ type OperatorBundle struct { Requirements []Requirement } -type Api struct { - Group string - Version string - Kind string - Plural string -} - -func (a Api) String() string { - return fmt.Sprintf("%s/%s/%s/%s", a.Group, a.Version, a.Kind, a.Plural) -} - -func ApiFromString(s string) (*Api, error) { - split := strings.Split(s, "/") - if len(split) < 4 { - return nil, fmt.Errorf("invalid gvk encoding") - } - return &Api{ - Group: split[0], - Version: split[1], - Kind: split[2], - Plural: split[3], - }, nil -} - type Capability struct { Name string `storm:"id"` - Value string + Value interface{} } type Requirement struct { Optional bool Name string - Selector string + Selector interface{} } type Package struct { diff --git a/pkg/boltdb/query.go b/pkg/boltdb/query.go index 931c6ec9e..9019dd527 100644 --- a/pkg/boltdb/query.go +++ b/pkg/boltdb/query.go @@ -3,10 +3,9 @@ package boltdb import ( "context" "fmt" - "strings" - "github.com/asdine/storm/v3" "github.com/asdine/storm/v3/q" + "github.com/operator-framework/operator-registry/pkg/boltdb/model" "github.com/operator-framework/operator-registry/pkg/api" "github.com/operator-framework/operator-registry/pkg/registry" @@ -31,7 +30,7 @@ func (*StormQuerier) ListTables(ctx context.Context) ([]string, error) { } func (s *StormQuerier) ListPackages(ctx context.Context) ([]string, error) { - var pkgs []Package + var pkgs []model.Package if err := s.db.All(&pkgs); err != nil { return nil, err } @@ -45,12 +44,12 @@ func (s *StormQuerier) ListPackages(ctx context.Context) ([]string, error) { } func (s *StormQuerier) GetPackage(ctx context.Context, name string) (*registry.PackageManifest, error) { - var pkg Package + var pkg model.Package if err := s.db.One("Name", name, &pkg); err != nil { return nil, err } - var channels []Channel + var channels []model.Channel if err := s.db.Find("PackageName", name, &channels); err != nil { return nil, fmt.Errorf("couldn't get channels for package %s: %v", name, err) } @@ -71,7 +70,7 @@ func (s *StormQuerier) GetPackage(ctx context.Context, name string) (*registry.P func (s *StormQuerier) GetBundle(ctx context.Context, pkgName, channelName, csvName string) (*api.Bundle, error) { // We only need the csvName to query for the OperatorBundle, since their names are 1:1 - var opBundle OperatorBundle + var opBundle model.OperatorBundle if err := s.db.One("Name", csvName, &opBundle); err != nil { return nil, fmt.Errorf("couldn't find bundle for %s, %s, %s: %v", pkgName, channelName, csvName, err) } @@ -97,14 +96,14 @@ func (s *StormQuerier) GetBundle(ctx context.Context, pkgName, channelName, csvN // provided apis for _, cap := range opBundle.Capabilities { fmt.Printf("%#v", cap) - gvkp := strings.Split(cap.Value, "/") - if len(gvkp) < 4 { - return nil, fmt.Errorf("malformed gvk storage: %v", gvkp) + + if cap.Name != model.GvkCapability { + continue } - if cap.Name != GvkCapability { + gvk, ok := cap.Value.(*model.Api) + if !ok { continue } - gvk, err := ApiFromString(cap.Value) if err != nil { return nil, err } @@ -118,10 +117,13 @@ func (s *StormQuerier) GetBundle(ctx context.Context, pkgName, channelName, csvN // required apis for _, req := range opBundle.Requirements { - if req.Name != GvkCapability { + if req.Name != model.GvkCapability { + continue + } + gvk, ok := req.Selector.(*model.ApiEqualitySelector) + if !ok { continue } - gvk, err := ApiFromString(req.Selector) if err != nil { return nil, err } @@ -137,7 +139,7 @@ func (s *StormQuerier) GetBundle(ctx context.Context, pkgName, channelName, csvN } func (s *StormQuerier) GetBundleForChannel(ctx context.Context, pkgName string, channelName string) (*api.Bundle, error) { - var channel Channel + var channel model.Channel if err := s.db.Select(q.Eq("PackageName", pkgName), q.Eq("ChannelName", channelName)).First(&channel); err != nil { return nil, fmt.Errorf("couldn't fetch bundle for %s %s: %v", pkgName, channelName, err) } @@ -154,7 +156,7 @@ func (s *StormQuerier) GetChannelEntriesThatReplace(ctx context.Context, name st } func (s *StormQuerier) GetBundleThatReplaces(ctx context.Context, name, pkgName, channelName string) (*api.Bundle, error) { - var entry ChannelEntry + var entry model.ChannelEntry if err := s.db.Select(q.Eq("PackageName", pkgName), q.Eq("ChannelName", channelName), q.Eq("Replaces", name)).First(&entry); err != nil { return nil, err } @@ -169,18 +171,18 @@ type GVKMatcher struct { } func (m GVKMatcher) MatchField(v interface{}) (bool, error) { - caps, ok := v.([]Capability) + caps, ok := v.([]model.Capability) if !ok { return false, fmt.Errorf("not a capability list") } for _, c := range caps { - if c.Name != GvkCapability { + if c.Name != model.GvkCapability { continue } - api, err := ApiFromString(c.Value) - if err != nil { - return false, err + api, ok := c.Value.(*model.Api) + if !ok { + continue } if api.Group == m.Group && api.Kind == m.Kind && api.Version == m.Version { return true, nil @@ -190,7 +192,7 @@ func (m GVKMatcher) MatchField(v interface{}) (bool, error) { } func (s *StormQuerier) GetChannelEntriesThatProvide(ctx context.Context, group, version, kind string) (entries []*registry.ChannelEntry, err error) { - var bundles []OperatorBundle + var bundles []model.OperatorBundle if err := s.db.Select(q.NewFieldMatcher("Capabilities", GVKMatcher{ Group: group, Version: version, @@ -203,7 +205,7 @@ func (s *StormQuerier) GetChannelEntriesThatProvide(ctx context.Context, group, for i, b := range bundles { bundleNames[i] = b.Name } - var ents []ChannelEntry + var ents []model.ChannelEntry if err := s.db.Select(q.In("BundleName", bundleNames)).Find(&ents); err != nil { return nil, err } @@ -222,7 +224,7 @@ func (s *StormQuerier) GetChannelEntriesThatProvide(ctx context.Context, group, // Get latest channel entries that provide an API. func (s *StormQuerier) GetLatestChannelEntriesThatProvide(ctx context.Context, group, version, kind string) (entries []*registry.ChannelEntry, err error) { - var bundles []OperatorBundle + var bundles []model.OperatorBundle if err := s.db.Select(q.NewFieldMatcher("Capabilities", GVKMatcher{ Group: group, Version: version, @@ -235,15 +237,15 @@ func (s *StormQuerier) GetLatestChannelEntriesThatProvide(ctx context.Context, g for i, b := range bundles { bundleNames[i] = b.Name } - var ents []ChannelEntry + var ents []model.ChannelEntry if err := s.db.Select(q.In("BundleName", bundleNames)).Find(&ents); err != nil { return nil, err } - pkgChannelToLatest := map[PackageChannel]*registry.ChannelEntry{} + pkgChannelToLatest := map[model.PackageChannel]*registry.ChannelEntry{} // record which packagechannels we have entries in for _, e := range ents { - pkgChannelToLatest[PackageChannel{ + pkgChannelToLatest[model.PackageChannel{ PackageName: e.PackageName, ChannelName: e.ChannelName, }] = nil @@ -295,7 +297,7 @@ func (s *StormQuerier) GetBundleThatProvides(ctx context.Context, group, version } // We will have 1 entry per package/channel - pkgChannelToLatest := map[PackageChannel]*registry.ChannelEntry{} + pkgChannelToLatest := map[model.PackageChannel]*registry.ChannelEntry{} pkgName := "" // record which packagechannels we have entries in for _, e := range entries { @@ -304,7 +306,7 @@ func (s *StormQuerier) GetBundleThatProvides(ctx context.Context, group, version } else if pkgName != e.PackageName { return nil, fmt.Errorf("more than one entry found that provides %s %s %s", group, version, kind) } - pkgChannelToLatest[PackageChannel{ + pkgChannelToLatest[model.PackageChannel{ PackageName: e.PackageName, ChannelName: e.ChannelName, }] = e @@ -314,7 +316,7 @@ func (s *StormQuerier) GetBundleThatProvides(ctx context.Context, group, version if err != nil { return nil, err } - provider, ok := pkgChannelToLatest[PackageChannel{ + provider, ok := pkgChannelToLatest[model.PackageChannel{ PackageName: pkgName, ChannelName: pkg.GetDefaultChannel(), }] @@ -326,7 +328,7 @@ func (s *StormQuerier) GetBundleThatProvides(ctx context.Context, group, version } func (s *StormQuerier) ListImages(ctx context.Context) ([]string, error) { - var related []RelatedImage + var related []model.RelatedImage if err := s.db.All(&related); err != nil { return nil, err } @@ -345,7 +347,7 @@ func (s *StormQuerier) ListImages(ctx context.Context) ([]string, error) { } func (s *StormQuerier) GetImagesForBundle(ctx context.Context, bundleName string) ([]string, error) { - var related []RelatedImage + var related []model.RelatedImage if err := s.db.Find("OperatorBundleName", bundleName, &related); err != nil { return nil, err }