1
0
Fork 0
mirror of https://github.com/kubernetes-sigs/node-feature-discovery.git synced 2025-04-15 00:36:23 +00:00

pkg/apis/nfd: specify CRD for custom labeling rules

Add a cluster-scoped Custom Resource Definition for specifying labeling
rules. Nodes (node features, node objects) are cluster-level objects and
thus the natural and encouraged setup is to only have one NFD deployment
per cluster - the set of underlying features of the node stays the same
independent of how many parallel NFD deployments you have. Our extension
points (hooks, feature files and now CRs) can be be used by multiple
actors (depending on us) simultaneously. Having the CRD cluster-scoped
hopefully drives deployments in this direction. It also should make
deployment of vendor-specific labeling rules easy as there is no need to
worry about the namespace.

This patch virtually replicates the source.custom.FeatureSpec in a CRD
API (located in the pkg/apis/nfd/v1alpha1 package) with the notable
exception that "MatchOn" legacy rules are not supported. Legacy rules
are left out in order to keep the CRD simple and clean.

The duplicate functionality in source/custom will be dropped by upcoming
patches.

This patch utilizes controller-gen (from sigs.k8s.io/controller-tools)
for generating the CRD and deepcopy methods. Code can be (re-)generated
with "make generate". Install controller-gen with:

  go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.7.0

Update kustomize and helm deployments to deploy the CRD.
This commit is contained in:
Markus Lehtonen 2021-08-31 11:10:12 +03:00
parent 0757248055
commit c3e2315834
16 changed files with 882 additions and 4 deletions

View file

@ -102,6 +102,8 @@ generate:
go mod vendor
go generate ./cmd/... ./pkg/... ./source/...
rm -rf vendor/
controller-gen object crd output:crd:stdout paths=./pkg/apis/... > deployment/base/nfd-crds/nodefeaturerule-crd.yaml
cp deployment/base/nfd-crds/nodefeaturerule-crd.yaml deployment/helm/node-feature-discovery/manifests/
gofmt:
@$(GO_FMT) -w -l $$(find . -name '*.go')

View file

@ -0,0 +1,71 @@
apiVersion: nfd.k8s-sigs.io/v1alpha1
kind: NodeFeatureRule
metadata:
name: my-rule
spec:
rules:
# The following feature demonstrates the capabilities of the matchFeatures and
# matchAny matchers.
- name: "my feature rule"
labels:
"my-complex-feature": "my-value"
# matchFeatures implements a logical AND over feature matchers.
matchFeatures:
- feature: cpu.cpuid
matchExpressions:
AVX512F: {op: Exists}
- feature: cpu.cstate
matchExpressions:
enabled: {op: IsTrue}
- feature: cpu.pstate
matchExpressions:
no_turbo: {op: IsFalse}
scaling_governor: {op: In, value: ["performance"]}
- feature: cpu.rdt
matchExpressions:
RDTL3CA: {op: Exists}
- feature: cpu.sst
matchExpressions:
bf.enabled: {op: IsTrue}
- feature: cpu.topology
matchExpressions:
hardware_multithreading: {op: IsFalse}
- feature: kernel.config
matchExpressions:
X86: {op: Exists}
LSM: {op: InRegexp, value: ["apparmor"]}
- feature: kernel.loadedmodule
matchExpressions:
e1000e: {op: Exists}
- feature: kernel.selinux
matchExpressions:
enabled: {op: IsFalse}
- feature: kernel.version
matchExpressions:
major: {op: In, value: ["5"]}
minor: {op: Gt, value: ["10"]}
- feature: system.osrelease
matchExpressions:
ID: {op: In, value: ["fedora", "centos"]}
- feature: system.name
matchExpressions:
nodename: {op: InRegexp, value: ["^worker-X"]}
- feature: local.label
matchExpressions:
custom-feature-knob: {op: Gt, value: ["100"]}
# matchAny implements a logical IF over all listed matchers (i.e. at
# least one must match)
matchAny:
- matchFeatures:
- feature: pci.device
matchExpressions:
vendor: {op: In, value: ["8086"]}
class: {op: In, value: ["0200"]}
- feature: usb.device
matchExpressions:
vendor: {op: In, value: ["8086"]}
class: {op: In, value: ["02"]}

View file

@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- nodefeaturerule-crd.yaml

View file

