|
8 | 8 | catalogd "github.com/operator-framework/catalogd/api/core/v1alpha1"
|
9 | 9 | "github.com/operator-framework/deppy/pkg/deppy"
|
10 | 10 | "github.com/operator-framework/deppy/pkg/deppy/input"
|
| 11 | + "github.com/operator-framework/operator-registry/alpha/declcfg" |
11 | 12 | "github.com/operator-framework/operator-registry/alpha/property"
|
12 | 13 | "sigs.k8s.io/controller-runtime/pkg/client"
|
13 | 14 |
|
@@ -71,70 +72,119 @@ func (es *CatalogdEntitySource) Iterate(ctx context.Context, fn input.IteratorFu
|
71 | 72 | return nil
|
72 | 73 | }
|
73 | 74 |
|
74 |
| -func getEntities(ctx context.Context, client client.Client) (input.EntityList, error) { |
75 |
| - entityList := input.EntityList{} |
76 |
| - bundleMetadatas, packageMetdatas, err := fetchMetadata(ctx, client) |
77 |
| - if err != nil { |
| 75 | +func getEntities(ctx context.Context, cl client.Client) (input.EntityList, error) { |
| 76 | + allEntitiesList := input.EntityList{} |
| 77 | + |
| 78 | + var catalogList catalogd.CatalogList |
| 79 | + if err := cl.List(ctx, &catalogList); err != nil { |
78 | 80 | return nil, err
|
79 | 81 | }
|
80 |
| - for _, bundle := range bundleMetadatas.Items { |
81 |
| - props := map[string]string{} |
82 |
| - |
83 |
| - // TODO: We should make sure all properties are forwarded |
84 |
| - // through and avoid a lossy translation from FBC --> entity |
85 |
| - for _, prop := range bundle.Spec.Properties { |
86 |
| - switch prop.Type { |
87 |
| - case property.TypePackage: |
88 |
| - // this is already a json marshalled object, so it doesn't need to be marshalled |
89 |
| - // like the other ones |
90 |
| - props[property.TypePackage] = string(prop.Value) |
91 |
| - case entities.PropertyBundleMediaType: |
92 |
| - props[entities.PropertyBundleMediaType] = string(prop.Value) |
93 |
| - } |
| 82 | + for _, catalog := range catalogList.Items { |
| 83 | + channels, bundles, err := fetchCatalogMetadata(ctx, cl, catalog.Name) |
| 84 | + if err != nil { |
| 85 | + return nil, err |
94 | 86 | }
|
95 | 87 |
|
96 |
| - imgValue, err := json.Marshal(bundle.Spec.Image) |
| 88 | + catalogEntitiesList, err := MetadataToEntities(catalog.Name, channels, bundles) |
97 | 89 | if err != nil {
|
98 | 90 | return nil, err
|
99 | 91 | }
|
100 |
| - props[entities.PropertyBundlePath] = string(imgValue) |
101 |
| - catalogScopedPkgName := fmt.Sprintf("%s-%s", bundle.Spec.Catalog.Name, bundle.Spec.Package) |
102 |
| - bundlePkg := packageMetdatas[catalogScopedPkgName] |
103 |
| - for _, ch := range bundlePkg.Spec.Channels { |
104 |
| - for _, b := range ch.Entries { |
105 |
| - catalogScopedEntryName := fmt.Sprintf("%s-%s", bundle.Spec.Catalog.Name, b.Name) |
106 |
| - if catalogScopedEntryName == bundle.Name { |
107 |
| - channelValue, _ := json.Marshal(property.Channel{ChannelName: ch.Name, Priority: 0}) |
108 |
| - props[property.TypeChannel] = string(channelValue) |
109 |
| - replacesValue, _ := json.Marshal(entities.ChannelEntry{ |
110 |
| - Name: b.Name, |
111 |
| - Replaces: b.Replaces, |
112 |
| - }) |
113 |
| - props[entities.PropertyBundleChannelEntry] = string(replacesValue) |
114 |
| - entity := input.Entity{ |
115 |
| - ID: deppy.IdentifierFromString(fmt.Sprintf("%s%s%s", bundle.Name, bundle.Spec.Package, ch.Name)), |
116 |
| - Properties: props, |
117 |
| - } |
118 |
| - entityList = append(entityList, entity) |
| 92 | + |
| 93 | + allEntitiesList = append(allEntitiesList, catalogEntitiesList...) |
| 94 | + } |
| 95 | + |
| 96 | + return allEntitiesList, nil |
| 97 | +} |
| 98 | + |
| 99 | +func MetadataToEntities(catalogName string, channels []declcfg.Channel, bundles []declcfg.Bundle) (input.EntityList, error) { |
| 100 | + entityList := input.EntityList{} |
| 101 | + |
| 102 | + bundlesMap := map[string]*declcfg.Bundle{} |
| 103 | + for i := range bundles { |
| 104 | + bundleKey := fmt.Sprintf("%s-%s", bundles[i].Package, bundles[i].Name) |
| 105 | + bundlesMap[bundleKey] = &bundles[i] |
| 106 | + } |
| 107 | + |
| 108 | + for _, ch := range channels { |
| 109 | + for _, chEntry := range ch.Entries { |
| 110 | + bundleKey := fmt.Sprintf("%s-%s", ch.Package, chEntry.Name) |
| 111 | + bundle, ok := bundlesMap[bundleKey] |
| 112 | + if !ok { |
| 113 | + return nil, fmt.Errorf("bundle %q not found in catalog %q (package %q, channel %q)", chEntry.Name, catalogName, ch.Package, ch.Name) |
| 114 | + } |
| 115 | + |
| 116 | + props := map[string]string{} |
| 117 | + |
| 118 | + for _, prop := range bundle.Properties { |
| 119 | + switch prop.Type { |
| 120 | + case property.TypePackage: |
| 121 | + // this is already a json marshalled object, so it doesn't need to be marshalled |
| 122 | + // like the other ones |
| 123 | + props[property.TypePackage] = string(prop.Value) |
| 124 | + case entities.PropertyBundleMediaType: |
| 125 | + props[entities.PropertyBundleMediaType] = string(prop.Value) |
119 | 126 | }
|
120 | 127 | }
|
| 128 | + |
| 129 | + imgValue, err := json.Marshal(bundle.Image) |
| 130 | + if err != nil { |
| 131 | + return nil, err |
| 132 | + } |
| 133 | + props[entities.PropertyBundlePath] = string(imgValue) |
| 134 | + |
| 135 | + channelValue, _ := json.Marshal(property.Channel{ChannelName: ch.Name, Priority: 0}) |
| 136 | + props[property.TypeChannel] = string(channelValue) |
| 137 | + replacesValue, _ := json.Marshal(entities.ChannelEntry{ |
| 138 | + Name: bundle.Name, |
| 139 | + Replaces: chEntry.Replaces, |
| 140 | + }) |
| 141 | + props[entities.PropertyBundleChannelEntry] = string(replacesValue) |
| 142 | + |
| 143 | + catalogScopedEntryName := fmt.Sprintf("%s-%s", catalogName, bundle.Name) |
| 144 | + entity := input.Entity{ |
| 145 | + ID: deppy.IdentifierFromString(fmt.Sprintf("%s%s%s", catalogScopedEntryName, bundle.Package, ch.Name)), |
| 146 | + Properties: props, |
| 147 | + } |
| 148 | + entityList = append(entityList, entity) |
121 | 149 | }
|
122 | 150 | }
|
| 151 | + |
123 | 152 | return entityList, nil
|
124 | 153 | }
|
125 | 154 |
|
126 |
| -func fetchMetadata(ctx context.Context, client client.Client) (catalogd.BundleMetadataList, map[string]catalogd.Package, error) { |
127 |
| - packageMetdatas := catalogd.PackageList{} |
128 |
| - if err := client.List(ctx, &packageMetdatas); err != nil { |
129 |
| - return catalogd.BundleMetadataList{}, nil, err |
| 155 | +func fetchCatalogMetadata(ctx context.Context, cl client.Client, catalogName string) ([]declcfg.Channel, []declcfg.Bundle, error) { |
| 156 | + channels, err := fetchCatalogMetadataByScheme[declcfg.Channel](ctx, cl, declcfg.SchemaChannel, catalogName) |
| 157 | + if err != nil { |
| 158 | + return nil, nil, err |
| 159 | + } |
| 160 | + bundles, err := fetchCatalogMetadataByScheme[declcfg.Bundle](ctx, cl, declcfg.SchemaBundle, catalogName) |
| 161 | + if err != nil { |
| 162 | + return nil, nil, err |
130 | 163 | }
|
131 |
| - bundleMetadatas := catalogd.BundleMetadataList{} |
132 |
| - if err := client.List(ctx, &bundleMetadatas); err != nil { |
133 |
| - return catalogd.BundleMetadataList{}, nil, err |
| 164 | + |
| 165 | + return channels, bundles, nil |
| 166 | +} |
| 167 | + |
| 168 | +type declcfgSchema interface { |
| 169 | + declcfg.Package | declcfg.Bundle | declcfg.Channel |
| 170 | +} |
| 171 | + |
| 172 | +// TODO: Cleanup once https://github.com/golang/go/issues/45380 implemented |
| 173 | +// We should be able to get rid of the schema arg and switch based on the type passed to this generic |
| 174 | +func fetchCatalogMetadataByScheme[T declcfgSchema](ctx context.Context, cl client.Client, schema, catalogName string) ([]T, error) { |
| 175 | + cmList := catalogd.CatalogMetadataList{} |
| 176 | + if err := cl.List(ctx, &cmList, client.MatchingLabels{"schema": schema, "catalog": catalogName}); err != nil { |
| 177 | + return nil, err |
134 | 178 | }
|
135 |
| - packages := map[string]catalogd.Package{} |
136 |
| - for _, pkg := range packageMetdatas.Items { |
137 |
| - packages[pkg.Name] = pkg |
| 179 | + |
| 180 | + contents := []T{} |
| 181 | + for _, cm := range cmList.Items { |
| 182 | + var content T |
| 183 | + if err := json.Unmarshal(cm.Spec.Content, &content); err != nil { |
| 184 | + return nil, err |
| 185 | + } |
| 186 | + contents = append(contents, content) |
138 | 187 | }
|
139 |
| - return bundleMetadatas, packages, nil |
| 188 | + |
| 189 | + return contents, nil |
140 | 190 | }
|
0 commit comments