From f3cc109f99494094884a38a5089e88078a2a3d32 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 12 May 2021 13:56:24 +0300 Subject: [PATCH] pkg/apis/nfd: work around issues with k8s deepcopy-gen Without this hack the generated code does not compile. --- pkg/apis/nfd/v1alpha1/expression.go | 24 +++++--- pkg/apis/nfd/v1alpha1/types.go | 7 ++- .../nfd/v1alpha1/zz_generated.deepcopy.go | 58 +++++++++++------- source/custom/custom_test.go | 60 ++++++++++++++----- source/custom/static_features.go | 10 +++- 5 files changed, 111 insertions(+), 48 deletions(-) diff --git a/pkg/apis/nfd/v1alpha1/expression.go b/pkg/apis/nfd/v1alpha1/expression.go index 5c6c186c3..7d4f49930 100644 --- a/pkg/apis/nfd/v1alpha1/expression.go +++ b/pkg/apis/nfd/v1alpha1/expression.go @@ -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) { @@ -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 @@ -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 @@ -344,7 +354,7 @@ 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 { @@ -352,9 +362,9 @@ func (m *MatchExpressionSet) UnmarshalJSON(data []byte) error { 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 { @@ -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) } } } diff --git a/pkg/apis/nfd/v1alpha1/types.go b/pkg/apis/nfd/v1alpha1/types.go index 99475e53a..eb6908f01 100644 --- a/pkg/apis/nfd/v1alpha1/types.go +++ b/pkg/apis/nfd/v1alpha1/types.go @@ -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 diff --git a/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go index d44d88de6..ddc7c86b1 100644 --- a/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go @@ -10,6 +10,35 @@ import ( regexpx "regexp" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Expressions) DeepCopyInto(out *Expressions) { + { + in := &in + *out = make(Expressions, len(*in)) + for key, val := range *in { + var outVal *MatchExpression + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = new(MatchExpression) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Expressions. +func (in Expressions) DeepCopy() Expressions { + if in == nil { + return nil + } + out := new(Expressions) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in FeatureMatcher) DeepCopyInto(out *FeatureMatcher) { { @@ -34,21 +63,7 @@ func (in FeatureMatcher) DeepCopy() FeatureMatcher { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FeatureMatcherTerm) DeepCopyInto(out *FeatureMatcherTerm) { *out = *in - if in.MatchExpressions != nil { - in, out := &in.MatchExpressions, &out.MatchExpressions - *out = make(MatchExpressionSet, len(*in)) - for key, val := range *in { - var outVal *MatchExpression - if val == nil { - (*out)[key] = nil - } else { - in, out := &val, &outVal - *out = new(MatchExpression) - (*in).DeepCopyInto(*out) - } - (*out)[key] = outVal - } - } + in.MatchExpressions.DeepCopyInto(&out.MatchExpressions) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureMatcherTerm. @@ -115,10 +130,11 @@ func (in *MatchExpression) DeepCopy() *MatchExpression { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in MatchExpressionSet) DeepCopyInto(out *MatchExpressionSet) { - { - in := &in - *out = make(MatchExpressionSet, len(*in)) +func (in *MatchExpressionSet) DeepCopyInto(out *MatchExpressionSet) { + *out = *in + if in.Expressions != nil { + in, out := &in.Expressions, &out.Expressions + *out = make(Expressions, len(*in)) for key, val := range *in { var outVal *MatchExpression if val == nil { @@ -134,13 +150,13 @@ func (in MatchExpressionSet) DeepCopyInto(out *MatchExpressionSet) { } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchExpressionSet. -func (in MatchExpressionSet) DeepCopy() MatchExpressionSet { +func (in *MatchExpressionSet) DeepCopy() *MatchExpressionSet { if in == nil { return nil } out := new(MatchExpressionSet) in.DeepCopyInto(out) - return *out + return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. diff --git a/source/custom/custom_test.go b/source/custom/custom_test.go index d29a7fbad..7d4f6f8d7 100644 --- a/source/custom/custom_test.go +++ b/source/custom/custom_test.go @@ -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), + }, + }, }, }, } @@ -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"), + }, + }, }, }, } @@ -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"), + }, + }, }, }, } @@ -132,12 +144,20 @@ 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"), + }, + }, }, }, } @@ -145,7 +165,7 @@ func TestRule(t *testing.T) { 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") @@ -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), + }, + }, }, }, }, @@ -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") diff --git a/source/custom/static_features.go b/source/custom/static_features.go index fed8a22c5..db1856c9f 100644 --- a/source/custom/static_features.go +++ b/source/custom/static_features.go @@ -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"), + }, }, }, }, @@ -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), + }, }, }, },