@ -0,0 +1,208 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.7.0
creationTimestamp: null
name: nodefeaturerules.nfd.k8s-sigs.io
spec:
group: nfd.k8s-sigs.io
names:
kind: NodeFeatureRule
listKind: NodeFeatureRuleList
plural: nodefeaturerules
singular: nodefeaturerule
scope: Cluster
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: NodeFeatureRule resource specifies a configuration for feature-based
customization of node objects, such as node labeling.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: NodeFeatureRuleSpec describes a NodeFeatureRule.
properties:
rules:
description: Rules is a list of node customization rules.
items:
description: Rule defines a rule for node customization such as
labeling.
properties:
labels:
additionalProperties:
type: string
description: Labels to create if the rule matches.
type: object
labelsTemplate:
description: LabelsTemplate specifies a template to expand for
dynamically generating multiple labels. Data (after template
expansion) must be keys with an optional value (<key>[=<value>])
separated by newlines.
type: string
matchAny:
description: MatchAny specifies a list of matchers one of which
must match.
items:
description: MatchAnyElem specifies one sub-matcher of MatchAny.
properties:
matchFeatures:
description: MatchFeatures specifies a set of matcher
terms all of which must match.
items:
description: FeatureMatcherTerm defines requirements
against one feature set. All requirements (specified
as MatchExpressions) are evaluated against each element
in the feature set.
properties:
feature:
type: string
matchExpressions:
additionalProperties:
description: "MatchExpression specifies an expression
to evaluate against a set of input values. It
contains an operator that is applied when matching
the input and an array of values that the operator
evaluates the input against. \n NB: CreateMatchExpression
or MustCreateMatchExpression() should be used
for creating new instances. NB: Validate()
must be called if Op or Value fields are modified
or if a new instance is created from scratch
without using the helper functions."
properties:
op:
description: Op is the operator to be applied.
enum:
- In
- NotIn
- InRegexp
- Exists
- DoesNotExist
- Gt
- Lt
- GtLt
- IsTrue
- IsFalse
type: string
value:
description: Value is the list of values that
the operand evaluates the input against.
Value should be empty if the operator is
Exists, DoesNotExist, IsTrue or IsFalse.
Value should contain exactly one element
if the operator is Gt or Lt and exactly
two elements if the operator is GtLt. In
other cases Value should contain at least
one element.
items:
type: string
type: array
required:
- op
type: object
description: MatchExpressionSet contains a set of
MatchExpressions, each of which is evaluated against
a set of input values.
type: object
required:
- feature
- matchExpressions
type: object
type: array
required:
- matchFeatures
type: object
type: array
matchFeatures:
description: MatchFeatures specifies a set of matcher terms
all of which must match.
items:
description: FeatureMatcherTerm defines requirements against
one feature set. All requirements (specified as MatchExpressions)
are evaluated against each element in the feature set.
properties:
feature:
type: string
matchExpressions:
additionalProperties:
description: "MatchExpression specifies an expression
to evaluate against a set of input values. It contains
an operator that is applied when matching the input
and an array of values that the operator evaluates
the input against. \n NB: CreateMatchExpression or
MustCreateMatchExpression() should be used for creating
new instances. NB: Validate() must be called if Op
or Value fields are modified or if a new instance
is created from scratch without using the helper functions."
properties:
op:
description: Op is the operator to be applied.
enum:
- In
- NotIn
- InRegexp
- Exists
- DoesNotExist
- Gt
- Lt
- GtLt
- IsTrue
- IsFalse
type: string
value:
description: Value is the list of values that the
operand evaluates the input against. Value should
be empty if the operator is Exists, DoesNotExist,
IsTrue or IsFalse. Value should contain exactly
one element if the operator is Gt or Lt and exactly
two elements if the operator is GtLt. In other
cases Value should contain at least one element.
items:
type: string
type: array
required:
- op
type: object
description: MatchExpressionSet contains a set of MatchExpressions,
each of which is evaluated against a set of input values.
type: object
required:
- feature
- matchExpressions
type: object
type: array
name:
description: Name of the rule.
type: string
required:
- name
type: object
type: array
required:
- rules
type: object
required:
- spec
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -0,0 +1,208 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.7.0
creationTimestamp: null
name: nodefeaturerules.nfd.k8s-sigs.io
spec:
group: nfd.k8s-sigs.io
names:
kind: NodeFeatureRule
listKind: NodeFeatureRuleList
plural: nodefeaturerules
singular: nodefeaturerule
scope: Cluster
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: NodeFeatureRule resource specifies a configuration for feature-based
customization of node objects, such as node labeling.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: NodeFeatureRuleSpec describes a NodeFeatureRule.
properties:
rules:
description: Rules is a list of node customization rules.
items:
description: Rule defines a rule for node customization such as
labeling.
properties:
labels:
additionalProperties:
type: string
description: Labels to create if the rule matches.
type: object
labelsTemplate:
description: LabelsTemplate specifies a template to expand for
dynamically generating multiple labels. Data (after template
expansion) must be keys with an optional value (<key>[=<value>])
separated by newlines.
type: string
matchAny:
description: MatchAny specifies a list of matchers one of which
must match.
items:
description: MatchAnyElem specifies one sub-matcher of MatchAny.
properties:
matchFeatures:
description: MatchFeatures specifies a set of matcher
terms all of which must match.
items:
description: FeatureMatcherTerm defines requirements
against one feature set. All requirements (specified
as MatchExpressions) are evaluated against each element
in the feature set.
properties:
feature:
type: string
matchExpressions:
additionalProperties:
description: "MatchExpression specifies an expression
to evaluate against a set of input values. It
contains an operator that is applied when matching
the input and an array of values that the operator
evaluates the input against. \n NB: CreateMatchExpression
or MustCreateMatchExpression() should be used
for creating new instances. NB: Validate()
must be called if Op or Value fields are modified
or if a new instance is created from scratch
without using the helper functions."
properties:
op:
description: Op is the operator to be applied.
enum:
- In
- NotIn
- InRegexp
- Exists
- DoesNotExist
- Gt
- Lt
- GtLt
- IsTrue
- IsFalse
type: string
value:
description: Value is the list of values that
the operand evaluates the input against.
Value should be empty if the operator is
Exists, DoesNotExist, IsTrue or IsFalse.
Value should contain exactly one element
if the operator is Gt or Lt and exactly
two elements if the operator is GtLt. In
other cases Value should contain at least
one element.
items:
type: string
type: array
required:
- op
type: object
description: MatchExpressionSet contains a set of
MatchExpressions, each of which is evaluated against
a set of input values.
type: object
required:
- feature
- matchExpressions
type: object
type: array
required:
- matchFeatures
type: object
type: array
matchFeatures:
description: MatchFeatures specifies a set of matcher terms
all of which must match.
items:
description: FeatureMatcherTerm defines requirements against
one feature set. All requirements (specified as MatchExpressions)
are evaluated against each element in the feature set.
properties:
feature:
type: string
matchExpressions:
additionalProperties:
description: "MatchExpression specifies an expression
to evaluate against a set of input values. It contains
an operator that is applied when matching the input
and an array of values that the operator evaluates
the input against. \n NB: CreateMatchExpression or
MustCreateMatchExpression() should be used for creating
new instances. NB: Validate() must be called if Op
or Value fields are modified or if a new instance
is created from scratch without using the helper functions."
properties:
op:
description: Op is the operator to be applied.
enum:
- In
- NotIn
- InRegexp
- Exists
- DoesNotExist
- Gt
- Lt
- GtLt
- IsTrue
- IsFalse
type: string
value:
description: Value is the list of values that the
operand evaluates the input against. Value should
be empty if the operator is Exists, DoesNotExist,
IsTrue or IsFalse. Value should contain exactly
one element if the operator is Gt or Lt and exactly
two elements if the operator is GtLt. In other
cases Value should contain at least one element.
items:
type: string
type: array
required:
- op
type: object
description: MatchExpressionSet contains a set of MatchExpressions,
each of which is evaluated against a set of input values.
type: object
required:
- feature
- matchExpressions
type: object
type: array
name:
description: Name of the rule.
type: string
required:
- name
type: object
type: array
required:
- rules
type: object
required:
- spec
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -0,0 +1,3 @@
{{- if .Values.nodeFeatureRule.createCRD }}
{{ .Files.Get "manifests/nodefeaturerule-crd.yaml" }}
{{- end}}

