mirror of
https://github.com/kubernetes/kubernetes.git
synced 2026-02-18 18:28:18 -05:00
network: migrate CIDR validation to DV
Co-authored-by: Abhishek Srivastava <abhishek@asrivas.me>
This commit is contained in:
parent
1c24a05ce1
commit
bc17031d19
9 changed files with 555 additions and 5 deletions
163
pkg/apis/networking/v1/zz_generated.validations.go
generated
163
pkg/apis/networking/v1/zz_generated.validations.go
generated
|
|
@ -47,9 +47,43 @@ func RegisterValidations(scheme *runtime.Scheme) error {
|
|||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
// type NetworkPolicy
|
||||
scheme.AddValidationFunc((*networkingv1.NetworkPolicy)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_NetworkPolicy(ctx, op, nil /* fldPath */, obj.(*networkingv1.NetworkPolicy), safe.Cast[*networkingv1.NetworkPolicy](oldObj))
|
||||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate_IPBlock validates an instance of IPBlock according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_IPBlock(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *networkingv1.IPBlock) (errs field.ErrorList) {
|
||||
// field networkingv1.IPBlock.CIDR
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *string, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
return
|
||||
}(fldPath.Child("cidr"), &obj.CIDR, safe.Field(oldObj, func(oldObj *networkingv1.IPBlock) *string { return &oldObj.CIDR }), oldObj != nil)...)
|
||||
|
||||
// field networkingv1.IPBlock.Except has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_IngressClass validates an instance of IngressClass according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_IngressClass(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *networkingv1.IngressClass) (errs field.ErrorList) {
|
||||
|
|
@ -148,3 +182,132 @@ func Validate_IngressClassSpec(ctx context.Context, op operation.Operation, fldP
|
|||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicy validates an instance of NetworkPolicy according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicy(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *networkingv1.NetworkPolicy) (errs field.ErrorList) {
|
||||
// field networkingv1.NetworkPolicy.TypeMeta has no validation
|
||||
// field networkingv1.NetworkPolicy.ObjectMeta has no validation
|
||||
|
||||
// field networkingv1.NetworkPolicy.Spec
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *networkingv1.NetworkPolicySpec, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_NetworkPolicySpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("spec"), &obj.Spec, safe.Field(oldObj, func(oldObj *networkingv1.NetworkPolicy) *networkingv1.NetworkPolicySpec { return &oldObj.Spec }), oldObj != nil)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicyEgressRule validates an instance of NetworkPolicyEgressRule according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicyEgressRule(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *networkingv1.NetworkPolicyEgressRule) (errs field.ErrorList) {
|
||||
// field networkingv1.NetworkPolicyEgressRule.Ports has no validation
|
||||
|
||||
// field networkingv1.NetworkPolicyEgressRule.To
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []networkingv1.NetworkPolicyPeer, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyPeer)...)
|
||||
return
|
||||
}(fldPath.Child("to"), obj.To, safe.Field(oldObj, func(oldObj *networkingv1.NetworkPolicyEgressRule) []networkingv1.NetworkPolicyPeer { return oldObj.To }), oldObj != nil)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicyIngressRule validates an instance of NetworkPolicyIngressRule according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicyIngressRule(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *networkingv1.NetworkPolicyIngressRule) (errs field.ErrorList) {
|
||||
// field networkingv1.NetworkPolicyIngressRule.Ports has no validation
|
||||
|
||||
// field networkingv1.NetworkPolicyIngressRule.From
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []networkingv1.NetworkPolicyPeer, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyPeer)...)
|
||||
return
|
||||
}(fldPath.Child("from"), obj.From, safe.Field(oldObj, func(oldObj *networkingv1.NetworkPolicyIngressRule) []networkingv1.NetworkPolicyPeer {
|
||||
return oldObj.From
|
||||
}), oldObj != nil)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicyPeer validates an instance of NetworkPolicyPeer according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicyPeer(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *networkingv1.NetworkPolicyPeer) (errs field.ErrorList) {
|
||||
// field networkingv1.NetworkPolicyPeer.PodSelector has no validation
|
||||
// field networkingv1.NetworkPolicyPeer.NamespaceSelector has no validation
|
||||
|
||||
// field networkingv1.NetworkPolicyPeer.IPBlock
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *networkingv1.IPBlock, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_IPBlock(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("ipBlock"), obj.IPBlock, safe.Field(oldObj, func(oldObj *networkingv1.NetworkPolicyPeer) *networkingv1.IPBlock { return oldObj.IPBlock }), oldObj != nil)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicySpec validates an instance of NetworkPolicySpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicySpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *networkingv1.NetworkPolicySpec) (errs field.ErrorList) {
|
||||
// field networkingv1.NetworkPolicySpec.PodSelector has no validation
|
||||
|
||||
// field networkingv1.NetworkPolicySpec.Ingress
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []networkingv1.NetworkPolicyIngressRule, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyIngressRule)...)
|
||||
return
|
||||
}(fldPath.Child("ingress"), obj.Ingress, safe.Field(oldObj, func(oldObj *networkingv1.NetworkPolicySpec) []networkingv1.NetworkPolicyIngressRule {
|
||||
return oldObj.Ingress
|
||||
}), oldObj != nil)...)
|
||||
|
||||
// field networkingv1.NetworkPolicySpec.Egress
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []networkingv1.NetworkPolicyEgressRule, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyEgressRule)...)
|
||||
return
|
||||
}(fldPath.Child("egress"), obj.Egress, safe.Field(oldObj, func(oldObj *networkingv1.NetworkPolicySpec) []networkingv1.NetworkPolicyEgressRule {
|
||||
return oldObj.Egress
|
||||
}), oldObj != nil)...)
|
||||
|
||||
// field networkingv1.NetworkPolicySpec.PolicyTypes has no validation
|
||||
return errs
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ func ValidateNetworkPolicyUpdate(update, old *networking.NetworkPolicy, opts Net
|
|||
func ValidateIPBlock(ipb *networking.IPBlock, fldPath *field.Path, opts NetworkPolicyValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if ipb.CIDR == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("cidr"), ""))
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("cidr"), "").MarkCoveredByDeclarative())
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, apivalidation.IsValidCIDRForLegacyField(fldPath.Child("cidr"), ipb.CIDR, opts.AllowCIDRsEvenIfInvalid)...)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
Copyright 2025 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.
|
||||
*/
|
||||
|
||||
package networkpolicy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
networking "k8s.io/kubernetes/pkg/apis/networking"
|
||||
)
|
||||
|
||||
var apiVersions = []string{"v1"}
|
||||
|
||||
func TestDeclarativeValidateIPBlockCIDR(t *testing.T) {
|
||||
|
||||
for _, apiVersion := range apiVersions {
|
||||
t.Run(apiVersion, func(t *testing.T) {
|
||||
ctx := genericapirequest.WithRequestInfo(
|
||||
genericapirequest.NewDefaultContext(),
|
||||
&genericapirequest.RequestInfo{
|
||||
APIGroup: "networking.k8s.io",
|
||||
APIVersion: apiVersion,
|
||||
Resource: "networkpolicies",
|
||||
IsResourceRequest: true,
|
||||
Verb: "create",
|
||||
},
|
||||
)
|
||||
|
||||
testCases := map[string]struct {
|
||||
input networking.NetworkPolicy
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid ingress rule with CIDR": {
|
||||
input: mkValidNetworkPolicy("ingress"),
|
||||
},
|
||||
"valid egress rule with CIDR": {
|
||||
input: mkValidNetworkPolicy("egress"),
|
||||
},
|
||||
"ingress rule rejects empty CIDR in ipBlock": {
|
||||
input: mkValidNetworkPolicy("ingress", tweakIngressFromIPBlock("")),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Required(
|
||||
field.NewPath("spec", "ingress").Index(0).Child("from").Index(0).Child("ipBlock", "cidr"),
|
||||
"",
|
||||
),
|
||||
},
|
||||
},
|
||||
"egress rule rejects empty CIDR in ipBlock": {
|
||||
input: mkValidNetworkPolicy("egress", tweakEgressToIPBlock("")),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Required(
|
||||
field.NewPath("spec", "egress").Index(0).Child("to").Index(0).Child("ipBlock", "cidr"),
|
||||
"",
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
apitesting.VerifyValidationEquivalence(
|
||||
t,
|
||||
ctx,
|
||||
&tc.input,
|
||||
Strategy.Validate,
|
||||
tc.expectedErrs,
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeclarativeValidateIPBlockCIDRUpdate(t *testing.T) {
|
||||
for _, apiVersion := range apiVersions {
|
||||
t.Run(apiVersion, func(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
oldObj networking.NetworkPolicy
|
||||
updateObj networking.NetworkPolicy
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid update ingress rule with CIDR": {
|
||||
oldObj: mkValidNetworkPolicy("ingress"),
|
||||
updateObj: mkValidNetworkPolicy("ingress", tweakIngressFromIPBlock("10.0.0.0/8")),
|
||||
},
|
||||
"valid update egress rule with CIDR": {
|
||||
oldObj: mkValidNetworkPolicy("egress"),
|
||||
updateObj: mkValidNetworkPolicy("egress", tweakEgressToIPBlock("10.0.0.0/8")),
|
||||
},
|
||||
"update ingress rule rejects empty CIDR in ipBlock": {
|
||||
oldObj: mkValidNetworkPolicy("ingress"),
|
||||
updateObj: mkValidNetworkPolicy("ingress", tweakIngressFromIPBlock("")),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Required(
|
||||
field.NewPath("spec", "ingress").Index(0).Child("from").Index(0).Child("ipBlock", "cidr"),
|
||||
"",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
"update egress rule rejects empty CIDR in ipBlock": {
|
||||
oldObj: mkValidNetworkPolicy("egress"),
|
||||
updateObj: mkValidNetworkPolicy("egress", tweakEgressToIPBlock("")),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Required(
|
||||
field.NewPath("spec", "egress").Index(0).Child("to").Index(0).Child("ipBlock", "cidr"),
|
||||
"",
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
ctx := genericapirequest.WithRequestInfo(
|
||||
genericapirequest.NewDefaultContext(),
|
||||
&genericapirequest.RequestInfo{
|
||||
APIPrefix: "apis",
|
||||
APIGroup: "networking.k8s.io",
|
||||
APIVersion: apiVersion,
|
||||
Resource: "networkpolicies",
|
||||
Name: "valid-network-policy",
|
||||
IsResourceRequest: true,
|
||||
Verb: "update",
|
||||
},
|
||||
)
|
||||
|
||||
apitesting.VerifyUpdateValidationEquivalence(
|
||||
t,
|
||||
ctx,
|
||||
&tc.updateObj,
|
||||
&tc.oldObj,
|
||||
Strategy.ValidateUpdate,
|
||||
tc.expectedErrs,
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func tweakIngressFromIPBlock(cidr string) func(obj *networking.NetworkPolicy) {
|
||||
return func(obj *networking.NetworkPolicy) {
|
||||
obj.Spec.Ingress[0].From[0].IPBlock.CIDR = cidr
|
||||
}
|
||||
}
|
||||
|
||||
func tweakEgressToIPBlock(cidr string) func(obj *networking.NetworkPolicy) {
|
||||
return func(obj *networking.NetworkPolicy) {
|
||||
obj.Spec.Egress[0].To[0].IPBlock.CIDR = cidr
|
||||
}
|
||||
}
|
||||
func mkValidNetworkPolicy(ruleType string, tweaks ...func(obj *networking.NetworkPolicy)) networking.NetworkPolicy {
|
||||
obj := networking.NetworkPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid-network-policy",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: networking.NetworkPolicySpec{
|
||||
PodSelector: metav1.LabelSelector{},
|
||||
},
|
||||
}
|
||||
|
||||
switch ruleType {
|
||||
case "ingress":
|
||||
obj.Spec.Ingress = []networking.NetworkPolicyIngressRule{
|
||||
{
|
||||
From: []networking.NetworkPolicyPeer{
|
||||
{
|
||||
IPBlock: &networking.IPBlock{
|
||||
CIDR: "192.168.1.0/24",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case "egress":
|
||||
obj.Spec.Egress = []networking.NetworkPolicyEgressRule{
|
||||
{
|
||||
To: []networking.NetworkPolicyPeer{
|
||||
{
|
||||
IPBlock: &networking.IPBlock{
|
||||
CIDR: "192.168.1.0/24",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
obj.ResourceVersion = "1"
|
||||
|
||||
for _, tweak := range tweaks {
|
||||
tweak(&obj)
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@ package networkpolicy
|
|||
|
||||
import (
|
||||
"context"
|
||||
"k8s.io/apimachinery/pkg/api/operation"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
|
@ -66,7 +68,9 @@ func (networkPolicyStrategy) PrepareForUpdate(ctx context.Context, obj, old runt
|
|||
func (networkPolicyStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||
networkPolicy := obj.(*networking.NetworkPolicy)
|
||||
ops := validation.ValidationOptionsForNetworking(networkPolicy, nil)
|
||||
return validation.ValidateNetworkPolicy(networkPolicy, ops)
|
||||
allErrs := validation.ValidateNetworkPolicy(networkPolicy, ops)
|
||||
return rest.ValidateDeclarativelyWithMigrationChecks(ctx, legacyscheme.Scheme, networkPolicy, nil, allErrs, operation.Create)
|
||||
|
||||
}
|
||||
|
||||
// WarningsOnCreate returns warnings for the creation of the given object.
|
||||
|
|
@ -85,9 +89,8 @@ func (networkPolicyStrategy) AllowCreateOnUpdate() bool {
|
|||
// ValidateUpdate is the default update validation for an end user.
|
||||
func (networkPolicyStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||
opts := validation.ValidationOptionsForNetworking(obj.(*networking.NetworkPolicy), old.(*networking.NetworkPolicy))
|
||||
validationErrorList := validation.ValidateNetworkPolicy(obj.(*networking.NetworkPolicy), opts)
|
||||
updateErrorList := validation.ValidateNetworkPolicyUpdate(obj.(*networking.NetworkPolicy), old.(*networking.NetworkPolicy), opts)
|
||||
return append(validationErrorList, updateErrorList...)
|
||||
allErrs := validation.ValidateNetworkPolicyUpdate(obj.(*networking.NetworkPolicy), old.(*networking.NetworkPolicy), opts)
|
||||
return rest.ValidateDeclarativelyWithMigrationChecks(ctx, legacyscheme.Scheme, obj, old, allErrs, operation.Update)
|
||||
}
|
||||
|
||||
// WarningsOnUpdate returns warnings for the given update.
|
||||
|
|
|
|||
|
|
@ -428,6 +428,8 @@ message HTTPIngressRuleValue {
|
|||
message IPBlock {
|
||||
// CIDR is a string representing the IP Block
|
||||
// Valid examples are "192.168.1.0/24" or "2001:db8::/64"
|
||||
// +required
|
||||
// +k8s:required
|
||||
optional string cidr = 1;
|
||||
|
||||
// Except is a slice of CIDRs that should not be included within an IP Block
|
||||
|
|
@ -746,6 +748,7 @@ message NetworkPolicyPeer {
|
|||
// IPBlock defines policy on a particular IPBlock. If this field is set then
|
||||
// neither of the other fields can be.
|
||||
// +optional
|
||||
// +k8s:optional
|
||||
optional IPBlock ipBlock = 3;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1209,6 +1209,8 @@ type NetworkPolicyPort struct {
|
|||
type IPBlock struct {
|
||||
// CIDR is a string representing the IP Block
|
||||
// Valid examples are "192.168.1.0/24" or "2001:db8::/64"
|
||||
// +required
|
||||
// +k8s:required
|
||||
CIDR string `json:"cidr" protobuf:"bytes,1,name=cidr"`
|
||||
// Except is a slice of CIDRs that should not be included within an IP Block
|
||||
// Valid examples are "192.168.1.0/24" or "2001:db8::/64"
|
||||
|
|
@ -1241,6 +1243,7 @@ type NetworkPolicyPeer struct {
|
|||
// IPBlock defines policy on a particular IPBlock. If this field is set then
|
||||
// neither of the other fields can be.
|
||||
// +optional
|
||||
// +k8s:optional
|
||||
IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
operation "k8s.io/apimachinery/pkg/api/operation"
|
||||
safe "k8s.io/apimachinery/pkg/api/safe"
|
||||
validate "k8s.io/apimachinery/pkg/api/validate"
|
||||
|
|
@ -37,6 +38,14 @@ func init() { localSchemeBuilder.Register(RegisterValidations) }
|
|||
// RegisterValidations adds validation functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterValidations(scheme *runtime.Scheme) error {
|
||||
// type NetworkPolicy
|
||||
scheme.AddValidationFunc((*NetworkPolicy)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_NetworkPolicy(ctx, op, nil /* fldPath */, obj.(*NetworkPolicy), safe.Cast[*NetworkPolicy](oldObj))
|
||||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
// type Scale
|
||||
scheme.AddValidationFunc((*Scale)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
|
|
@ -48,6 +57,155 @@ func RegisterValidations(scheme *runtime.Scheme) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Validate_IPBlock validates an instance of IPBlock according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_IPBlock(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *IPBlock) (errs field.ErrorList) {
|
||||
// field IPBlock.CIDR
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *string, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
return
|
||||
}(fldPath.Child("cidr"), &obj.CIDR, safe.Field(oldObj, func(oldObj *IPBlock) *string { return &oldObj.CIDR }), oldObj != nil)...)
|
||||
|
||||
// field IPBlock.Except has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicy validates an instance of NetworkPolicy according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicy(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicy) (errs field.ErrorList) {
|
||||
// field NetworkPolicy.TypeMeta has no validation
|
||||
// field NetworkPolicy.ObjectMeta has no validation
|
||||
|
||||
// field NetworkPolicy.Spec
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *NetworkPolicySpec, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_NetworkPolicySpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("spec"), &obj.Spec, safe.Field(oldObj, func(oldObj *NetworkPolicy) *NetworkPolicySpec { return &oldObj.Spec }), oldObj != nil)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicyEgressRule validates an instance of NetworkPolicyEgressRule according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicyEgressRule(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicyEgressRule) (errs field.ErrorList) {
|
||||
// field NetworkPolicyEgressRule.Ports has no validation
|
||||
|
||||
// field NetworkPolicyEgressRule.To
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []NetworkPolicyPeer, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyPeer)...)
|
||||
return
|
||||
}(fldPath.Child("to"), obj.To, safe.Field(oldObj, func(oldObj *NetworkPolicyEgressRule) []NetworkPolicyPeer { return oldObj.To }), oldObj != nil)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicyIngressRule validates an instance of NetworkPolicyIngressRule according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicyIngressRule(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicyIngressRule) (errs field.ErrorList) {
|
||||
// field NetworkPolicyIngressRule.Ports has no validation
|
||||
|
||||
// field NetworkPolicyIngressRule.From
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []NetworkPolicyPeer, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyPeer)...)
|
||||
return
|
||||
}(fldPath.Child("from"), obj.From, safe.Field(oldObj, func(oldObj *NetworkPolicyIngressRule) []NetworkPolicyPeer { return oldObj.From }), oldObj != nil)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicyPeer validates an instance of NetworkPolicyPeer according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicyPeer(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicyPeer) (errs field.ErrorList) {
|
||||
// field NetworkPolicyPeer.PodSelector has no validation
|
||||
// field NetworkPolicyPeer.NamespaceSelector has no validation
|
||||
|
||||
// field NetworkPolicyPeer.IPBlock
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *IPBlock, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_IPBlock(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("ipBlock"), obj.IPBlock, safe.Field(oldObj, func(oldObj *NetworkPolicyPeer) *IPBlock { return oldObj.IPBlock }), oldObj != nil)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicySpec validates an instance of NetworkPolicySpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicySpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicySpec) (errs field.ErrorList) {
|
||||
// field NetworkPolicySpec.PodSelector has no validation
|
||||
|
||||
// field NetworkPolicySpec.Ingress
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []NetworkPolicyIngressRule, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyIngressRule)...)
|
||||
return
|
||||
}(fldPath.Child("ingress"), obj.Ingress, safe.Field(oldObj, func(oldObj *NetworkPolicySpec) []NetworkPolicyIngressRule { return oldObj.Ingress }), oldObj != nil)...)
|
||||
|
||||
// field NetworkPolicySpec.Egress
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []NetworkPolicyEgressRule, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyEgressRule)...)
|
||||
return
|
||||
}(fldPath.Child("egress"), obj.Egress, safe.Field(oldObj, func(oldObj *NetworkPolicySpec) []NetworkPolicyEgressRule { return oldObj.Egress }), oldObj != nil)...)
|
||||
|
||||
// field NetworkPolicySpec.PolicyTypes has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Scale validates an instance of Scale according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Scale(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *Scale) (errs field.ErrorList) {
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ message IPAddressSpec {
|
|||
message IPBlock {
|
||||
// cidr is a string representing the IPBlock
|
||||
// Valid examples are "192.168.1.0/24" or "2001:db8::/64"
|
||||
// +required
|
||||
// +k8s:required
|
||||
optional string cidr = 1;
|
||||
|
||||
// except is a slice of CIDRs that should not be included within an IPBlock
|
||||
|
|
@ -511,6 +513,7 @@ message NetworkPolicyPeer {
|
|||
// ipBlock defines policy on a particular IPBlock. If this field is set then
|
||||
// neither of the other fields can be.
|
||||
// +optional
|
||||
// +k8s:optional
|
||||
optional IPBlock ipBlock = 3;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,8 @@ type NetworkPolicyPort struct {
|
|||
type IPBlock struct {
|
||||
// cidr is a string representing the IPBlock
|
||||
// Valid examples are "192.168.1.0/24" or "2001:db8::/64"
|
||||
// +required
|
||||
// +k8s:required
|
||||
CIDR string `json:"cidr" protobuf:"bytes,1,name=cidr"`
|
||||
|
||||
// except is a slice of CIDRs that should not be included within an IPBlock
|
||||
|
|
@ -212,6 +214,7 @@ type NetworkPolicyPeer struct {
|
|||
// ipBlock defines policy on a particular IPBlock. If this field is set then
|
||||
// neither of the other fields can be.
|
||||
// +optional
|
||||
// +k8s:optional
|
||||
IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"`
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue