Skip to content

Commit bc7e94b

Browse files
committed
OPRUN-3033: Update Version regex to support ranges
Fixes #345 Add positive and negative test cases. Signed-off-by: Todd Short <[email protected]>
1 parent 2114da6 commit bc7e94b

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

api/v1alpha1/operator_types.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type OperatorSpec struct {
2929
PackageName string `json:"packageName"`
3030

3131
//+kubebuilder:validation:MaxLength:=64
32-
//+kubebuilder:validation:Pattern=^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$
32+
//+kubebuilder:validation:Pattern=`^(\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|[x|X|\*])(\.(0|[1-9]\d*|x|X|\*]))?(\.(0|[1-9]\d*|x|X|\*))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)((?:\s+|,\s*|\s*\|\|\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|x|X|\*])(\.(0|[1-9]\d*|x|X|\*))?(\.(0|[1-9]\d*|x|X|\*]))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)*$`
3333
//+kubebuilder:Optional
3434
// Version is an optional semver constraint on the package version. If not specified, the latest version available of the package will be installed.
3535
// If specified, the specific version of the package will be installed so long as it is available in any of the content sources available.

config/crd/bases/operators.operatorframework.io_operators.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ spec:
5151
sources available. Examples: 1.2.3, 1.0.0-alpha, 1.0.0-rc.1 \n For
5252
more information on semver, please see https://semver.org/"
5353
maxLength: 64
54-
pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$
54+
pattern: ^(\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|[x|X|\*])(\.(0|[1-9]\d*|x|X|\*]))?(\.(0|[1-9]\d*|x|X|\*))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)((?:\s+|,\s*|\s*\|\|\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|x|X|\*])(\.(0|[1-9]\d*|x|X|\*))?(\.(0|[1-9]\d*|x|X|\*]))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)*$
5555
type: string
5656
required:
5757
- packageName

internal/controllers/admission_test.go

+53-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ var _ = Describe("Operator Spec Validations", func() {
6161
"1.2.3-pre+bad_metadata",
6262
"1.2.-3",
6363
".1.2.3",
64+
"<<1.2.3",
65+
">>1.2.3",
66+
">~1.2.3",
67+
"==1.2.3",
68+
"=!1.2.3",
69+
"1.Y",
70+
">1.2.3 && <2.3.4",
71+
">1.2.3;<2.3.4",
6472
}
6573
for _, invalidSemver := range invalidSemvers {
6674
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
@@ -69,7 +77,51 @@ var _ = Describe("Operator Spec Validations", func() {
6977
}))
7078

7179
Expect(err).To(HaveOccurred(), "expected error for invalid semver %q", invalidSemver)
72-
Expect(err.Error()).To(ContainSubstring("spec.version in body should match '^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-(0|[1-9]\\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*))?$'"))
80+
Expect(err.Error()).To(ContainSubstring("spec.version in body should match '^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|[x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*]))?(\\.(0|[1-9]\\d*|x|X|\\*))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)((?:\\s+|,\\s*|\\s*\\|\\|\\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*))?(\\.(0|[1-9]\\d*|x|X|\\*]))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)*$'"))
81+
}
82+
})
83+
It("should pass if a valid semver range given", func() {
84+
validSemvers := []string{
85+
">=1.2.3",
86+
"=>1.2.3",
87+
">= 1.2.3",
88+
">=v1.2.3",
89+
">= v1.2.3",
90+
"<=1.2.3",
91+
"=<1.2.3",
92+
"=1.2.3",
93+
"!=1.2.3",
94+
"<1.2.3",
95+
">1.2.3",
96+
"~1.2.2",
97+
"~>1.2.3",
98+
"^1.2.3",
99+
"1.2.3",
100+
"v1.2.3",
101+
"1.x",
102+
"1.X",
103+
"1.*",
104+
"1.2.x",
105+
"1.2.X",
106+
"1.2.*",
107+
">=1.2.3 <2.3.4",
108+
">=1.2.3,<2.3.4",
109+
">=1.2.3, <2.3.4",
110+
"<1.2.3||>2.3.4",
111+
"<1.2.3|| >2.3.4",
112+
"<1.2.3 ||>2.3.4",
113+
"<1.2.3 || >2.3.4",
114+
"<1.2.3-abc >2.3.4-def",
115+
}
116+
for _, validSemver := range validSemvers {
117+
op := operator(operatorsv1alpha1.OperatorSpec{
118+
PackageName: "package",
119+
Version: validSemver,
120+
})
121+
err := cl.Create(ctx, op)
122+
Expect(err).NotTo(HaveOccurred(), "expected success for semver range '%q': %w", validSemver, err)
123+
err = cl.Delete(ctx, op)
124+
Expect(err).NotTo(HaveOccurred(), "unexpected error deleting valid semver '%q': %w", validSemver, err)
73125
}
74126
})
75127
It("should fail if an invalid channel name is given", func() {

0 commit comments

Comments
 (0)