Skip to content

Commit

Permalink
pkg/apis/nfd: work around issues with k8s deepcopy-gen
Browse files Browse the repository at this point in the history
Without this hack the generated code does not compile.
  • Loading branch information
marquiz committed Nov 17, 2021
1 parent 7141071 commit eb1efdf
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 48 deletions.
24 changes: 17 additions & 7 deletions pkg/apis/nfd/v1alpha1/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ var matchOps = map[MatchOp]struct{}{
MatchIsFalse: struct{}{},
}

// NewMatchExpressionSet returns a new MatchExpressionSet instance.
func NewMatchExpressionSet() *MatchExpressionSet {
return &MatchExpressionSet{Expressions: make(Expressions)}
}

// Len returns the number of expressions.
func (e *Expressions) Len() int {
return len(*e)
}

// CreateMatchExpression creates a new MatchExpression instance. Returns an
// error if validation fails.
func CreateMatchExpression(op MatchOp, values ...string) (*MatchExpression, error) {
Expand Down Expand Up @@ -302,7 +312,7 @@ func (m *MatchExpression) UnmarshalJSON(data []byte) error {

// MatchKeys evaluates the MatchExpressionSet against a set of keys.
func (m *MatchExpressionSet) MatchKeys(keys map[string]feature.Nil) (bool, error) {
for n, e := range *m {
for n, e := range (*m).Expressions {
match, err := e.MatchKeys(n, keys)
if err != nil {
return false, err
Expand All @@ -316,7 +326,7 @@ func (m *MatchExpressionSet) MatchKeys(keys map[string]feature.Nil) (bool, error

// MatchValues evaluates the MatchExpressionSet against a set of key-value pairs.
func (m *MatchExpressionSet) MatchValues(values map[string]string) (bool, error) {
for n, e := range *m {
for n, e := range (*m).Expressions {
match, err := e.MatchValues(n, values)
if err != nil {
return false, err
Expand Down Expand Up @@ -344,17 +354,17 @@ func (m *MatchExpressionSet) MatchInstances(instances []feature.InstanceFeature)

// UnmarshalJSON implements the Unmarshaler interface of "encoding/json".
func (m *MatchExpressionSet) UnmarshalJSON(data []byte) error {
*m = make(MatchExpressionSet)
*m = *NewMatchExpressionSet()

names := make([]string, 0)
if err := json.Unmarshal(data, &names); err == nil {
// Simplified slice form
for _, name := range names {
split := strings.SplitN(name, "=", 2)
if len(split) == 1 {
(*m)[split[0]] = newMatchExpression(MatchExists)
(*m).Expressions[split[0]] = newMatchExpression(MatchExists)
} else {
(*m)[split[0]] = newMatchExpression(MatchIn, split[1])
(*m).Expressions[split[0]] = newMatchExpression(MatchIn, split[1])
}
}
} else {
Expand All @@ -365,9 +375,9 @@ func (m *MatchExpressionSet) UnmarshalJSON(data []byte) error {
} else {
for k, v := range expressions {
if v != nil {
(*m)[k] = v
(*m).Expressions[k] = v
} else {
(*m)[k] = newMatchExpression(MatchExists)
(*m).Expressions[k] = newMatchExpression(MatchExists)
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion pkg/apis/nfd/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,12 @@ type FeatureMatcherTerm struct {

// MatchExpressionSet contains a set of MatchExpressions, each of which is
// evaluated against a set of input values.
type MatchExpressionSet map[string]*MatchExpression
type MatchExpressionSet struct {
Expressions `json:",inline"`
}

// Expressions is a helper type to work around issues with k8s deepcopy-gen
type Expressions map[string]*MatchExpression

// MatchExpression specifies an expression to evaluate against a set of input
// values. It contains an operator that is applied when matching the input and
Expand Down
58 changes: 37 additions & 21 deletions pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 44 additions & 16 deletions source/custom/custom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ func TestRule(t *testing.T) {
Labels: map[string]string{"label-1": "label-val-1"},
MatchFeatures: FeatureMatcher{
FeatureMatcherTerm{
Feature: "domain-1.kf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{"key-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists)},
Feature: "domain-1.kf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{
Expressions: nfdv1alpha1.Expressions{
"key-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists),
},
},
},
},
}
Expand Down Expand Up @@ -94,8 +98,12 @@ func TestRule(t *testing.T) {
Labels: map[string]string{"label-3": "label-val-3", "empty": ""},
MatchFeatures: FeatureMatcher{
FeatureMatcherTerm{
Feature: "domain-1.vf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{"key-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1")},
Feature: "domain-1.vf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{
Expressions: nfdv1alpha1.Expressions{
"key-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1"),
},
},
},
},
}
Expand All @@ -113,8 +121,12 @@ func TestRule(t *testing.T) {
Labels: map[string]string{"label-4": "label-val-4"},
MatchFeatures: FeatureMatcher{
FeatureMatcherTerm{
Feature: "domain-1.if-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{"attr-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1")},
Feature: "domain-1.if-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{
Expressions: nfdv1alpha1.Expressions{
"attr-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1"),
},
},
},
},
}
Expand All @@ -132,20 +144,28 @@ func TestRule(t *testing.T) {
Labels: map[string]string{"label-5": "label-val-5"},
MatchFeatures: FeatureMatcher{
FeatureMatcherTerm{
Feature: "domain-1.vf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{"key-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-x")},
Feature: "domain-1.vf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{
Expressions: nfdv1alpha1.Expressions{
"key-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-x"),
},
},
},
FeatureMatcherTerm{
Feature: "domain-1.if-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{"attr-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1")},
Feature: "domain-1.if-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{
Expressions: nfdv1alpha1.Expressions{
"attr-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1"),
},
},
},
},
}
m, err = r5.execute(f)
assert.Nilf(t, err, "unexpected error: %v", err)
assert.Nil(t, m, "instances should not have matched")

r5.MatchFeatures[0].MatchExpressions["key-1"] = nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1")
r5.MatchFeatures[0].MatchExpressions.Expressions["key-1"] = nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1")
m, err = r5.execute(f)
assert.Nilf(t, err, "unexpected error: %v", err)
assert.Equal(t, r5.Labels, m, "instances should have matched")
Expand All @@ -155,8 +175,12 @@ func TestRule(t *testing.T) {
MatchAnyElem{
MatchFeatures: FeatureMatcher{
FeatureMatcherTerm{
Feature: "domain-1.kf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{"key-na": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists)},
Feature: "domain-1.kf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{
Expressions: nfdv1alpha1.Expressions{
"key-na": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists),
},
},
},
},
},
Expand All @@ -169,12 +193,16 @@ func TestRule(t *testing.T) {
MatchAnyElem{
MatchFeatures: FeatureMatcher{
FeatureMatcherTerm{
Feature: "domain-1.kf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{"key-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists)},
Feature: "domain-1.kf-1",
MatchExpressions: nfdv1alpha1.MatchExpressionSet{
Expressions: nfdv1alpha1.Expressions{
"key-1": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists),
},
},
},
},
})
r5.MatchFeatures[0].MatchExpressions["key-1"] = nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1")
r5.MatchFeatures[0].MatchExpressions.Expressions["key-1"] = nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "val-1")
m, err = r5.execute(f)
assert.Nilf(t, err, "unexpected error: %v", err)
assert.Equal(t, r5.Labels, m, "instances should have matched")
Expand Down
10 changes: 7 additions & 3 deletions source/custom/static_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ func getStaticFeatureConfig() []CustomRule {
{
PciID: &rules.PciIDRule{
MatchExpressionSet: nfdv1alpha1.MatchExpressionSet{
"vendor": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "15b3"),
Expressions: nfdv1alpha1.Expressions{
"vendor": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchIn, "15b3"),
},
},
},
},
Expand All @@ -46,8 +48,10 @@ func getStaticFeatureConfig() []CustomRule {
{
LoadedKMod: &rules.LoadedKModRule{
MatchExpressionSet: nfdv1alpha1.MatchExpressionSet{
"ib_uverbs": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists),
"rdma_ucm": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists),
Expressions: nfdv1alpha1.Expressions{
"ib_uverbs": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists),
"rdma_ucm": nfdv1alpha1.MustCreateMatchExpression(nfdv1alpha1.MatchExists),
},
},
},
},
Expand Down

0 comments on commit eb1efdf

Please sign in to comment.