Skip to content

Commit

Permalink
poc for schema import (#1151)
Browse files Browse the repository at this point in the history
Signed-off-by: Jordan Keister <[email protected]>
  • Loading branch information
grokspawn authored Nov 6, 2023
1 parent 5d951b8 commit f2285a2
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 59 deletions.
5 changes: 1 addition & 4 deletions alpha/action/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,10 +450,7 @@ BundleLoop:
func combineConfigs(cfgs []declcfg.DeclarativeConfig) *declcfg.DeclarativeConfig {
out := &declcfg.DeclarativeConfig{}
for _, in := range cfgs {
out.Packages = append(out.Packages, in.Packages...)
out.Channels = append(out.Channels, in.Channels...)
out.Bundles = append(out.Bundles, in.Bundles...)
out.Others = append(out.Others, in.Others...)
out.Merge(&in)
}
return out
}
37 changes: 30 additions & 7 deletions alpha/declcfg/declcfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ import (
)

const (
SchemaPackage = "olm.package"
SchemaChannel = "olm.channel"
SchemaBundle = "olm.bundle"
SchemaPackage = "olm.package"
SchemaChannel = "olm.channel"
SchemaBundle = "olm.bundle"
SchemaDeprecation = "olm.catalog.deprecation"
)

type DeclarativeConfig struct {
Packages []Package
Channels []Channel
Bundles []Bundle
Others []Meta
Packages []Package
Channels []Channel
Bundles []Bundle
Deprecations []Deprecation
Others []Meta
}

type Package struct {
Expand Down Expand Up @@ -90,6 +92,19 @@ type RelatedImage struct {
Image string `json:"image"`
}

type Deprecation struct {
Schema string `json:"schema"`
Package string `json:"package"`
Name string `json:"name,omitempty"`
Deprecations []DeprecationEntry `json:"deprecations"`
}

type DeprecationEntry struct {
Schema string `json:"schema"`
Name string `json:"name,omitempty"`
Message json.RawMessage `json:"message"`
}

type Meta struct {
Schema string
Package string
Expand Down Expand Up @@ -181,3 +196,11 @@ func extractUniqueMetaKeys(blobMap map[string]any, m *Meta) error {
}
return nil
}

func (destination *DeclarativeConfig) Merge(src *DeclarativeConfig) {
destination.Packages = append(destination.Packages, src.Packages...)
destination.Channels = append(destination.Channels, src.Channels...)
destination.Bundles = append(destination.Bundles, src.Bundles...)
destination.Others = append(destination.Others, src.Others...)
destination.Deprecations = append(destination.Deprecations, src.Deprecations...)
}
12 changes: 7 additions & 5 deletions alpha/declcfg/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,8 @@ func mergeCfgs(ctx context.Context, cfgChan <-chan *DeclarativeConfig, fcfg *Dec
if !ok {
return nil
}
fcfg.Packages = append(fcfg.Packages, cfg.Packages...)
fcfg.Channels = append(fcfg.Channels, cfg.Channels...)
fcfg.Bundles = append(fcfg.Bundles, cfg.Bundles...)
fcfg.Others = append(fcfg.Others, cfg.Others...)
fcfg.Merge(cfg)
}

}
}

