github.com/kotalco/kotal@v0.3.0/apis/ethereum2/v1alpha1/beacon_node_validation_webhook.go (about) 1 package v1alpha1 2 3 import ( 4 "fmt" 5 6 apierrors "k8s.io/apimachinery/pkg/api/errors" 7 runtime "k8s.io/apimachinery/pkg/runtime" 8 "k8s.io/apimachinery/pkg/runtime/schema" 9 "k8s.io/apimachinery/pkg/util/validation/field" 10 "sigs.k8s.io/controller-runtime/pkg/webhook" 11 "sigs.k8s.io/controller-runtime/pkg/webhook/admission" 12 ) 13 14 // +kubebuilder:webhook:verbs=create;update,path=/validate-ethereum2-kotal-io-v1alpha1-beaconnode,mutating=false,failurePolicy=fail,groups=ethereum2.kotal.io,resources=beaconnodes,versions=v1alpha1,name=validate-ethereum2-v1alpha1-beaconnode.kb.io,sideEffects=None,admissionReviewVersions=v1 15 16 var _ webhook.Validator = &BeaconNode{} 17 18 // validate is the shared validate create and update logic 19 func (r *BeaconNode) validate() field.ErrorList { 20 var nodeErrors field.ErrorList 21 22 path := field.NewPath("spec") 23 24 // rest is supported by all clients except prysm 25 if r.Spec.REST && r.Spec.Client == PrysmClient { 26 err := field.Invalid(path.Child("rest"), r.Spec.REST, fmt.Sprintf("not supported by %s client", r.Spec.Client)) 27 nodeErrors = append(nodeErrors, err) 28 } 29 30 // rpc is supported by prysm only 31 if r.Spec.RPC && r.Spec.Client != PrysmClient { 32 err := field.Invalid(path.Child("rpc"), r.Spec.RPC, fmt.Sprintf("not supported by %s client", r.Spec.Client)) 33 nodeErrors = append(nodeErrors, err) 34 } 35 36 // validate verbosity level support 37 if !r.Spec.Client.SupportsVerbosityLevel(r.Spec.Logging, false) { 38 err := field.Invalid(path.Child("logging"), r.Spec.Logging, fmt.Sprintf("not supported by %s client", r.Spec.Client)) 39 nodeErrors = append(nodeErrors, err) 40 } 41 42 // grpc is supported by prysm only 43 if r.Spec.GRPC && r.Spec.Client != PrysmClient { 44 err := field.Invalid(path.Child("grpc"), r.Spec.GRPC, fmt.Sprintf("not supported by %s client", r.Spec.Client)) 45 nodeErrors = append(nodeErrors, err) 46 } 47 48 // validate cert secret name is supported by prysm only 49 if r.Spec.CertSecretName != "" && r.Spec.Client != PrysmClient { 50 err := field.Invalid(path.Child("certSecretName"), r.Spec.CertSecretName, fmt.Sprintf("not supported by %s client", r.Spec.Client)) 51 nodeErrors = append(nodeErrors, err) 52 } 53 54 // rpc is always on in prysm 55 if r.Spec.Client == PrysmClient && !r.Spec.RPC { 56 err := field.Invalid(path.Child("rpc"), r.Spec.RPC, "can't be disabled in prysm client") 57 nodeErrors = append(nodeErrors, err) 58 } 59 60 return nodeErrors 61 } 62 63 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type 64 func (r *BeaconNode) ValidateCreate() (admission.Warnings, error) { 65 var allErrors field.ErrorList 66 67 nodelog.Info("validate create", "name", r.Name) 68 69 allErrors = append(allErrors, r.validate()...) 70 allErrors = append(allErrors, r.Spec.Resources.ValidateCreate()...) 71 72 if len(allErrors) == 0 { 73 return nil, nil 74 } 75 76 return nil, apierrors.NewInvalid(schema.GroupKind{}, r.Name, allErrors) 77 78 } 79 80 // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type 81 func (r *BeaconNode) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { 82 var allErrors field.ErrorList 83 oldNode := old.(*BeaconNode) 84 path := field.NewPath("spec") 85 86 nodelog.Info("validate update", "name", r.Name) 87 88 allErrors = append(allErrors, r.validate()...) 89 allErrors = append(allErrors, r.Spec.Resources.ValidateUpdate(&oldNode.Spec.Resources)...) 90 91 if oldNode.Spec.Client != r.Spec.Client { 92 err := field.Invalid(path.Child("client"), r.Spec.Client, "field is immutable") 93 allErrors = append(allErrors, err) 94 } 95 96 if oldNode.Spec.Network != r.Spec.Network { 97 err := field.Invalid(path.Child("network"), r.Spec.Network, "field is immutable") 98 allErrors = append(allErrors, err) 99 } 100 101 if len(allErrors) == 0 { 102 return nil, nil 103 } 104 105 return nil, apierrors.NewInvalid(schema.GroupKind{}, r.Name, allErrors) 106 } 107 108 // ValidateDelete implements webhook.Validator so a webhook will be registered for the type 109 func (r *BeaconNode) ValidateDelete() (admission.Warnings, error) { 110 nodelog.Info("validate delete", "name", r.Name) 111 112 return nil, nil 113 }