View file

@ -18,6 +18,9 @@ serviceAccount:
nameOverride: ""
fullnameOverride: ""
nodeFeatureRule:
createCRD: true
master:
instance:
extraLabelNs: []

View file

@ -5,6 +5,7 @@ namespace: node-feature-discovery
bases:
- ../../base/rbac
- ../../base/nfd-crds
- ../../base/master-worker-combined
resources:

View file

@ -5,6 +5,7 @@ namespace: node-feature-discovery
bases:
- ../../base/rbac
- ../../base/nfd-crds
- ../../base/master
- ../../base/worker-job

View file

@ -5,6 +5,7 @@ namespace: node-feature-discovery
bases:
- ../../base/rbac
- ../../base/nfd-crds
- ../../base/master
- ../../base/worker-daemonset

View file

@ -6,6 +6,7 @@ namespace: node-feature-discovery
bases:
- ../../base/rbac
- ../../base/rbac-topologyupdater
- ../../base/nfd-crds
- ../../base/master
- ../../base/worker-daemonset
- ../../base/noderesourcetopologies-crd

View file

@ -290,6 +290,7 @@ We have introduced the following Chart parameters.
| `rbac` | dict | | RBAC [parameteres](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) |
| `nameOverride` | string | | Override the name of the chart |
| `fullnameOverride` | string | | Override a default fully qualified app name |
| `nodeFeatureRule.createCRD` | bool | true | Specifies whether to create the NodeFeatureRule CRD |
##### Master pod parameters