Expand Down Expand Up @@ -297,6 +293,12 @@ func LoadReader(r io.Reader) (*DeclarativeConfig, error) {
return fmt.Errorf("parse bundle: %v", err)
}
cfg.Bundles = append(cfg.Bundles, b)
case SchemaDeprecation:
var d Deprecation
if err := json.Unmarshal(in.Blob, &d); err != nil {
return fmt.Errorf("parse deprecation: %w", err)
}
cfg.Deprecations = append(cfg.Deprecations, d)
case "":
return fmt.Errorf("object '%s' is missing root schema field", string(in.Blob))
default:
Expand Down
128 changes: 89 additions & 39 deletions alpha/declcfg/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,14 @@ func TestLoadReader(t *testing.T) {

func TestWalkMetasFS(t *testing.T) {
type spec struct {
name string
fsys fs.FS
assertion require.ErrorAssertionFunc
expectNumPackages int
expectNumChannels int
expectNumBundles int
expectNumOthers int
name string
fsys fs.FS
assertion require.ErrorAssertionFunc
expectNumPackages int
expectNumChannels int
expectNumBundles int
expectNumDeprecations int
expectNumOthers int
}
specs := []spec{
{
Expand All @@ -122,19 +123,20 @@ func TestWalkMetasFS(t *testing.T) {
assertion: require.Error,
},
{
name: "Success/ValidDir",
fsys: validFS,
assertion: require.NoError,
expectNumPackages: 3,
expectNumChannels: 0,
expectNumBundles: 12,
expectNumOthers: 1,
name: "Success/ValidDir",
fsys: validFS,
assertion: require.NoError,
expectNumPackages: 3,
expectNumChannels: 0,
expectNumBundles: 12,
expectNumDeprecations: 1,
expectNumOthers: 1,
},
}

for _, s := range specs {
t.Run(s.name, func(t *testing.T) {
numPackages, numChannels, numBundles, numOthers := 0, 0, 0, 0
numPackages, numChannels, numBundles, numDeprecations, numOthers := 0, 0, 0, 0, 0
err := WalkMetasFS(s.fsys, func(path string, meta *Meta, err error) error {
if err != nil {
return err
Expand All @@ -146,6 +148,8 @@ func TestWalkMetasFS(t *testing.T) {
numChannels++
case SchemaBundle:
numBundles++
case SchemaDeprecation:
numDeprecations++
default:
numOthers++
}
Expand Down Expand Up @@ -332,6 +336,18 @@ func TestLoadFS(t *testing.T) {
Schema: "olm.bundle",
},
},
Deprecations: []Deprecation{
{
Schema: "olm.catalog.deprecation",
Package: "kiali",
Name: "bobs-discount-name",
Deprecations: []DeprecationEntry{
{Schema: "olm.bundle", Name: "kiali-operator.v1.68.0", Message: json.RawMessage(`"kiali-operator.v1.68.0 is deprecated. Uninstall and install kiali-operator.v1.72.0 for support.\n"`)},
{Schema: "olm.package", Name: "kiali", Message: json.RawMessage(`"package kiali is end of life. Please use 'kiali-new' package for support.\n"`)},
{Schema: "olm.channel", Name: "alpha", Message: json.RawMessage(`"channel alpha is no longer supported. Please switch to channel 'stable'.\n"`)},
},
},
},
Others: []Meta{
{Schema: "unexpected", Package: "", Blob: json.RawMessage(`{ "schema": "unexpected" }`)},
},
Expand Down Expand Up @@ -881,6 +897,25 @@ present in the .indexignore file.`),
unrecognizedSchema = &fstest.MapFile{
Data: []byte(`{"schema":"olm.package"}{"schema":"unexpected"}{"schema":"olm.bundle"}`),
}
deprecations = &fstest.MapFile{
Data: []byte(`---
schema: olm.catalog.deprecation
package: kiali
name: bobs-discount-name
deprecations:
- schema: olm.bundle
name: kiali-operator.v1.68.0
message: |
kiali-operator.v1.68.0 is deprecated. Uninstall and install kiali-operator.v1.72.0 for support.
- schema: olm.package
name: kiali
message: |
package kiali is end of life. Please use 'kiali-new' package for support.
- schema: olm.channel
name: alpha
message: |
channel alpha is no longer supported. Please switch to channel 'stable'.`),
}

validFS = fstest.MapFS{
".indexignore": indexIgnore,
Expand All @@ -889,18 +924,19 @@ present in the .indexignore file.`),
"etcdoperator.v0.6.1.clusterserviceversion.yaml": etcdCSV,
"README.md": readme,
"unrecognized-schema.json": unrecognizedSchema,
"deprecations.yaml": deprecations,
}
)

type EvaluationFunc func(*testing.T, *DeclarativeConfig)

func TestLoadFile(t *testing.T) {
type spec struct {
name string
fsys fs.FS
path string
assertion require.ErrorAssertionFunc
expectNumPackages int
expectNumBundles int
expectNumOthers int
name string
fsys fs.FS
path string
assertion require.ErrorAssertionFunc
expect EvaluationFunc
}
specs := []spec{
{
Expand Down Expand Up @@ -944,22 +980,38 @@ func TestLoadFile(t *testing.T) {
assertion: require.Error,
},
{
name: "Success/UnrecognizedSchema",
fsys: validFS,
path: "unrecognized-schema.json",
assertion: require.NoError,
expectNumPackages: 1,
expectNumBundles: 1,
expectNumOthers: 1,
name: "Success/UnrecognizedSchema",
fsys: validFS,
path: "unrecognized-schema.json",
assertion: require.NoError,
expect: func(t *testing.T, d *DeclarativeConfig) {
require.Equal(t, 1, len(d.Packages))
require.Equal(t, 1, len(d.Bundles))
require.Equal(t, 1, len(d.Others))
},
},
{
name: "Success/ValidFile",
fsys: validFS,
path: "etcd.yaml",
assertion: require.NoError,
expectNumPackages: 1,
expectNumBundles: 6,
expectNumOthers: 0,
name: "Success/ValidFile",
fsys: validFS,
path: "etcd.yaml",
assertion: require.NoError,
expect: func(t *testing.T, d *DeclarativeConfig) {
require.Equal(t, 1, len(d.Packages))
require.Equal(t, 6, len(d.Bundles))
require.Equal(t, 0, len(d.Others))
},
},
{
name: "Success/ValidFile/Deprecations",
fsys: validFS,
path: "deprecations.yaml",
assertion: require.NoError,
expect: func(t *testing.T, d *DeclarativeConfig) {
require.Equal(t, 0, len(d.Packages))
require.Equal(t, 0, len(d.Bundles))
require.Equal(t, 0, len(d.Others))
require.Equal(t, 1, len(d.Deprecations))
},
},
}

Expand All @@ -969,9 +1021,7 @@ func TestLoadFile(t *testing.T) {
s.assertion(t, err)
if err == nil {
require.NotNil(t, cfg)
assert.Equal(t, len(cfg.Packages), s.expectNumPackages, "unexpected package count")
assert.Equal(t, len(cfg.Bundles), s.expectNumBundles, "unexpected bundle count")
assert.Equal(t, len(cfg.Others), s.expectNumOthers, "unexpected others count")
s.expect(t, cfg)
}
})
}
Expand Down
17 changes: 17 additions & 0 deletions alpha/declcfg/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,12 @@ func writeToEncoder(cfg DeclarativeConfig, enc encoder) error {
pkgNames.Insert(pkgName)
othersByPackage[pkgName] = append(othersByPackage[pkgName], o)
}
deprecationsByPackage := map[string][]Deprecation{}
for _, d := range cfg.Deprecations {
pkgName := d.Package
pkgNames.Insert(pkgName)
deprecationsByPackage[pkgName] = append(deprecationsByPackage[pkgName], d)
}

for _, pName := range pkgNames.List() {
if len(pName) == 0 {
Expand Down Expand Up @@ -418,13 +424,24 @@ func writeToEncoder(cfg DeclarativeConfig, enc encoder) error {
return err
}
}

deprecations := deprecationsByPackage[pName]
sort.SliceStable(deprecations, func(i, j int) bool {
return deprecations[i].Name < deprecations[j].Name
})
for _, d := range deprecations {
if err := enc.Encode(d); err != nil {
return err
}
}
}

for _, o := range othersByPackage[""] {
if err := enc.Encode(o); err != nil {
return err
}
}

return nil
}

Expand Down
5 changes: 1 addition & 4 deletions alpha/template/semver/semver.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,10 +387,7 @@ func newChannel(pkgName string, chName string) *declcfg.Channel {
func combineConfigs(cfgs []declcfg.DeclarativeConfig) *declcfg.DeclarativeConfig {
out := &declcfg.DeclarativeConfig{}
for _, in := range cfgs {
out.Packages = append(out.Packages, in.Packages...)
out.Channels = append(out.Channels, in.Channels...)
out.Bundles = append(out.Bundles, in.Bundles...)
out.Others = append(out.Others, in.Others...)
out.Merge(&in)
}
return out
}
Expand Down

0 comments on commit f2285a2

Please sign in to comment.