Skip to content

Commit 51bbbe2

Browse files
committed
Extend NFR code with MatchStatus and introduce failFast strategy.
MatchStatus provides details about successful expressions and their results, which are the matched host features. Additionally, a new flag controls rule processing behavior: it can either stop at the first error or continue processing all expressions and rules. Signed-off-by: Marcin Franczyk <[email protected]>
1 parent 0188aad commit 51bbbe2

File tree

9 files changed

+291
-126
lines changed

9 files changed

+291
-126
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha1
18+
19+
import (
20+
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
21+
)
22+
23+
// ArtifactType is a type of OCI artifact that contains image compatibility metadata.
24+
const (
25+
ArtifactType = "application/vnd.nfd.image-compatibility.v1alpha1"
26+
Version = "v1alpha1"
27+
)
28+
29+
// Spec represents image compatibility metadata.
30+
type Spec struct {
31+
// Version of the spec.
32+
Version string `json:"version"`
33+
// Compatibilities contains list of compatibility sets.
34+
Compatibilties []Compatibility `json:"compatibilities"`
35+
}
36+
37+
// Compatibility represents image compatibility metadata
38+
// that describe the image requirements for the host and OS.
39+
type Compatibility struct {
40+
// Rules represents a list of Node Feature Rules.
41+
Rules []nfdv1alpha1.Rule `json:"rules"`
42+
// Weight indicates the priority of the compatibility set.
43+
Weight int `json:"weight,omitempty"`
44+
// Tag enables grouping or distinguishing between compatibility sets.
45+
Tag string `json:"tag,omitempty"`
46+
// Description of the compatibility set.
47+
Description string `json:"description,omitempty"`
48+
}

api/nfd/v1alpha1/types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package v1alpha1
1818

1919
import (
20+
"fmt"
21+
2022
corev1 "k8s.io/api/core/v1"
2123
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2224
)
@@ -298,6 +300,13 @@ type MatchExpression struct {
298300
Value MatchValue `json:"value,omitempty"`
299301
}
300302

303+
func (m MatchExpression) String() string {
304+
if len(m.Value) < 1 {
305+
return fmt.Sprintf("{op: %q}", m.Op)
306+
}
307+
return fmt.Sprintf("{op: %q, value: %q}", m.Op, m.Value)
308+
}
309+
301310
// MatchOp is the match operator that is applied on values when evaluating a
302311
// MatchExpression.
303312
// +kubebuilder:validation:Enum="In";"NotIn";"InRegexp";"Exists";"DoesNotExist";"Gt";"Lt";"GtLt";"IsTrue";"IsFalse"

pkg/apis/nfd/nodefeaturerule/expression-api_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ bar: { op: Exists }
116116
t.Fatal("failed to parse data of test case")
117117
}
118118

119-
res, out, err := api.MatchGetKeys(mes, tc.input)
119+
res, out, _, err := api.MatchGetKeys(mes, tc.input)
120120
tc.result(t, res)
121121
assert.Equal(t, tc.output, out)
122122
tc.err(t, err)
@@ -183,12 +183,12 @@ baz: { op: Gt, value: ["10"] }
183183
t.Fatal("failed to parse data of test case")
184184
}
185185

186-
res, out, err := api.MatchGetValues(mes, tc.input)
186+
res, out, _, err := api.MatchGetValues(mes, tc.input, true)
187187
tc.result(t, res)
188188
assert.Equal(t, tc.output, out)
189189
tc.err(t, err)
190190

191-
res, err = api.MatchValues(mes, tc.input)
191+
res, _, err = api.MatchValues(mes, tc.input, true)
192192
tc.result(t, res)
193193
tc.err(t, err)
194194
})
@@ -248,12 +248,12 @@ bar: { op: Lt, value: ["10"] }
248248
t.Fatal("failed to parse data of test case")
249249
}
250250

251-
res, out, err := api.MatchGetInstances(mes, tc.input)
251+
res, out, _, err := api.MatchGetInstances(mes, tc.input, true)
252252
assert.Equal(t, tc.output, out)
253253
tc.result(t, res)
254254
tc.err(t, err)
255255

256-
res, err = api.MatchInstances(mes, tc.input)
256+
res, err = api.MatchInstances(mes, tc.input, true)
257257
tc.result(t, res)
258258
tc.err(t, err)
259259
})
@@ -745,7 +745,7 @@ func TestMatchMulti(t *testing.T) {
745745

746746
for _, tc := range tcs {
747747
t.Run(tc.name, func(t *testing.T) {
748-
res, out, err := api.MatchMulti(tc.mes, tc.inputKeys, tc.inputValues, tc.inputInstances)
748+
res, out, _, err := api.MatchMulti(tc.mes, tc.inputKeys, tc.inputValues, tc.inputInstances, true)
749749
if tc.expectErr {
750750
assert.NotNil(t, err)
751751
} else {

0 commit comments

Comments
 (0)