|
1 | 1 | package variablesources
|
2 | 2 |
|
3 | 3 | import (
|
4 |
| - "context" |
5 | 4 | "fmt"
|
6 | 5 | "sort"
|
7 | 6 |
|
8 | 7 | mmsemver "github.com/Masterminds/semver/v3"
|
9 |
| - "github.com/operator-framework/deppy/pkg/deppy" |
10 |
| - "github.com/operator-framework/deppy/pkg/deppy/input" |
11 | 8 |
|
| 9 | + operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1" |
12 | 10 | "github.com/operator-framework/operator-controller/internal/catalogmetadata"
|
13 | 11 | catalogfilter "github.com/operator-framework/operator-controller/internal/catalogmetadata/filter"
|
14 | 12 | catalogsort "github.com/operator-framework/operator-controller/internal/catalogmetadata/sort"
|
15 | 13 | olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables"
|
16 | 14 | )
|
17 | 15 |
|
18 |
| -var _ input.VariableSource = &RequiredPackageVariableSource{} |
| 16 | +// MakeRequiredPackageVariables returns a variable which represent |
| 17 | +// explicit requirement for a package from an user. |
| 18 | +// This is when an user explicitly asks "install this" via Operator API. |
| 19 | +func MakeRequiredPackageVariables(allBundles []*catalogmetadata.Bundle, operators []operatorsv1alpha1.Operator) ([]*olmvariables.RequiredPackageVariable, error) { |
| 20 | + result := make([]*olmvariables.RequiredPackageVariable, 0, len(operators)) |
19 | 21 |
|
20 |
| -type RequiredPackageVariableSourceOption func(*RequiredPackageVariableSource) error |
| 22 | + for _, operator := range operators { |
| 23 | + packageName := operator.Spec.PackageName |
| 24 | + channelName := operator.Spec.Channel |
| 25 | + versionRange := operator.Spec.Version |
21 | 26 |
|
22 |
| -func InVersionRange(versionRange string) RequiredPackageVariableSourceOption { |
23 |
| - return func(r *RequiredPackageVariableSource) error { |
24 |
| - if versionRange != "" { |
25 |
| - vr, err := mmsemver.NewConstraint(versionRange) |
26 |
| - if err == nil { |
27 |
| - r.versionRange = versionRange |
28 |
| - r.predicates = append(r.predicates, catalogfilter.InMastermindsSemverRange(vr)) |
29 |
| - return nil |
30 |
| - } |
31 |
| - |
32 |
| - return fmt.Errorf("invalid version range '%s': %w", versionRange, err) |
| 27 | + predicates := []catalogfilter.Predicate[catalogmetadata.Bundle]{ |
| 28 | + catalogfilter.WithPackageName(packageName), |
33 | 29 | }
|
34 |
| - return nil |
35 |
| - } |
36 |
| -} |
37 | 30 |
|
38 |
| -func InChannel(channelName string) RequiredPackageVariableSourceOption { |
39 |
| - return func(r *RequiredPackageVariableSource) error { |
40 | 31 | if channelName != "" {
|
41 |
| - r.channelName = channelName |
42 |
| - r.predicates = append(r.predicates, catalogfilter.InChannel(channelName)) |
| 32 | + predicates = append(predicates, catalogfilter.InChannel(channelName)) |
43 | 33 | }
|
44 |
| - return nil |
45 |
| - } |
46 |
| -} |
47 |
| - |
48 |
| -type RequiredPackageVariableSource struct { |
49 |
| - allBundles []*catalogmetadata.Bundle |
50 |
| - |
51 |
| - packageName string |
52 |
| - versionRange string |
53 |
| - channelName string |
54 |
| - predicates []catalogfilter.Predicate[catalogmetadata.Bundle] |
55 |
| -} |
56 | 34 |
|
57 |
| -func NewRequiredPackageVariableSource(allBundles []*catalogmetadata.Bundle, packageName string, options ...RequiredPackageVariableSourceOption) (*RequiredPackageVariableSource, error) { |
58 |
| - if packageName == "" { |
59 |
| - return nil, fmt.Errorf("package name must not be empty") |
60 |
| - } |
61 |
| - r := &RequiredPackageVariableSource{ |
62 |
| - allBundles: allBundles, |
| 35 | + if versionRange != "" { |
| 36 | + vr, err := mmsemver.NewConstraint(versionRange) |
| 37 | + if err != nil { |
| 38 | + return nil, fmt.Errorf("invalid version range %q: %w", versionRange, err) |
| 39 | + } |
| 40 | + predicates = append(predicates, catalogfilter.InMastermindsSemverRange(vr)) |
| 41 | + } |
63 | 42 |
|
64 |
| - packageName: packageName, |
65 |
| - predicates: []catalogfilter.Predicate[catalogmetadata.Bundle]{catalogfilter.WithPackageName(packageName)}, |
66 |
| - } |
67 |
| - for _, option := range options { |
68 |
| - if err := option(r); err != nil { |
69 |
| - return nil, err |
| 43 | + resultSet := catalogfilter.Filter(allBundles, catalogfilter.And(predicates...)) |
| 44 | + if len(resultSet) == 0 { |
| 45 | + if versionRange != "" && channelName != "" { |
| 46 | + return nil, fmt.Errorf("no package %q matching version %q found in channel %q", packageName, versionRange, channelName) |
| 47 | + } |
| 48 | + if versionRange != "" { |
| 49 | + return nil, fmt.Errorf("no package %q matching version %q found", packageName, versionRange) |
| 50 | + } |
| 51 | + if channelName != "" { |
| 52 | + return nil, fmt.Errorf("no package %q found in channel %q", packageName, channelName) |
| 53 | + } |
| 54 | + return nil, fmt.Errorf("no package %q found", packageName) |
70 | 55 | }
|
71 |
| - } |
72 |
| - return r, nil |
73 |
| -} |
| 56 | + sort.SliceStable(resultSet, func(i, j int) bool { |
| 57 | + return catalogsort.ByVersion(resultSet[i], resultSet[j]) |
| 58 | + }) |
74 | 59 |
|
75 |
| -func (r *RequiredPackageVariableSource) GetVariables(_ context.Context) ([]deppy.Variable, error) { |
76 |
| - resultSet := catalogfilter.Filter(r.allBundles, catalogfilter.And(r.predicates...)) |
77 |
| - if len(resultSet) == 0 { |
78 |
| - return nil, r.notFoundError() |
| 60 | + result = append(result, olmvariables.NewRequiredPackageVariable(packageName, resultSet)) |
79 | 61 | }
|
80 |
| - sort.SliceStable(resultSet, func(i, j int) bool { |
81 |
| - return catalogsort.ByVersion(resultSet[i], resultSet[j]) |
82 |
| - }) |
83 |
| - return []deppy.Variable{ |
84 |
| - olmvariables.NewRequiredPackageVariable(r.packageName, resultSet), |
85 |
| - }, nil |
86 |
| -} |
87 | 62 |
|
88 |
| -func (r *RequiredPackageVariableSource) notFoundError() error { |
89 |
| - if r.versionRange != "" && r.channelName != "" { |
90 |
| - return fmt.Errorf("no package '%s' matching version '%s' found in channel '%s'", r.packageName, r.versionRange, r.channelName) |
91 |
| - } |
92 |
| - if r.versionRange != "" { |
93 |
| - return fmt.Errorf("no package '%s' matching version '%s' found", r.packageName, r.versionRange) |
94 |
| - } |
95 |
| - if r.channelName != "" { |
96 |
| - return fmt.Errorf("no package '%s' found in channel '%s'", r.packageName, r.channelName) |
97 |
| - } |
98 |
| - return fmt.Errorf("no package '%s' found", r.packageName) |
| 63 | + return result, nil |
99 | 64 | }
|
0 commit comments