|
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