1
go.mod
View file

@ -87,7 +87,6 @@ require (
github.com/go-ozzo/ozzo-validation v3.5.0+incompatible // indirect
github.com/godbus/dbus/v5 v5.0.4 // indirect
github.com/gofrs/uuid v4.0.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.4.4 // indirect
github.com/google/cadvisor v0.39.2 // indirect

View file

@ -0,0 +1,20 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +kubebuilder:object:generate=true
// +groupName=nfd.k8s-sigs.io
package v1alpha1

View file

@ -18,8 +18,80 @@ package v1alpha1
import (
"regexp"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// NodeFeatureRuleList contains a list of NodeFeatureRule objects.
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type NodeFeatureRuleList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []NodeFeatureRule `json:"items"`
}
// NodeFeatureRule resource specifies a configuration for feature-based
// customization of node objects, such as node labeling.
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type NodeFeatureRule struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec NodeFeatureRuleSpec `json:"spec"`
}
// NodeFeatureRuleSpec describes a NodeFeatureRule.
type NodeFeatureRuleSpec struct {
// Rules is a list of node customization rules.
Rules []Rule `json:"rules"`
}
// Rule defines a rule for node customization such as labeling.
type Rule struct {
// Name of the rule.
Name string `json:"name"`
// Labels to create if the rule matches.
// +optional
Labels map[string]string `json:"labels"`
// LabelsTemplate specifies a template to expand for dynamically generating
// multiple labels. Data (after template expansion) must be keys with an
// optional value (<key>[=<value>]) separated by newlines.
// +optional
LabelsTemplate string `json:"labelsTemplate"`
// MatchFeatures specifies a set of matcher terms all of which must match.
// +optional
MatchFeatures FeatureMatcher `json:"matchFeatures"`
// MatchAny specifies a list of matchers one of which must match.
// +optional
MatchAny []MatchAnyElem `json:"matchAny"`
}
// MatchAnyElem specifies one sub-matcher of MatchAny.
type MatchAnyElem struct {
// MatchFeatures specifies a set of matcher terms all of which must match.
MatchFeatures FeatureMatcher `json:"matchFeatures"`
}
// FeatureMatcher specifies a set of feature matcher terms (i.e. per-feature
// matchers), all of which must match.
type FeatureMatcher []FeatureMatcherTerm
// FeatureMatcherTerm defines requirements against one feature set. All
// requirements (specified as MatchExpressions) are evaluated against each
// element in the feature set.
type FeatureMatcherTerm struct {
Feature string `json:"feature"`
MatchExpressions MatchExpressionSet `json:"matchExpressions"`
}
// MatchExpressionSet contains a set of MatchExpressions, each of which is
// evaluated against a set of input values.
type MatchExpressionSet map[string]*MatchExpression
@ -27,27 +99,30 @@ type MatchExpressionSet 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
// an array of values that the operator evaluates the input against.
//
// NB: CreateMatchExpression or MustCreateMatchExpression() should be used for
// creating new instances.
// NB: Validate() must be called if Op or Value fields are modified or if a new
// instance is created from scratch without using the helper functions.
type MatchExpression struct {
// Op is the operator to be applied.
Op MatchOp
Op MatchOp `json:"op"`
// Value is the list of values that the operand evaluates the input
// against. Value should be empty if the operator is Exists, DoesNotExist,
// IsTrue or IsFalse. Value should contain exactly one element if the
// operator is Gt or Lt and exactly two elements if the operator is GtLt.
// In other cases Value should contain at least one element.
Value MatchValue `json:",omitempty"`
// +optional
Value MatchValue `json:"value,omitempty"`
// valueRe caches compiled regexps for "InRegexp" operator
valueRe []*regexp.Regexp
valueRe []*regexp.Regexp `json:"-"`
}
// MatchOp is the match operator that is applied on values when evaluating a
// MatchExpression.
// +kubebuilder:validation:Enum="In";"NotIn";"InRegexp";"Exists";"DoesNotExist";"Gt";"Lt";"GtLt";"IsTrue";"IsFalse"
type MatchOp string
// MatchValue is the list of values associated with a MatchExpression.

View file

@ -0,0 +1,279 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
// Code generated by controller-gen. DO NOT EDIT.
package v1alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
regexpx "regexp"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in FeatureMatcher) DeepCopyInto(out *FeatureMatcher) {
{
in := &in
*out = make(FeatureMatcher, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureMatcher.
func (in FeatureMatcher) DeepCopy() FeatureMatcher {
if in == nil {
return nil
}
out := new(FeatureMatcher)
in.DeepCopyInto(out)
return *out
}
// 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
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureMatcherTerm.
func (in *FeatureMatcherTerm) DeepCopy() *FeatureMatcherTerm {
if in == nil {
return nil
}
out := new(FeatureMatcherTerm)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MatchAnyElem) DeepCopyInto(out *MatchAnyElem) {
*out = *in
if in.MatchFeatures != nil {
in, out := &in.MatchFeatures, &out.MatchFeatures
*out = make(FeatureMatcher, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchAnyElem.
func (in *MatchAnyElem) DeepCopy() *MatchAnyElem {
if in == nil {
return nil
}
out := new(MatchAnyElem)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MatchExpression) DeepCopyInto(out *MatchExpression) {
*out = *in
if in.Value != nil {
in, out := &in.Value, &out.Value
*out = make(MatchValue, len(*in))
copy(*out, *in)
}
if in.valueRe != nil {
in, out := &in.valueRe, &out.valueRe
*out = make([]*regexpx.Regexp, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(regexpx.Regexp)
(*in).DeepCopyInto(*out)
}
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchExpression.
func (in *MatchExpression) DeepCopy() *MatchExpression {
if in == nil {
return nil
}
out := new(MatchExpression)
in.DeepCopyInto(out)
return out
}
// 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))
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 MatchExpressionSet.
func (in MatchExpressionSet) DeepCopy() MatchExpressionSet {
if in == nil {
return nil
}
out := new(MatchExpressionSet)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in MatchValue) DeepCopyInto(out *MatchValue) {
{
in := &in
*out = make(MatchValue, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchValue.
func (in MatchValue) DeepCopy() MatchValue {
if in == nil {
return nil
}
out := new(MatchValue)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeFeatureRule) DeepCopyInto(out *NodeFeatureRule) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRule.
func (in *NodeFeatureRule) DeepCopy() *NodeFeatureRule {
if in == nil {
return nil
}
out := new(NodeFeatureRule)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *NodeFeatureRule) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeFeatureRuleList) DeepCopyInto(out *NodeFeatureRuleList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]NodeFeatureRule, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRuleList.
func (in *NodeFeatureRuleList) DeepCopy() *NodeFeatureRuleList {
if in == nil {
return nil
}
out := new(NodeFeatureRuleList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *NodeFeatureRuleList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeFeatureRuleSpec) DeepCopyInto(out *NodeFeatureRuleSpec) {
*out = *in
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]Rule, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRuleSpec.
func (in *NodeFeatureRuleSpec) DeepCopy() *NodeFeatureRuleSpec {
if in == nil {
return nil
}
out := new(NodeFeatureRuleSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Rule) DeepCopyInto(out *Rule) {
*out = *in
if in.Labels != nil {
in, out := &in.Labels, &out.Labels
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.MatchFeatures != nil {
in, out := &in.MatchFeatures, &out.MatchFeatures
*out = make(FeatureMatcher, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.MatchAny != nil {
in, out := &in.MatchAny, &out.MatchAny
*out = make([]MatchAnyElem, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule.
func (in *Rule) DeepCopy() *Rule {
if in == nil {
return nil
}
out := new(Rule)
in.DeepCopyInto(out)
return out
}