@@ -18,6 +18,7 @@ package nodevalidator
18
18
19
19
import (
20
20
"context"
21
+ "fmt"
21
22
"slices"
22
23
"sort"
23
24
@@ -62,12 +63,12 @@ func New(opts ...NodeValidatorOpts) nodeValidator {
62
63
func (nv * nodeValidator ) Execute (ctx context.Context ) ([]* CompatibilityStatus , error ) {
63
64
spec , err := nv .artifactClient .FetchCompatibilitySpec (ctx )
64
65
if err != nil {
65
- return nil , err
66
+ return nil , fmt . Errorf ( "failed to fetch compatibility spec: %w" , err )
66
67
}
67
68
68
69
for _ , s := range nv .sources {
69
70
if err := s .Discover (); err != nil {
70
- return nil , err
71
+ return nil , fmt . Errorf ( "error during discovery of source %s: %w" , s . Name (), err )
71
72
}
72
73
}
73
74
features := source .GetAllFeatures ()
@@ -84,7 +85,7 @@ func (nv *nodeValidator) Execute(ctx context.Context) ([]*CompatibilityStatus, e
84
85
if err != nil {
85
86
return nil , err
86
87
}
87
- compat .Rules = append (compat .Rules , evaluateRuleStatus (& r , ruleOut .MatchStatus ))
88
+ compat .Rules = append (compat .Rules , nv . evaluateRuleStatus (& r , ruleOut .MatchStatus ))
88
89
89
90
// Add the 'rule.matched' feature for backreference functionality
90
91
features .InsertAttributeFeatures (nfdv1alpha1 .RuleBackrefDomain , nfdv1alpha1 .RuleBackrefFeature , ruleOut .Labels )
@@ -96,91 +97,100 @@ func (nv *nodeValidator) Execute(ctx context.Context) ([]*CompatibilityStatus, e
96
97
return compats , nil
97
98
}
98
99
99
- func evaluateRuleStatus (rule * nfdv1alpha1.Rule , matchStatus * nodefeaturerule.MatchStatus ) ProcessedRuleStatus {
100
- var matchedFeatureTerms nfdv1alpha1.FeatureMatcher
100
+ func (nv * nodeValidator ) evaluateRuleStatus (rule * nfdv1alpha1.Rule , matchStatus * nodefeaturerule.MatchStatus ) ProcessedRuleStatus {
101
101
out := ProcessedRuleStatus {Name : rule .Name , IsMatch : matchStatus .IsMatch }
102
102
103
- evaluateFeatureMatcher := func (featureMatcher , matchedFeatureTerms nfdv1alpha1.FeatureMatcher ) []MatchedExpression {
104
- out := []MatchedExpression {}
105
- for _ , term := range featureMatcher {
106
- if term .MatchExpressions != nil {
107
- for name , exp := range * term .MatchExpressions {
108
- isMatch := false
109
-
110
- // Check if the expression matches
111
- for _ , processedTerm := range matchedFeatureTerms {
112
- if term .Feature != processedTerm .Feature || processedTerm .MatchExpressions == nil {
113
- continue
114
- }
115
- pexp , ok := (* processedTerm .MatchExpressions )[name ]
116
- if isMatch = ok && exp .Op == pexp .Op && slices .Equal (exp .Value , pexp .Value ); isMatch {
117
- break
118
- }
119
- }
120
-
121
- out = append (out , MatchedExpression {
122
- Feature : term .Feature ,
123
- Name : name ,
124
- Expression : exp ,
125
- MatcherType : MatchExpressionType ,
126
- IsMatch : isMatch ,
127
- })
128
- }
129
- }
103
+ matchedFeatureTerms := nfdv1alpha1.FeatureMatcher {}
104
+ if m := matchStatus .MatchFeatureStatus ; m != nil {
105
+ matchedFeatureTerms = m .MatchedFeaturesTerms
106
+ }
107
+ out .MatchedExpressions = nv .matchFeatureExpressions (rule .MatchFeatures , matchedFeatureTerms )
130
108
131
- if term .MatchName != nil {
132
- isMatch := false
133
- for _ , processedTerm := range matchStatus .MatchedFeaturesTerms {
134
- if term .Feature != processedTerm .Feature || processedTerm .MatchName == nil {
135
- continue
136
- }
137
- isMatch = term .MatchName .Op == processedTerm .MatchName .Op && slices .Equal (term .MatchName .Value , processedTerm .MatchName .Value )
138
- if isMatch {
139
- break
140
- }
141
- }
142
- out = append (out , MatchedExpression {
143
- Feature : term .Feature ,
144
- Name : "" ,
145
- Expression : term .MatchName ,
146
- MatcherType : MatchNameType ,
147
- IsMatch : isMatch ,
148
- })
149
- }
109
+ for i , matchAnyElem := range rule .MatchAny {
110
+ matchedFeatureTermsAny := nfdv1alpha1.FeatureMatcher {}
111
+ if t := matchStatus .MatchAny [i ].MatchedFeaturesTerms ; t != nil {
112
+ matchedFeatureTermsAny = t
150
113
}
114
+ matchedExpressions := nv .matchFeatureExpressions (matchAnyElem .MatchFeatures , matchedFeatureTermsAny )
115
+ out .MatchedAny = append (out .MatchedAny , MatchAnyElem {MatchedExpressions : matchedExpressions })
116
+ }
151
117
152
- // For reproducible output sort by name, feature, expression.
153
- sort .Slice (out , func (i , j int ) bool {
154
- if out [i ].Feature != out [j ].Feature {
155
- return out [i ].Feature < out [j ].Feature
156
- }
157
- if out [i ].Name != out [j ].Name {
158
- return out [i ].Name < out [j ].Name
159
- }
160
- return out [i ].Expression .String () < out [j ].Expression .String ()
161
- })
118
+ return out
119
+ }
162
120
163
- return out
164
- }
121
+ func ( nv * nodeValidator ) matchFeatureExpressions ( featureMatcher , matchedFeatureTerms nfdv1alpha1. FeatureMatcher ) [] MatchedExpression {
122
+ var out [] MatchedExpression
165
123
166
- if matchFeatures := rule .MatchFeatures ; matchFeatures != nil {
167
- if matchStatus .MatchFeatureStatus != nil {
168
- matchedFeatureTerms = matchStatus .MatchFeatureStatus .MatchedFeaturesTerms
124
+ for _ , term := range featureMatcher {
125
+ if term .MatchExpressions != nil {
126
+ out = append (out , nv .matchExpressions (term , matchedFeatureTerms )... )
127
+ }
128
+ if term .MatchName != nil {
129
+ out = append (out , nv .matchName (term , matchedFeatureTerms ))
169
130
}
170
- out .MatchedExpressions = evaluateFeatureMatcher (matchFeatures , matchedFeatureTerms )
171
131
}
172
132
173
- for i , matchAnyElem := range rule .MatchAny {
174
- if matchStatus .MatchAny [i ].MatchedFeaturesTerms != nil {
175
- matchedFeatureTerms = matchStatus .MatchAny [i ].MatchedFeaturesTerms
133
+ // For reproducible output sort by name, feature, expression.
134
+ sort .Slice (out , func (i , j int ) bool {
135
+ if out [i ].Feature != out [j ].Feature {
136
+ return out [i ].Feature < out [j ].Feature
176
137
}
177
- matchedExpressions := evaluateFeatureMatcher (matchAnyElem .MatchFeatures , matchedFeatureTerms )
178
- out .MatchedAny = append (out .MatchedAny , MatchAnyElem {MatchedExpressions : matchedExpressions })
138
+ if out [i ].Name != out [j ].Name {
139
+ return out [i ].Name < out [j ].Name
140
+ }
141
+ return out [i ].Expression .String () < out [j ].Expression .String ()
142
+ })
143
+
144
+ return out
145
+ }
146
+
147
+ func (nodeValidator ) matchExpressions (term nfdv1alpha1.FeatureMatcherTerm , matchedFeatureTerms nfdv1alpha1.FeatureMatcher ) []MatchedExpression {
148
+ var out []MatchedExpression
149
+
150
+ for name , exp := range * term .MatchExpressions {
151
+ isMatch := false
152
+ for _ , processedTerm := range matchedFeatureTerms {
153
+ if term .Feature != processedTerm .Feature || processedTerm .MatchExpressions == nil {
154
+ continue
155
+ }
156
+ pexp , ok := (* processedTerm .MatchExpressions )[name ]
157
+ if isMatch = ok && exp .Op == pexp .Op && slices .Equal (exp .Value , pexp .Value ); isMatch {
158
+ break
159
+ }
160
+ }
161
+
162
+ out = append (out , MatchedExpression {
163
+ Feature : term .Feature ,
164
+ Name : name ,
165
+ Expression : exp ,
166
+ MatcherType : MatchExpressionType ,
167
+ IsMatch : isMatch ,
168
+ })
179
169
}
180
170
181
171
return out
182
172
}
183
173
174
+ func (nodeValidator ) matchName (term nfdv1alpha1.FeatureMatcherTerm , matchedFeatureTerms nfdv1alpha1.FeatureMatcher ) MatchedExpression {
175
+ isMatch := false
176
+ for _ , processedTerm := range matchedFeatureTerms {
177
+ if term .Feature != processedTerm .Feature || processedTerm .MatchName == nil {
178
+ continue
179
+ }
180
+ isMatch = term .MatchName .Op == processedTerm .MatchName .Op && slices .Equal (term .MatchName .Value , processedTerm .MatchName .Value )
181
+ if isMatch {
182
+ break
183
+ }
184
+ }
185
+ return MatchedExpression {
186
+ Feature : term .Feature ,
187
+ Name : "" ,
188
+ Expression : term .MatchName ,
189
+ MatcherType : MatchNameType ,
190
+ IsMatch : isMatch ,
191
+ }
192
+ }
193
+
184
194
// NodeValidatorOpts applies certain options to the node validator.
185
195
type NodeValidatorOpts interface {
186
196
apply (* nodeValidator )
0 commit comments