diff --git a/pkg/apis/certificates/v1/zz_generated.validations.go b/pkg/apis/certificates/v1/zz_generated.validations.go index 73e28035dba..42a1716c4d9 100644 --- a/pkg/apis/certificates/v1/zz_generated.validations.go +++ b/pkg/apis/certificates/v1/zz_generated.validations.go @@ -22,7 +22,16 @@ limitations under the License. package v1 import ( + context "context" + fmt "fmt" + + certificatesv1 "k8s.io/api/certificates/v1" + 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" runtime "k8s.io/apimachinery/pkg/runtime" + field "k8s.io/apimachinery/pkg/util/validation/field" ) func init() { localSchemeBuilder.Register(RegisterValidations) } @@ -30,5 +39,91 @@ 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 { + scheme.AddValidationFunc((*certificatesv1.CertificateSigningRequest)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { + switch op.Request.SubresourcePath() { + case "/", "/approval", "/status": + return Validate_CertificateSigningRequest(ctx, op, nil /* fldPath */, obj.(*certificatesv1.CertificateSigningRequest), safe.Cast[*certificatesv1.CertificateSigningRequest](oldObj)) + } + return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} + }) + scheme.AddValidationFunc((*certificatesv1.CertificateSigningRequestList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { + switch op.Request.SubresourcePath() { + case "/": + return Validate_CertificateSigningRequestList(ctx, op, nil /* fldPath */, obj.(*certificatesv1.CertificateSigningRequestList), safe.Cast[*certificatesv1.CertificateSigningRequestList](oldObj)) + } + return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} + }) return nil } + +func Validate_CertificateSigningRequest(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *certificatesv1.CertificateSigningRequest) (errs field.ErrorList) { + // field certificatesv1.CertificateSigningRequest.TypeMeta has no validation + // field certificatesv1.CertificateSigningRequest.ObjectMeta has no validation + // field certificatesv1.CertificateSigningRequest.Spec has no validation + + // field certificatesv1.CertificateSigningRequest.Status + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *certificatesv1.CertificateSigningRequestStatus) (errs field.ErrorList) { + errs = append(errs, Validate_CertificateSigningRequestStatus(ctx, op, fldPath, obj, oldObj)...) + return + }(fldPath.Child("status"), &obj.Status, safe.Field(oldObj, func(oldObj *certificatesv1.CertificateSigningRequest) *certificatesv1.CertificateSigningRequestStatus { + return &oldObj.Status + }))...) + + return errs +} + +func Validate_CertificateSigningRequestList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *certificatesv1.CertificateSigningRequestList) (errs field.ErrorList) { + // field certificatesv1.CertificateSigningRequestList.TypeMeta has no validation + // field certificatesv1.CertificateSigningRequestList.ListMeta has no validation + + // field certificatesv1.CertificateSigningRequestList.Items + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []certificatesv1.CertificateSigningRequest) (errs field.ErrorList) { + if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil // no changes + } + errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_CertificateSigningRequest)...) + return + }(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *certificatesv1.CertificateSigningRequestList) []certificatesv1.CertificateSigningRequest { + return oldObj.Items + }))...) + + return errs +} + +var zeroOrOneOfMembershipFor_k8s_io_api_certificates_v1_CertificateSigningRequestStatus_Conditions_ = validate.NewUnionMembership([2]string{"Conditions[{\"type\": \"Approved\"}]", ""}, [2]string{"Conditions[{\"type\": \"Denied\"}]", ""}) + +func Validate_CertificateSigningRequestStatus(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *certificatesv1.CertificateSigningRequestStatus) (errs field.ErrorList) { + // field certificatesv1.CertificateSigningRequestStatus.Conditions + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []certificatesv1.CertificateSigningRequestCondition) (errs field.ErrorList) { + if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil // no changes + } + if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + return // do not proceed + } + errs = append(errs, validate.ZeroOrOneOfUnion(ctx, op, fldPath, obj, oldObj, zeroOrOneOfMembershipFor_k8s_io_api_certificates_v1_CertificateSigningRequestStatus_Conditions_, func(list []certificatesv1.CertificateSigningRequestCondition) bool { + for i := range list { + if list[i].Type == "Approved" { + return true + } + } + return false + }, func(list []certificatesv1.CertificateSigningRequestCondition) bool { + for i := range list { + if list[i].Type == "Denied" { + return true + } + } + return false + })...) + return + }(fldPath.Child("conditions"), obj.Conditions, safe.Field(oldObj, func(oldObj *certificatesv1.CertificateSigningRequestStatus) []certificatesv1.CertificateSigningRequestCondition { + return oldObj.Conditions + }))...) + + // field certificatesv1.CertificateSigningRequestStatus.Certificate has no validation + return errs +} diff --git a/pkg/apis/certificates/v1beta1/zz_generated.validations.go b/pkg/apis/certificates/v1beta1/zz_generated.validations.go index 0b9e874b635..99d3dc0267b 100644 --- a/pkg/apis/certificates/v1beta1/zz_generated.validations.go +++ b/pkg/apis/certificates/v1beta1/zz_generated.validations.go @@ -22,7 +22,16 @@ limitations under the License. package v1beta1 import ( + context "context" + fmt "fmt" + + certificatesv1beta1 "k8s.io/api/certificates/v1beta1" + 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" runtime "k8s.io/apimachinery/pkg/runtime" + field "k8s.io/apimachinery/pkg/util/validation/field" ) func init() { localSchemeBuilder.Register(RegisterValidations) } @@ -30,5 +39,91 @@ 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 { + scheme.AddValidationFunc((*certificatesv1beta1.CertificateSigningRequest)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { + switch op.Request.SubresourcePath() { + case "/", "/approval", "/status": + return Validate_CertificateSigningRequest(ctx, op, nil /* fldPath */, obj.(*certificatesv1beta1.CertificateSigningRequest), safe.Cast[*certificatesv1beta1.CertificateSigningRequest](oldObj)) + } + return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} + }) + scheme.AddValidationFunc((*certificatesv1beta1.CertificateSigningRequestList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { + switch op.Request.SubresourcePath() { + case "/": + return Validate_CertificateSigningRequestList(ctx, op, nil /* fldPath */, obj.(*certificatesv1beta1.CertificateSigningRequestList), safe.Cast[*certificatesv1beta1.CertificateSigningRequestList](oldObj)) + } + return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} + }) return nil } + +func Validate_CertificateSigningRequest(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *certificatesv1beta1.CertificateSigningRequest) (errs field.ErrorList) { + // field certificatesv1beta1.CertificateSigningRequest.TypeMeta has no validation + // field certificatesv1beta1.CertificateSigningRequest.ObjectMeta has no validation + // field certificatesv1beta1.CertificateSigningRequest.Spec has no validation + + // field certificatesv1beta1.CertificateSigningRequest.Status + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *certificatesv1beta1.CertificateSigningRequestStatus) (errs field.ErrorList) { + errs = append(errs, Validate_CertificateSigningRequestStatus(ctx, op, fldPath, obj, oldObj)...) + return + }(fldPath.Child("status"), &obj.Status, safe.Field(oldObj, func(oldObj *certificatesv1beta1.CertificateSigningRequest) *certificatesv1beta1.CertificateSigningRequestStatus { + return &oldObj.Status + }))...) + + return errs +} + +func Validate_CertificateSigningRequestList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *certificatesv1beta1.CertificateSigningRequestList) (errs field.ErrorList) { + // field certificatesv1beta1.CertificateSigningRequestList.TypeMeta has no validation + // field certificatesv1beta1.CertificateSigningRequestList.ListMeta has no validation + + // field certificatesv1beta1.CertificateSigningRequestList.Items + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []certificatesv1beta1.CertificateSigningRequest) (errs field.ErrorList) { + if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil // no changes + } + errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_CertificateSigningRequest)...) + return + }(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *certificatesv1beta1.CertificateSigningRequestList) []certificatesv1beta1.CertificateSigningRequest { + return oldObj.Items + }))...) + + return errs +} + +var zeroOrOneOfMembershipFor_k8s_io_api_certificates_v1beta1_CertificateSigningRequestStatus_Conditions_ = validate.NewUnionMembership([2]string{"Conditions[{\"type\": \"Approved\"}]", ""}, [2]string{"Conditions[{\"type\": \"Denied\"}]", ""}) + +func Validate_CertificateSigningRequestStatus(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *certificatesv1beta1.CertificateSigningRequestStatus) (errs field.ErrorList) { + // field certificatesv1beta1.CertificateSigningRequestStatus.Conditions + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []certificatesv1beta1.CertificateSigningRequestCondition) (errs field.ErrorList) { + if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil // no changes + } + if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + return // do not proceed + } + errs = append(errs, validate.ZeroOrOneOfUnion(ctx, op, fldPath, obj, oldObj, zeroOrOneOfMembershipFor_k8s_io_api_certificates_v1beta1_CertificateSigningRequestStatus_Conditions_, func(list []certificatesv1beta1.CertificateSigningRequestCondition) bool { + for i := range list { + if list[i].Type == "Approved" { + return true + } + } + return false + }, func(list []certificatesv1beta1.CertificateSigningRequestCondition) bool { + for i := range list { + if list[i].Type == "Denied" { + return true + } + } + return false + })...) + return + }(fldPath.Child("conditions"), obj.Conditions, safe.Field(oldObj, func(oldObj *certificatesv1beta1.CertificateSigningRequestStatus) []certificatesv1beta1.CertificateSigningRequestCondition { + return oldObj.Conditions + }))...) + + // field certificatesv1beta1.CertificateSigningRequestStatus.Certificate has no validation + return errs +} diff --git a/staging/src/k8s.io/api/certificates/v1/types.go b/staging/src/k8s.io/api/certificates/v1/types.go index ba8009840d8..71203e80d55 100644 --- a/staging/src/k8s.io/api/certificates/v1/types.go +++ b/staging/src/k8s.io/api/certificates/v1/types.go @@ -39,6 +39,8 @@ import ( // This API can be used to request client certificates to authenticate to kube-apiserver // (with the "kubernetes.io/kube-apiserver-client" signerName), // or to obtain certificates from custom non-Kubernetes signers. +// +k8s:supportsSubresource=/status +// +k8s:supportsSubresource=/approval type CertificateSigningRequest struct { metav1.TypeMeta `json:",inline"` // +optional @@ -178,6 +180,11 @@ type CertificateSigningRequestStatus struct { // +listType=map // +listMapKey=type // +optional + // +k8s:listType=map + // +k8s:listMapKey=type + // +k8s:optional + // +k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember + // +k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember Conditions []CertificateSigningRequestCondition `json:"conditions,omitempty" protobuf:"bytes,1,rep,name=conditions"` // certificate is populated with an issued certificate by the signer after an Approved condition is present. diff --git a/staging/src/k8s.io/api/certificates/v1beta1/types.go b/staging/src/k8s.io/api/certificates/v1beta1/types.go index 1ce104807dd..fadb7e082ef 100644 --- a/staging/src/k8s.io/api/certificates/v1beta1/types.go +++ b/staging/src/k8s.io/api/certificates/v1beta1/types.go @@ -31,6 +31,8 @@ import ( // +k8s:prerelease-lifecycle-gen:replacement=certificates.k8s.io,v1,CertificateSigningRequest // Describes a certificate signing request +// +k8s:supportsSubresource=/status +// +k8s:supportsSubresource=/approval type CertificateSigningRequest struct { metav1.TypeMeta `json:",inline"` // +optional @@ -175,6 +177,11 @@ type CertificateSigningRequestStatus struct { // +listType=map // +listMapKey=type // +optional + // +k8s:listType=map + // +k8s:listMapKey=type + // +k8s:optional + // +k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember + // +k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember Conditions []CertificateSigningRequestCondition `json:"conditions,omitempty" protobuf:"bytes,1,rep,name=conditions"` // If request was approved, the controller will place the issued certificate here.