diff --git a/hack/generated/pkg/genruntime/admissions.go b/hack/generated/pkg/genruntime/admissions.go new file mode 100644 index 00000000000..59c3245cf0f --- /dev/null +++ b/hack/generated/pkg/genruntime/admissions.go @@ -0,0 +1,28 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + +package genruntime + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +// Validator is similar to controller-runtime/pkg/webhook/admission Validator. Implementing this interface +// allows you to hook into the code generated validations and add custom handcrafted validations. +type Validator interface { + // CreateValidations returns validation functions that should be run on create. + CreateValidations() []func() error + // UpdateValidations returns validation functions that should be run on update. + UpdateValidations() []func(old runtime.Object) error + // DeleteValidations returns validation functions taht should be run on delete. + DeleteValidations() []func() error +} + +// Defaulter is similar to controller-runtime/pkg/webhook/admission Defaulter. Implementing this interface +// allows you to hook into the code generated defaults and add custom handcrafted defaults. +type Defaulter interface { + // CustomDefault performs custom defaults that are run in addition to the code generated defaults. + CustomDefault() +} diff --git a/hack/generator/pkg/astbuilder/assignments.go b/hack/generator/pkg/astbuilder/assignments.go index d691dad3c60..afbdd83a482 100644 --- a/hack/generator/pkg/astbuilder/assignments.go +++ b/hack/generator/pkg/astbuilder/assignments.go @@ -42,3 +42,26 @@ func SimpleAssignmentWithErr(lhs dst.Expr, tok token.Token, rhs dst.Expr) *dst.A }, } } + +// AssignToInterface performs an assignment of a well-typed variable to an interface{}. This is usually used to +// perform a type assertion on a concrete type in a subsequent statement (which Go doesn't allow, it only allows type +// assertions on interface types). +// var interface{} = +func AssignToInterface(lhsVar string, rhs dst.Expr) *dst.DeclStmt { + return &dst.DeclStmt{ + Decl: &dst.GenDecl{ + Tok: token.VAR, + Specs: []dst.Spec{ + &dst.ValueSpec{ + Names: []*dst.Ident{ + dst.NewIdent(lhsVar), + }, + Type: dst.NewIdent("interface{}"), + Values: []dst.Expr{ + dst.Clone(rhs).(dst.Expr), + }, + }, + }, + }, + } +} diff --git a/hack/generator/pkg/astbuilder/builder.go b/hack/generator/pkg/astbuilder/builder.go index 80dad1bd9b8..b05ecac867b 100644 --- a/hack/generator/pkg/astbuilder/builder.go +++ b/hack/generator/pkg/astbuilder/builder.go @@ -22,6 +22,20 @@ func CheckErrorAndReturn(otherReturns ...dst.Expr) dst.Stmt { returnValues := append([]dst.Expr{}, cloneExprSlice(otherReturns)...) returnValues = append(returnValues, dst.NewIdent("err")) + retStmt := &dst.ReturnStmt{ + Results: returnValues, + } + + return CheckErrorAndSingleStatement(retStmt) +} + +// CheckErrorAndSingleStatement checks if the err is non-nil, and if it is executes the provided statement. +// +// if err != nil { +// +// } +func CheckErrorAndSingleStatement(stmt dst.Stmt) dst.Stmt { + return &dst.IfStmt{ Cond: &dst.BinaryExpr{ X: dst.NewIdent("err"), @@ -30,9 +44,7 @@ func CheckErrorAndReturn(otherReturns ...dst.Expr) dst.Stmt { }, Body: &dst.BlockStmt{ List: []dst.Stmt{ - &dst.ReturnStmt{ - Results: returnValues, - }, + stmt, }, }, } diff --git a/hack/generator/pkg/astbuilder/calls.go b/hack/generator/pkg/astbuilder/calls.go index 965ae08e01c..35d2a5e88bf 100644 --- a/hack/generator/pkg/astbuilder/calls.go +++ b/hack/generator/pkg/astbuilder/calls.go @@ -13,7 +13,7 @@ import ( // // (...) // -func CallFunc(funcName string, arguments ...dst.Expr) dst.Expr { +func CallFunc(funcName string, arguments ...dst.Expr) *dst.CallExpr { return &dst.CallExpr{ Fun: dst.NewIdent(funcName), Args: cloneExprSlice(arguments), @@ -25,7 +25,7 @@ func CallFunc(funcName string, arguments ...dst.Expr) dst.Expr { // // .(arguments...) // -func CallQualifiedFunc(qualifier string, funcName string, arguments ...dst.Expr) dst.Expr { +func CallQualifiedFunc(qualifier string, funcName string, arguments ...dst.Expr) *dst.CallExpr { return &dst.CallExpr{ Fun: &dst.SelectorExpr{ X: dst.NewIdent(qualifier), diff --git a/hack/generator/pkg/astmodel/arm_spec_interface.go b/hack/generator/pkg/astmodel/arm_spec_interface.go index 53c3db3d6fd..c4493dd4a0e 100644 --- a/hack/generator/pkg/astmodel/arm_spec_interface.go +++ b/hack/generator/pkg/astmodel/arm_spec_interface.go @@ -53,24 +53,27 @@ func NewARMSpecInterfaceImpl( } getNameFunc := &objectFunction{ - name: "GetName", - o: spec, - idFactory: idFactory, - asFunc: getNameFunction, + name: "GetName", + o: spec, + idFactory: idFactory, + asFunc: getNameFunction, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference), } getTypeFunc := &objectFunction{ - name: "GetType", - o: spec, - idFactory: idFactory, - asFunc: getTypeFunction, + name: "GetType", + o: spec, + idFactory: idFactory, + asFunc: getTypeFunction, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference), } getApiVersionFunc := &objectFunction{ - name: "GetApiVersion", - o: spec, - idFactory: idFactory, - asFunc: getApiVersionFunction, + name: "GetApiVersion", + o: spec, + idFactory: idFactory, + asFunc: getApiVersionFunction, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference), } result := NewInterfaceImplementation( diff --git a/hack/generator/pkg/astmodel/file_definition.go b/hack/generator/pkg/astmodel/file_definition.go index 9185ad6ab4c..3c7120f8358 100644 --- a/hack/generator/pkg/astmodel/file_definition.go +++ b/hack/generator/pkg/astmodel/file_definition.go @@ -139,6 +139,7 @@ func (file *FileDefinition) generateImports() *PackageImportSet { // TODO: Make this configurable requiredImports.ApplyName(MetaV1PackageReference, "metav1") + requiredImports.ApplyName(APIMachineryErrorsReference, "kerrors") // Force local imports to have explicit names based on the service for _, imp := range requiredImports.AsSlice() { diff --git a/hack/generator/pkg/astmodel/function.go b/hack/generator/pkg/astmodel/function.go index 3aacc7ac46f..d9208e74ed2 100644 --- a/hack/generator/pkg/astmodel/function.go +++ b/hack/generator/pkg/astmodel/function.go @@ -27,3 +27,93 @@ type Function interface { // Equals determines if this Function is equal to another one Equals(f Function) bool } + +var _ Function = &objectFunction{} + +type objectFunctionHandler func(f *objectFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl + +// objectFunction is a simple helper that implements the Function interface. It is intended for use for functions +// that only need information about the object they are operating on +type objectFunction struct { + name string + o *ObjectType + idFactory IdentifierFactory + asFunc objectFunctionHandler + requiredPackages *PackageReferenceSet +} + +// Name returns the unique name of this function +// (You can't have two functions with the same name on the same object or resource) +func (k *objectFunction) Name() string { + return k.name +} + +// RequiredPackageReferences returns the set of required packages for this function +func (k *objectFunction) RequiredPackageReferences() *PackageReferenceSet { + return k.requiredPackages +} + +// References returns the TypeName's referenced by this function +func (k *objectFunction) References() TypeNameSet { + return k.o.References() +} + +// AsFunc renders the current instance as a Go abstract syntax tree +func (k *objectFunction) AsFunc(codeGenerationContext *CodeGenerationContext, receiver TypeName) *dst.FuncDecl { + return k.asFunc(k, codeGenerationContext, receiver, k.name) +} + +// Equals checks if this function is equal to the passed in function +func (k *objectFunction) Equals(f Function) bool { + typedF, ok := f.(*objectFunction) + if !ok { + return false + } + + // TODO: We're not actually checking function structure here + return k.o.Equals(typedF.o) && k.name == typedF.name +} + +type resourceFunctionHandler func(f *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl + +// resourceFunction is a simple helper that implements the Function interface. It is intended for use for functions +// that only need information about the resource they are operating on +type resourceFunction struct { + name string + resource *ResourceType + idFactory IdentifierFactory + asFunc resourceFunctionHandler + requiredPackages *PackageReferenceSet +} + +// Name returns the unique name of this function +// (You can't have two functions with the same name on the same object or resource) +func (r *resourceFunction) Name() string { + return r.name +} + +// RequiredPackageReferences returns the set of required packages for this function +func (r *resourceFunction) RequiredPackageReferences() *PackageReferenceSet { + return r.requiredPackages +} + +// References returns the TypeName's referenced by this function +func (r *resourceFunction) References() TypeNameSet { + return r.resource.References() +} + +// AsFunc renders the current instance as a Go abstract syntax tree +func (r *resourceFunction) AsFunc(codeGenerationContext *CodeGenerationContext, receiver TypeName) *dst.FuncDecl { + return r.asFunc(r, codeGenerationContext, receiver, r.name) +} + +// Equals determines if this Function is equal to another one +func (r *resourceFunction) Equals(f Function) bool { + typedF, ok := f.(*resourceFunction) + if !ok { + return false + } + + // TODO: We're not actually checking function structure here + return r.resource.Equals(typedF.resource) && r.name == typedF.name +} diff --git a/hack/generator/pkg/astmodel/kubernetes_admissions_defaulter.go b/hack/generator/pkg/astmodel/kubernetes_admissions_defaulter.go new file mode 100644 index 00000000000..0bd36447e59 --- /dev/null +++ b/hack/generator/pkg/astmodel/kubernetes_admissions_defaulter.go @@ -0,0 +1,171 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + +package astmodel + +import ( + "fmt" + "strings" + + "github.com/dave/dst" + + "github.com/Azure/azure-service-operator/hack/generator/pkg/astbuilder" +) + +var DefaulterInterfaceName = MakeTypeName(ControllerRuntimeAdmission, "Defaulter") +var GenRuntimeDefaulterInterfaceName = MakeTypeName(GenRuntimeReference, "Defaulter") + +// DefaulterBuilder helps in building an interface implementation for admissions.Defaulter. +type DefaulterBuilder struct { + resourceName TypeName + resource *ResourceType + idFactory IdentifierFactory + + defaults []*resourceFunction +} + +// NewDefaulterBuilder creates a new DefaulterBuilder for the given object type. +func NewDefaulterBuilder(resourceName TypeName, resource *ResourceType, idFactory IdentifierFactory) *DefaulterBuilder { + return &DefaulterBuilder{ + resourceName: resourceName, + resource: resource, + idFactory: idFactory, + } +} + +// AddDefault adds an additional default function to the set of default functions to be applied to the given object +func (d *DefaulterBuilder) AddDefault(f *resourceFunction) { + if !d.resource.Equals(f.resource) { + panic("cannot add default function on non-matching object types") + } + d.defaults = append(d.defaults, f) +} + +// ToInterfaceImplementation creates an InterfaceImplementation that implements the admissions.Defaulter interface. +// This implementation includes calls to all defaults registered with this DefaulterBuilder via the AddDefault function, +// as well as helper functions that allow additional handcrafted defaults to be injected by +// implementing the genruntime.Defaulter interface. +func (d *DefaulterBuilder) ToInterfaceImplementation() *InterfaceImplementation { + lpr, ok := d.resourceName.PackageReference.AsLocalPackage() + if !ok { + panic(fmt.Sprintf("expected resource name %s to be a local package reference", d.resourceName.String())) + } + + group := lpr.group // e.g. "microsoft.network.infra.azure.com" + resource := d.resourceName.Name() // e.g. "backendaddresspools" + version := lpr.version // e.g. "v1" + + group = strings.ToLower(group + GroupSuffix) + nonPluralResource := strings.ToLower(resource) + resource = strings.ToLower(d.resourceName.Plural().Name()) + + // e.g. "mutate-microsoft-network-infra-azure-com-v1-backendaddresspool" + // note that this must match _exactly_ how controller-runtime generates the path + // or it will not work! + path := fmt.Sprintf("/mutate-%s-%s-%s", strings.ReplaceAll(group, ".", "-"), version, nonPluralResource) + + // e.g. "default.v123.backendaddresspool.infra.azure.com" + name := fmt.Sprintf("default.%s.%s.%s", version, resource, group) + + annotation := fmt.Sprintf( + "+kubebuilder:webhook:path=%s,mutating=true,sideEffects=None,"+ + "matchPolicy=Exact,failurePolicy=fail,groups=%s,resources=%s,"+ + "verbs=create;update,versions=%s,name=%s,admissionReviewVersions=v1beta1", // admission review version v1 is not yet supported by controller-runtime + path, + group, + resource, + version, + name) + + funcs := []Function{ + &resourceFunction{ + name: "Default", + resource: d.resource, + idFactory: d.idFactory, + asFunc: d.defaultFunction, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference), + }, + &resourceFunction{ + name: "defaultImpl", + resource: d.resource, + idFactory: d.idFactory, + asFunc: d.localDefault, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference), + }, + } + + // Add the actual individual default functions + for _, def := range d.defaults { + funcs = append(funcs, def) + } + + return NewInterfaceImplementation( + DefaulterInterfaceName, + funcs...).WithAnnotation(annotation) +} + +func (d *DefaulterBuilder) localDefault(k *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { + receiverIdent := k.idFactory.CreateIdentifier(receiver.Name(), NotExported) + receiverType := receiver.AsType(codeGenerationContext) + + var defaults []dst.Stmt + for _, def := range d.defaults { + defaults = append( + defaults, + &dst.ExprStmt{ + X: astbuilder.CallQualifiedFunc(receiverIdent, def.name), + }) + } + + fn := &astbuilder.FuncDetails{ + Name: methodName, + ReceiverIdent: receiverIdent, + ReceiverType: &dst.StarExpr{ + X: receiverType, + }, + Body: defaults, + } + + fn.AddComments(fmt.Sprintf("applies the code generated defaults to the %s resource", receiver.Name())) + return fn.DefineFunc() +} + +func (d *DefaulterBuilder) defaultFunction(k *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { + receiverIdent := k.idFactory.CreateIdentifier(receiver.Name(), NotExported) + receiverType := receiver.AsType(codeGenerationContext) + tempVarIdent := "temp" + runtimeDefaulterIdent := "runtimeDefaulter" + + overrideInterfaceType := GenRuntimeDefaulterInterfaceName.AsType(codeGenerationContext) + + fn := &astbuilder.FuncDetails{ + Name: methodName, + ReceiverIdent: receiverIdent, + ReceiverType: &dst.StarExpr{ + X: receiverType, + }, + Body: []dst.Stmt{ + &dst.ExprStmt{ + X: astbuilder.CallQualifiedFunc(receiverIdent, "defaultImpl"), // TODO: This part should maybe be conditional if there are no defaults to define? + }, + astbuilder.AssignToInterface(tempVarIdent, dst.NewIdent(receiverIdent)), + &dst.IfStmt{ + Init: astbuilder.TypeAssert( + dst.NewIdent(runtimeDefaulterIdent), + dst.NewIdent(tempVarIdent), + overrideInterfaceType), + Cond: dst.NewIdent("ok"), + Body: &dst.BlockStmt{ + List: []dst.Stmt{ + astbuilder.InvokeQualifiedFunc(runtimeDefaulterIdent, "CustomDefault"), + }, + }, + }, + }, + } + + fn.AddComments(fmt.Sprintf("applies defaults to the %s resource", receiver.Name())) + return fn.DefineFunc() +} diff --git a/hack/generator/pkg/astmodel/kubernetes_admissions_defaults.go b/hack/generator/pkg/astmodel/kubernetes_admissions_defaults.go new file mode 100644 index 00000000000..0dfcddd75c1 --- /dev/null +++ b/hack/generator/pkg/astmodel/kubernetes_admissions_defaults.go @@ -0,0 +1,71 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + +package astmodel + +import ( + "go/token" + + "github.com/dave/dst" + + "github.com/Azure/azure-service-operator/hack/generator/pkg/astbuilder" +) + +func NewDefaultAzureNameFunction(resource *ResourceType, idFactory IdentifierFactory) *resourceFunction { + return &resourceFunction{ + name: "defaultAzureName", + resource: resource, + idFactory: idFactory, + asFunc: defaultAzureNameFunction, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference), + } +} + +// defaultAzureNameFunction returns a function that defaults the AzureName property of the resource spec +// to the Name property of the resource spec +func defaultAzureNameFunction(k *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { + receiverIdent := k.idFactory.CreateIdentifier(receiver.Name(), NotExported) + receiverType := receiver.AsType(codeGenerationContext) + + specSelector := &dst.SelectorExpr{ + X: dst.NewIdent(receiverIdent), + Sel: dst.NewIdent("Spec"), + } + + azureNameProp := &dst.SelectorExpr{ + X: specSelector, + Sel: dst.NewIdent(AzureNameProperty), + } + + nameProp := &dst.SelectorExpr{ + X: dst.NewIdent(receiverIdent), + Sel: dst.NewIdent("Name"), // this comes from ObjectMeta + } + + fn := &astbuilder.FuncDetails{ + Name: methodName, + ReceiverIdent: receiverIdent, + ReceiverType: &dst.StarExpr{ + X: receiverType, + }, + Body: []dst.Stmt{ + &dst.IfStmt{ + Cond: &dst.BinaryExpr{ + X: dst.Clone(azureNameProp).(dst.Expr), + Op: token.EQL, + Y: &dst.BasicLit{Kind: token.STRING, Value: "\"\""}, + }, + Body: astbuilder.StatementBlock( + astbuilder.SimpleAssignment( + azureNameProp, + token.ASSIGN, + nameProp)), + }, + }, + } + + fn.AddComments("defaults the Azure name of the resource to the Kubernetes name") + return fn.DefineFunc() +} diff --git a/hack/generator/pkg/astmodel/kubernetes_admissions_validator.go b/hack/generator/pkg/astmodel/kubernetes_admissions_validator.go new file mode 100644 index 00000000000..d3259aa45fc --- /dev/null +++ b/hack/generator/pkg/astmodel/kubernetes_admissions_validator.go @@ -0,0 +1,392 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + +package astmodel + +import ( + "fmt" + "go/token" + "strings" + + "github.com/dave/dst" + + "github.com/Azure/azure-service-operator/hack/generator/pkg/astbuilder" +) + +var ValidatorInterfaceName = MakeTypeName(ControllerRuntimeAdmission, "Validator") +var GenRuntimeValidatorInterfaceName = MakeTypeName(GenRuntimeReference, "Validator") + +// ValidationKind determines when a particular validation should be run +type ValidationKind string + +const ( + ValidationKindCreate = ValidationKind("Create") + ValidationKindUpdate = ValidationKind("Update") + ValidationKindDelete = ValidationKind("Delete") +) + +// ValidatorBuilder helps in building an interface implementation for admissions.Validator. +type ValidatorBuilder struct { + resourceName TypeName + resource *ResourceType + idFactory IdentifierFactory + + validations map[ValidationKind][]*resourceFunction +} + +// NewValidatorBuilder creates a new ValidatorBuilder for the given object type. +func NewValidatorBuilder(resourceName TypeName, resource *ResourceType, idFactory IdentifierFactory) *ValidatorBuilder { + return &ValidatorBuilder{ + resourceName: resourceName, + resource: resource, + idFactory: idFactory, + validations: map[ValidationKind][]*resourceFunction{ + ValidationKindCreate: nil, + ValidationKindUpdate: nil, + ValidationKindDelete: nil, + }, + } +} + +// AddValidation adds an additional validation function to the set of validation functions to be applied to the given object. +func (v *ValidatorBuilder) AddValidation(kind ValidationKind, f *resourceFunction) { + if !v.resource.Equals(f.resource) { + panic("cannot add validation function on non-matching object types") + } + v.validations[kind] = append(v.validations[kind], f) +} + +// ToInterfaceImplementation creates an InterfaceImplementation that implements the admissions.Validator interface. +// This implementation includes calls to all validations registered with this ValidatorBuilder via the AddValidation function, +// as well as helper functions that allow additional handcrafted validations to be injected by +// implementing the genruntime.Validator interface. +func (v *ValidatorBuilder) ToInterfaceImplementation() *InterfaceImplementation { + lpr, ok := v.resourceName.PackageReference.AsLocalPackage() + if !ok { + panic(fmt.Sprintf("expected resource name %s to be a local package reference", v.resourceName.String())) + } + + group := lpr.group // e.g. "microsoft.network.infra.azure.com" + resource := v.resourceName.Name() // e.g. "backendaddresspools" + version := lpr.version // e.g. "v1" + + group = strings.ToLower(group + GroupSuffix) + nonPluralResource := strings.ToLower(resource) + resource = strings.ToLower(v.resourceName.Plural().Name()) + + // e.g. "validate-microsoft-network-infra-azure-com-v1-backendaddresspool" + // note that this must match _exactly_ how controller-runtime generates the path + // or it will not work! + path := fmt.Sprintf("/validate-%s-%s-%s", strings.ReplaceAll(group, ".", "-"), version, nonPluralResource) + + // e.g. "default.v123.backendaddresspool.infra.azure.com" + name := fmt.Sprintf("validate.%s.%s.%s", version, resource, group) + + annotation := fmt.Sprintf( + "+kubebuilder:webhook:path=%s,mutating=false,sideEffects=None,"+ + "matchPolicy=Exact,failurePolicy=fail,groups=%s,resources=%s,"+ + "verbs=create;update,versions=%s,name=%s,admissionReviewVersions=v1beta1", // admission review version v1 is not yet supported by controller-runtime + path, + group, + resource, + version, + name) + + funcs := []Function{ + &resourceFunction{ + name: "ValidateCreate", + resource: v.resource, + idFactory: v.idFactory, + asFunc: v.validateCreate, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference, APIMachineryErrorsReference, APIMachineryRuntimeReference), + }, + &resourceFunction{ + name: "ValidateUpdate", + resource: v.resource, + idFactory: v.idFactory, + asFunc: v.validateUpdate, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference, APIMachineryErrorsReference, APIMachineryRuntimeReference), + }, + &resourceFunction{ + name: "ValidateDelete", + resource: v.resource, + idFactory: v.idFactory, + asFunc: v.validateDelete, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference, APIMachineryErrorsReference, APIMachineryRuntimeReference), + }, + &resourceFunction{ + name: "createValidations", + resource: v.resource, + idFactory: v.idFactory, + asFunc: v.localCreateValidations, + requiredPackages: NewPackageReferenceSet(), + }, + &resourceFunction{ + name: "updateValidations", + resource: v.resource, + idFactory: v.idFactory, + asFunc: v.localUpdateValidations, + requiredPackages: NewPackageReferenceSet(), + }, + &resourceFunction{ + name: "deleteValidations", + resource: v.resource, + idFactory: v.idFactory, + asFunc: v.localDeleteValidations, + requiredPackages: NewPackageReferenceSet(), + }, + } + + // Add the actual individual validation functions + for _, validations := range v.validations { + for _, validation := range validations { + funcs = append(funcs, validation) + } + } + + return NewInterfaceImplementation( + ValidatorInterfaceName, + funcs..., + ).WithAnnotation(annotation) +} + +// validateCreate returns a function that performs validation of creation for the resource +func (v *ValidatorBuilder) validateCreate(k *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { + receiverIdent := k.idFactory.CreateIdentifier(receiver.Name(), NotExported) + receiverType := receiver.AsType(codeGenerationContext) + + fn := &astbuilder.FuncDetails{ + Name: methodName, + ReceiverIdent: receiverIdent, + ReceiverType: &dst.StarExpr{ + X: receiverType, + }, + Returns: []*dst.Field{ + { + Type: dst.NewIdent("error"), + }, + }, + Body: v.validateBody(codeGenerationContext, receiverIdent, "createValidations", "CreateValidations", ""), + } + + fn.AddComments("validates the creation of the resource") + return fn.DefineFunc() +} + +// validateUpdate returns a function that performs validation of update for the resource +func (v *ValidatorBuilder) validateUpdate(k *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { + receiverIdent := k.idFactory.CreateIdentifier(receiver.Name(), NotExported) + receiverType := receiver.AsType(codeGenerationContext) + + retType := getValidationFuncType(ValidationKindUpdate, codeGenerationContext) + + fn := &astbuilder.FuncDetails{ + Name: methodName, + Params: retType.Params.List, + ReceiverIdent: receiverIdent, + ReceiverType: &dst.StarExpr{ + X: receiverType, + }, + Returns: retType.Results.List, + Body: v.validateBody(codeGenerationContext, receiverIdent, "updateValidations", "UpdateValidations", "old"), + } + + fn.AddComments("validates an update of the resource") + return fn.DefineFunc() +} + +// validateDelete returns a function that performs validation of deletion for the resource +func (v *ValidatorBuilder) validateDelete(k *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { + receiverIdent := k.idFactory.CreateIdentifier(receiver.Name(), NotExported) + receiverType := receiver.AsType(codeGenerationContext) + + fn := &astbuilder.FuncDetails{ + Name: methodName, + ReceiverIdent: receiverIdent, + ReceiverType: &dst.StarExpr{ + X: receiverType, + }, + Returns: []*dst.Field{ + { + Type: dst.NewIdent("error"), + }, + }, + Body: v.validateBody(codeGenerationContext, receiverIdent, "deleteValidations", "DeleteValidations", ""), + } + + fn.AddComments("validates the deletion of the resource") + return fn.DefineFunc() +} + +func (v *ValidatorBuilder) validateBody(codeGenerationContext *CodeGenerationContext, receiverIdent string, implFunctionName string, overrideFunctionName string, funcParamIdent string) []dst.Stmt { + kErrors, err := codeGenerationContext.GetImportedPackageName(APIMachineryErrorsReference) + if err != nil { + panic(err) + } + + overrideInterfaceType := GenRuntimeValidatorInterfaceName.AsType(codeGenerationContext) + + validationsIdent := "validations" + validationIdent := "validation" + tempVarIdent := "temp" + runtimeValidatorIdent := "runtimeValidator" + errsIdent := "errs" + + var args []dst.Expr + if funcParamIdent != "" { + args = append(args, dst.NewIdent(funcParamIdent)) + } + + // TODO: This loop (and possibly some of the other body stuff below) could be done in a generic method written in + // TODO: genruntime -- thoughts? + validationLoop := &dst.RangeStmt{ + Key: dst.NewIdent("_"), + Value: dst.NewIdent(validationIdent), + X: dst.NewIdent(validationsIdent), + Tok: token.DEFINE, + Body: &dst.BlockStmt{ + List: []dst.Stmt{ + astbuilder.SimpleAssignment(dst.NewIdent("err"), token.DEFINE, astbuilder.CallFunc(validationIdent, args...)), + astbuilder.CheckErrorAndSingleStatement(astbuilder.AppendList(dst.NewIdent(errsIdent), dst.NewIdent("err"))), + }, + }, + } + + hack := astbuilder.CallQualifiedFunc(runtimeValidatorIdent, overrideFunctionName) + hack.Ellipsis = true + + appendFuncCall := astbuilder.CallFunc("append", dst.NewIdent(validationsIdent), astbuilder.CallQualifiedFunc(runtimeValidatorIdent, overrideFunctionName)) + appendFuncCall.Ellipsis = true + + body := []dst.Stmt{ + astbuilder.SimpleAssignment( + dst.NewIdent(validationsIdent), + token.DEFINE, + astbuilder.CallQualifiedFunc(receiverIdent, implFunctionName)), + astbuilder.AssignToInterface(tempVarIdent, dst.NewIdent(receiverIdent)), + &dst.IfStmt{ + Init: astbuilder.TypeAssert( + dst.NewIdent(runtimeValidatorIdent), + dst.NewIdent(tempVarIdent), + overrideInterfaceType), + Cond: dst.NewIdent("ok"), + Body: &dst.BlockStmt{ + List: []dst.Stmt{ + // Not using astbuilder.AppendList here as we want to tack on a "..." at the end + astbuilder.SimpleAssignment( + dst.NewIdent(validationsIdent), + token.ASSIGN, + appendFuncCall), + }, + }, + }, + astbuilder.LocalVariableDeclaration(errsIdent, &dst.ArrayType{Elt: dst.NewIdent("error")}, ""), + validationLoop, + astbuilder.Returns(astbuilder.CallQualifiedFunc(kErrors, "NewAggregate", dst.NewIdent(errsIdent))), + } + + return body +} + +func (v *ValidatorBuilder) localCreateValidations(_ *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { + fn := v.makeLocalValidationFuncDetails(ValidationKindCreate, codeGenerationContext, receiver, methodName) + fn.AddComments("validates the creation of the resource") + return fn.DefineFunc() +} + +func (v *ValidatorBuilder) localUpdateValidations(_ *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { + fn := v.makeLocalValidationFuncDetails(ValidationKindUpdate, codeGenerationContext, receiver, methodName) + fn.AddComments("validates the update of the resource") + return fn.DefineFunc() +} + +func (v *ValidatorBuilder) localDeleteValidations(_ *resourceFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { + fn := v.makeLocalValidationFuncDetails(ValidationKindDelete, codeGenerationContext, receiver, methodName) + fn.AddComments("validates the deletion of the resource") + return fn.DefineFunc() +} + +func (v *ValidatorBuilder) makeLocalValidationFuncDetails(kind ValidationKind, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *astbuilder.FuncDetails { + receiverIdent := v.idFactory.CreateIdentifier(receiver.Name(), NotExported) + receiverType := receiver.AsType(codeGenerationContext) + + return &astbuilder.FuncDetails{ + Name: methodName, + ReceiverIdent: receiverIdent, + ReceiverType: &dst.StarExpr{ + X: receiverType, + }, + Returns: []*dst.Field{ + { + Type: &dst.ArrayType{ + Elt: getValidationFuncType(kind, codeGenerationContext), + }, + }, + }, + Body: v.localValidationFuncBody(kind, codeGenerationContext, receiverIdent), + } +} + +func (v *ValidatorBuilder) localValidationFuncBody(kind ValidationKind, codeGenerationContext *CodeGenerationContext, receiverIdent string) []dst.Stmt { + var elements []dst.Expr + for _, validationFunc := range v.validations[kind] { + elements = append(elements, astbuilder.Selector(dst.NewIdent(receiverIdent), validationFunc.name)) + } + + if len(elements) == 0 { + return []dst.Stmt{astbuilder.Returns(dst.NewIdent("nil"))} + } + + returnStmt := astbuilder.Returns(&dst.CompositeLit{ + Type: &dst.ArrayType{ + Elt: getValidationFuncType(kind, codeGenerationContext), + }, + Elts: elements, + }) + + return []dst.Stmt{returnStmt} +} + +func getValidationFuncType(kind ValidationKind, codeGenerationContext *CodeGenerationContext) *dst.FuncType { + runtime, err := codeGenerationContext.GetImportedPackageName(APIMachineryRuntimeReference) + if err != nil { + panic(err) + } + + if kind == ValidationKindUpdate { + return &dst.FuncType{ + Params: &dst.FieldList{ + List: []*dst.Field{ + { + Names: []*dst.Ident{ + dst.NewIdent("old"), + }, + Type: &dst.SelectorExpr{ + X: dst.NewIdent(runtime), + Sel: dst.NewIdent("Object"), + }, + }, + }, + }, + Results: &dst.FieldList{ + List: []*dst.Field{ + { + Type: dst.NewIdent("error"), + }, + }, + }, + } + } + + return &dst.FuncType{ + Results: &dst.FieldList{ + List: []*dst.Field{ + { + Type: dst.NewIdent("error"), + }, + }, + }, + } +} diff --git a/hack/generator/pkg/astmodel/kubernetes_resource_interface.go b/hack/generator/pkg/astmodel/kubernetes_resource_interface.go index fbdbc1c3172..be863bf5b66 100644 --- a/hack/generator/pkg/astmodel/kubernetes_resource_interface.go +++ b/hack/generator/pkg/astmodel/kubernetes_resource_interface.go @@ -8,11 +8,11 @@ package astmodel import ( "fmt" "go/token" - "strings" - "github.com/Azure/azure-service-operator/hack/generator/pkg/astbuilder" "github.com/dave/dst" "github.com/pkg/errors" + + "github.com/Azure/azure-service-operator/hack/generator/pkg/astbuilder" ) // These are some magical field names which we're going to use or generate @@ -58,17 +58,19 @@ func AddKubernetesResourceInterfaceImpls( } getAzureNameProperty := &objectFunction{ - name: AzureNameProperty, - o: spec, - idFactory: idFactory, - asFunc: getNameFunction, + name: AzureNameProperty, + o: spec, + idFactory: idFactory, + asFunc: getNameFunction, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference), } getOwnerProperty := &objectFunction{ - name: OwnerProperty, - o: spec, - idFactory: idFactory, - asFunc: ownerFunction, + name: OwnerProperty, + o: spec, + idFactory: idFactory, + asFunc: ownerFunction, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference), } r = r.WithInterface(NewInterfaceImplementation( @@ -90,66 +92,31 @@ func AddKubernetesResourceInterfaceImpls( r = r.WithSpec(specObj.WithFunction( &objectFunction{ - name: SetAzureNameFunc, - o: specObj, - idFactory: idFactory, - asFunc: setNameFunction, + name: SetAzureNameFunc, + o: specObj, + idFactory: idFactory, + asFunc: setNameFunction, + requiredPackages: NewPackageReferenceSet(GenRuntimeReference), })) } + // Add defaults + defaulterBuilder := NewDefaulterBuilder(resourceName, r, idFactory) if setNameFunction != nil { - // we also need to generate a Defaulter implementation to default AzureName - r = r.WithInterface(generateDefaulter(resourceName, spec, idFactory)) + defaulterBuilder.AddDefault(NewDefaultAzureNameFunction(r, idFactory)) } + r = r.WithInterface(defaulterBuilder.ToInterfaceImplementation()) - return r, nil -} + // Add validations + validatorBuilder := NewValidatorBuilder(resourceName, r, idFactory) + r = r.WithInterface(validatorBuilder.ToInterfaceImplementation()) -var admissionPackageReference PackageReference = MakeExternalPackageReference("sigs.k8s.io/controller-runtime/pkg/webhook/admission") -var DefaulterInterfaceName = MakeTypeName(admissionPackageReference, "Defaulter") - -func generateDefaulter(resourceName TypeName, spec *ObjectType, idFactory IdentifierFactory) *InterfaceImplementation { - lpr, _ := resourceName.PackageReference.AsLocalPackage() - - group := lpr.group // e.g. "microsoft.network.infra.azure.com" - resource := resourceName.Name() // e.g. "backendaddresspools" - version := lpr.version // e.g. "v1" - - group = strings.ToLower(group + GroupSuffix) - nonPluralResource := strings.ToLower(resource) - resource = strings.ToLower(resourceName.Plural().Name()) - - // e.g. "mutate-microsoft-network-infra-azure-com-v1-backendaddresspool" - // note that this must match _exactly_ how controller-runtime generates the path - // or it will not work! - path := fmt.Sprintf("/mutate-%s-%s-%s", strings.ReplaceAll(group, ".", "-"), version, nonPluralResource) - - // e.g. "default.v123.backendaddresspool.infra.azure.com" - name := fmt.Sprintf("default.%s.%s.%s", version, resource, group) - - annotation := fmt.Sprintf( - "+kubebuilder:webhook:path=%s,mutating=true,sideEffects=None,"+ - "matchPolicy=Exact,failurePolicy=fail,groups=%s,resources=%s,"+ - "verbs=create;update,versions=%s,name=%s,admissionReviewVersions=v1beta1", // admission review version v1 is not yet supported by controller-runtime - path, - group, - resource, - version, - name) - - return NewInterfaceImplementation( - DefaulterInterfaceName, - &objectFunction{ - name: "Default", - o: spec, - idFactory: idFactory, - asFunc: defaultAzureNameFunction, - }).WithAnnotation(annotation) + return r, nil } // note that this can, as a side-effect, update the resource type // it is a bit ugly! -func getAzureNameFunctionsForType(r **ResourceType, spec *ObjectType, t Type, types Types) (asFuncType, asFuncType, error) { +func getAzureNameFunctionsForType(r **ResourceType, spec *ObjectType, t Type, types Types) (objectFunctionHandler, objectFunctionHandler, error) { // handle different types of AzureName property switch azureNamePropType := t.(type) { case *ValidatedType: @@ -213,20 +180,9 @@ func getAzureNameFunctionsForType(r **ResourceType, spec *ObjectType, t Type, ty } } -// objectFunction is a simple helper that implements the Function interface. It is intended for use for functions -// that only need information about the object they are operating on -type objectFunction struct { - name string - o *ObjectType - idFactory IdentifierFactory - asFunc asFuncType -} - -type asFuncType func(f *objectFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl - // getEnumAzureNameFunction adds an AzureName() function that casts the AzureName property // with an enum value to a string -func getEnumAzureNameFunction(enumType TypeName) asFuncType { +func getEnumAzureNameFunction(enumType TypeName) objectFunctionHandler { return func(f *objectFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { receiverIdent := f.idFactory.CreateIdentifier(receiver.Name(), NotExported) receiverType := receiver.AsType(codeGenerationContext) @@ -269,7 +225,7 @@ func getEnumAzureNameFunction(enumType TypeName) asFuncType { // setEnumAzureNameFunction returns a function that sets the AzureName property to the result of casting // the argument string to the given enum type -func setEnumAzureNameFunction(enumType TypeName) asFuncType { +func setEnumAzureNameFunction(enumType TypeName) objectFunctionHandler { return func(f *objectFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { receiverIdent := f.idFactory.CreateIdentifier(receiver.Name(), NotExported) receiverType := receiver.AsType(codeGenerationContext) @@ -305,7 +261,7 @@ func setEnumAzureNameFunction(enumType TypeName) asFuncType { } // fixedValueGetAzureNameFunction adds an AzureName() function that returns a fixed value -func fixedValueGetAzureNameFunction(fixedValue string) asFuncType { +func fixedValueGetAzureNameFunction(fixedValue string) objectFunctionHandler { // ensure fixedValue is quoted. This is always the case with enum values we pass, // but let's be safe: @@ -348,36 +304,6 @@ func fixedValueGetAzureNameFunction(fixedValue string) asFuncType { } } -var _ Function = &objectFunction{} - -// Name returns the unique name of this function -// (You can't have two functions with the same name on the same object or resource) -func (k *objectFunction) Name() string { - return k.name -} - -func (k *objectFunction) RequiredPackageReferences() *PackageReferenceSet { - // We only require GenRuntime - return NewPackageReferenceSet(GenRuntimeReference) -} - -func (k *objectFunction) References() TypeNameSet { - return k.o.References() -} - -func (k *objectFunction) AsFunc(codeGenerationContext *CodeGenerationContext, receiver TypeName) *dst.FuncDecl { - return k.asFunc(k, codeGenerationContext, receiver, k.name) -} - -func (k *objectFunction) Equals(f Function) bool { - typedF, ok := f.(*objectFunction) - if !ok { - return false - } - - return k.o.Equals(typedF.o) -} - // IsKubernetesResourceProperty returns true if the supplied property name is one of our "magical" names func IsKubernetesResourceProperty(name PropertyName) bool { return name == AzureNameProperty || name == OwnerProperty @@ -502,53 +428,6 @@ func createResourceReference( }) } -// defaultAzureNameFunction returns a function that defaults the AzureName property of the resource spec -// to the Name property of the resource spec -func defaultAzureNameFunction(k *objectFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { - receiverIdent := k.idFactory.CreateIdentifier(receiver.Name(), NotExported) - receiverType := receiver.AsType(codeGenerationContext) - - specSelector := &dst.SelectorExpr{ - X: dst.NewIdent(receiverIdent), - Sel: dst.NewIdent("Spec"), - } - - azureNameProp := &dst.SelectorExpr{ - X: specSelector, - Sel: dst.NewIdent(AzureNameProperty), - } - - nameProp := &dst.SelectorExpr{ - X: dst.NewIdent(receiverIdent), - Sel: dst.NewIdent("Name"), // this comes from ObjectMeta - } - - fn := &astbuilder.FuncDetails{ - Name: methodName, - ReceiverIdent: receiverIdent, - ReceiverType: &dst.StarExpr{ - X: receiverType, - }, - Body: []dst.Stmt{ - &dst.IfStmt{ - Cond: &dst.BinaryExpr{ - X: dst.Clone(azureNameProp).(dst.Expr), - Op: token.EQL, - Y: &dst.BasicLit{Kind: token.STRING, Value: "\"\""}, - }, - Body: astbuilder.StatementBlock( - astbuilder.SimpleAssignment( - azureNameProp, - token.ASSIGN, - nameProp)), - }, - }, - } - - fn.AddComments("defaults the Azure name of the resource to the Kubernetes name") - return fn.DefineFunc() -} - // setStringAzureNameFunction returns a function that sets the Name property of // the resource spec to the argument string func setStringAzureNameFunction(k *objectFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl { diff --git a/hack/generator/pkg/astmodel/object_type_serialization_test_case.go b/hack/generator/pkg/astmodel/object_type_serialization_test_case.go index 2f07a31579c..8d75356b37c 100644 --- a/hack/generator/pkg/astmodel/object_type_serialization_test_case.go +++ b/hack/generator/pkg/astmodel/object_type_serialization_test_case.go @@ -72,8 +72,8 @@ func (o ObjectSerializationTestCase) AsFuncs(name TypeName, genContext *CodeGene // Temporarily remove properties related to support for Arbitrary JSON // TODO: Add generators for these properties - o.removeByPackage(properties, ApiExtensionsReference) - o.removeByPackage(properties, ApiExtensionsJsonReference) + o.removeByPackage(properties, APIExtensionsReference) + o.removeByPackage(properties, APIExtensionsJSONReference) // Write errors for any properties we don't handle for _, p := range properties { diff --git a/hack/generator/pkg/astmodel/std_references.go b/hack/generator/pkg/astmodel/std_references.go index 704a1e70666..d309bbabb67 100644 --- a/hack/generator/pkg/astmodel/std_references.go +++ b/hack/generator/pkg/astmodel/std_references.go @@ -7,6 +7,7 @@ package astmodel var ( // References to standard Go Libraries + ErrorsReference = MakeExternalPackageReference("errors") FmtReference = MakeExternalPackageReference("fmt") JsonReference = MakeExternalPackageReference("encoding/json") ReflectReference = MakeExternalPackageReference("reflect") @@ -16,9 +17,12 @@ var ( GenRuntimeReference = MakeExternalPackageReference(genRuntimePathPrefix) // References to other libraries - ErrorsReference = MakeExternalPackageReference("github.com/pkg/errors") - ApiExtensionsReference = MakeExternalPackageReference("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1") - ApiExtensionsJsonReference = MakeExternalPackageReference("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/JSON") + APIExtensionsReference = MakeExternalPackageReference("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1") + APIExtensionsJSONReference = MakeExternalPackageReference("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/JSON") + APIMachineryErrorsReference = MakeExternalPackageReference("k8s.io/apimachinery/pkg/util/errors") + APIMachineryRuntimeReference = MakeExternalPackageReference("k8s.io/apimachinery/pkg/runtime") + ClientGoSchemeReference = MakeExternalPackageReference("k8s.io/client-go/kubernetes/scheme") + ControllerRuntimeAdmission = MakeExternalPackageReference("sigs.k8s.io/controller-runtime/pkg/webhook/admission") // References to libraries used for testing CmpReference = MakeExternalPackageReference("github.com/google/go-cmp/cmp") diff --git a/hack/generator/pkg/codegen/resource_registration_file.go b/hack/generator/pkg/codegen/resource_registration_file.go index ce28fb1472f..1ccfbb83778 100644 --- a/hack/generator/pkg/codegen/resource_registration_file.go +++ b/hack/generator/pkg/codegen/resource_registration_file.go @@ -114,24 +114,15 @@ func (r *ResourceRegistrationFile) generateImports() *astmodel.PackageImportSet } // We require these imports - clientGoSchemePkgRef := makeClientGoKubernetesSchemePackageReference() - clientGoSchemeImport := astmodel.NewPackageImport(clientGoSchemePkgRef).WithName("clientgoscheme") + clientGoSchemeImport := astmodel.NewPackageImport(astmodel.ClientGoSchemeReference).WithName("clientgoscheme") requiredImports.AddImport(clientGoSchemeImport) - runtimeImport := astmodel.NewPackageImport(makeApiMachineryRuntimePackageReference()) + runtimeImport := astmodel.NewPackageImport(astmodel.APIMachineryRuntimeReference) requiredImports.AddImport(runtimeImport) return requiredImports } -func makeApiMachineryRuntimePackageReference() astmodel.PackageReference { - return astmodel.MakeExternalPackageReference("k8s.io/apimachinery/pkg/runtime") -} - -func makeClientGoKubernetesSchemePackageReference() astmodel.PackageReference { - return astmodel.MakeExternalPackageReference("k8s.io/client-go/kubernetes/scheme") -} - // createGetKnownStorageTypesFunc creates a getKnownStorageTypes function that returns all storage types: // func getKnownStorageTypes() []runtime.Object { // var result []runtime.Object @@ -167,7 +158,7 @@ func (r *ResourceRegistrationFile) createGetKnownTypesFunc(codeGenerationContext } func createKnownTypesFuncImpl(codeGenerationContext *astmodel.CodeGenerationContext, resources []astmodel.TypeName, funcName string, funcComment string) (dst.Decl, error) { - runtime, err := codeGenerationContext.GetImportedPackageName(makeApiMachineryRuntimePackageReference()) + runtime, err := codeGenerationContext.GetImportedPackageName(astmodel.APIMachineryRuntimeReference) if err != nil { return nil, err } @@ -254,12 +245,12 @@ func createKnownTypesFuncImpl(codeGenerationContext *astmodel.CodeGenerationCont // return scheme // } func (r *ResourceRegistrationFile) createCreateSchemeFunc(codeGenerationContext *astmodel.CodeGenerationContext) (dst.Decl, error) { - runtime, err := codeGenerationContext.GetImportedPackageName(makeApiMachineryRuntimePackageReference()) + runtime, err := codeGenerationContext.GetImportedPackageName(astmodel.APIMachineryRuntimeReference) if err != nil { return nil, err } - clientGoScheme, err := codeGenerationContext.GetImportedPackageName(makeClientGoKubernetesSchemePackageReference()) + clientGoScheme, err := codeGenerationContext.GetImportedPackageName(astmodel.ClientGoSchemeReference) if err != nil { return nil, err } diff --git a/hack/generator/pkg/codegen/storage/type_converter.go b/hack/generator/pkg/codegen/storage/type_converter.go index b135da64b34..f4457419d35 100644 --- a/hack/generator/pkg/codegen/storage/type_converter.go +++ b/hack/generator/pkg/codegen/storage/type_converter.go @@ -63,8 +63,9 @@ func (t *TypeConverter) convertResourceType( resource *astmodel.ResourceType, ctx interface{}) (astmodel.Type, error) { - // storage resource types do not need defaulter interface, they have no webhooks - modifiedResource := resource.WithoutInterface(astmodel.DefaulterInterfaceName) + // storage resource types do not need defaulter/validator interfaces, they have no webhooks + modifiedResource := resource.WithoutInterface(astmodel.DefaulterInterfaceName). + WithoutInterface(astmodel.ValidatorInterfaceName) return astmodel.IdentityVisitOfResourceType(tv, modifiedResource, ctx) } diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_oneof_resource_conversion_on_arm_type_only_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_oneof_resource_conversion_on_arm_type_only_azure.golden index 70ad6fa5a49..bb63633482f 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_oneof_resource_conversion_on_arm_type_only_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_oneof_resource_conversion_on_arm_type_only_azure.golden @@ -8,6 +8,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -27,13 +29,25 @@ type FakeResource struct { var _ admission.Defaulter = &FakeResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the FakeResource resource func (fakeResource *FakeResource) Default() { + fakeResource.defaultImpl() + var temp interface{} = fakeResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (fakeResource *FakeResource) defaultAzureName() { if fakeResource.Spec.AzureName == "" { fakeResource.Spec.AzureName = fakeResource.Name } } +// defaultImpl applies the code generated defaults to the FakeResource resource +func (fakeResource *FakeResource) defaultImpl() { fakeResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &FakeResource{} // AzureName returns the Azure name of the resource @@ -47,6 +61,76 @@ func (fakeResource *FakeResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: fakeResource.Namespace, Name: fakeResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-fakeresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=fakeresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.fakeresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &FakeResource{} + +// ValidateCreate validates the creation of the resource +func (fakeResource *FakeResource) ValidateCreate() error { + validations := fakeResource.createValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (fakeResource *FakeResource) ValidateDelete() error { + validations := fakeResource.deleteValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (fakeResource *FakeResource) ValidateUpdate(old runtime.Object) error { + validations := fakeResource.updateValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (fakeResource *FakeResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (fakeResource *FakeResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (fakeResource *FakeResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/FakeResource type FakeResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_dependent_resource_and_ownership_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_dependent_resource_and_ownership_azure.golden index a2f48ab49c0..cb82f8c04bf 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_dependent_resource_and_ownership_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_dependent_resource_and_ownership_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type A struct { var _ admission.Defaulter = &A{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the A resource func (a *A) Default() { + a.defaultImpl() + var temp interface{} = a + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (a *A) defaultAzureName() { if a.Spec.AzureName == "" { a.Spec.AzureName = a.Name } } +// defaultImpl applies the code generated defaults to the A resource +func (a *A) defaultImpl() { a.defaultAzureName() } + var _ genruntime.KubernetesResource = &A{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (a *A) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: a.Namespace, Name: a.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-a,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=as,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.as.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &A{} + +// ValidateCreate validates the creation of the resource +func (a *A) ValidateCreate() error { + validations := a.createValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (a *A) ValidateDelete() error { + validations := a.deleteValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (a *A) ValidateUpdate(old runtime.Object) error { + validations := a.updateValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (a *A) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (a *A) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (a *A) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/A type AList struct { @@ -93,13 +177,25 @@ type B struct { var _ admission.Defaulter = &B{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the B resource func (b *B) Default() { + b.defaultImpl() + var temp interface{} = b + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (b *B) defaultAzureName() { if b.Spec.AzureName == "" { b.Spec.AzureName = b.Name } } +// defaultImpl applies the code generated defaults to the B resource +func (b *B) defaultImpl() { b.defaultAzureName() } + var _ genruntime.KubernetesResource = &B{} // AzureName returns the Azure name of the resource @@ -113,6 +209,76 @@ func (b *B) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: b.Namespace, Name: b.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-b,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=bs,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.bs.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &B{} + +// ValidateCreate validates the creation of the resource +func (b *B) ValidateCreate() error { + validations := b.createValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (b *B) ValidateDelete() error { + validations := b.deleteValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (b *B) ValidateUpdate(old runtime.Object) error { + validations := b.updateValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (b *B) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (b *B) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (b *B) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/B type BList struct { @@ -160,13 +326,25 @@ type C struct { var _ admission.Defaulter = &C{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the C resource func (c *C) Default() { + c.defaultImpl() + var temp interface{} = c + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (c *C) defaultAzureName() { if c.Spec.AzureName == "" { c.Spec.AzureName = c.Name } } +// defaultImpl applies the code generated defaults to the C resource +func (c *C) defaultImpl() { c.defaultAzureName() } + var _ genruntime.KubernetesResource = &C{} // AzureName returns the Azure name of the resource @@ -180,6 +358,76 @@ func (c *C) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: c.Namespace, Name: c.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-c,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=cs,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.cs.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &C{} + +// ValidateCreate validates the creation of the resource +func (c *C) ValidateCreate() error { + validations := c.createValidations() + var temp interface{} = c + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (c *C) ValidateDelete() error { + validations := c.deleteValidations() + var temp interface{} = c + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (c *C) ValidateUpdate(old runtime.Object) error { + validations := c.updateValidations() + var temp interface{} = c + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (c *C) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (c *C) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (c *C) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/C type CList struct { @@ -227,13 +475,25 @@ type D struct { var _ admission.Defaulter = &D{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the D resource func (d *D) Default() { + d.defaultImpl() + var temp interface{} = d + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (d *D) defaultAzureName() { if d.Spec.AzureName == "" { d.Spec.AzureName = d.Name } } +// defaultImpl applies the code generated defaults to the D resource +func (d *D) defaultImpl() { d.defaultAzureName() } + var _ genruntime.KubernetesResource = &D{} // AzureName returns the Azure name of the resource @@ -247,6 +507,76 @@ func (d *D) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: d.Namespace, Name: d.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-d,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=ds,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.ds.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &D{} + +// ValidateCreate validates the creation of the resource +func (d *D) ValidateCreate() error { + validations := d.createValidations() + var temp interface{} = d + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (d *D) ValidateDelete() error { + validations := d.deleteValidations() + var temp interface{} = d + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (d *D) ValidateUpdate(old runtime.Object) error { + validations := d.updateValidations() + var temp interface{} = d + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (d *D) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (d *D) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (d *D) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/D type DList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_empty_objecttype_removed_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_empty_objecttype_removed_azure.golden index e4aec80d3c5..adf873f7c18 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_empty_objecttype_removed_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_empty_objecttype_removed_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type A struct { var _ admission.Defaulter = &A{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the A resource func (a *A) Default() { + a.defaultImpl() + var temp interface{} = a + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (a *A) defaultAzureName() { if a.Spec.AzureName == "" { a.Spec.AzureName = a.Name } } +// defaultImpl applies the code generated defaults to the A resource +func (a *A) defaultImpl() { a.defaultAzureName() } + var _ genruntime.KubernetesResource = &A{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (a *A) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: a.Namespace, Name: a.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-a,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=as,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.as.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &A{} + +// ValidateCreate validates the creation of the resource +func (a *A) ValidateCreate() error { + validations := a.createValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (a *A) ValidateDelete() error { + validations := a.deleteValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (a *A) ValidateUpdate(old runtime.Object) error { + validations := a.updateValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (a *A) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (a *A) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (a *A) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/A type AList struct { @@ -94,13 +178,25 @@ type B struct { var _ admission.Defaulter = &B{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the B resource func (b *B) Default() { + b.defaultImpl() + var temp interface{} = b + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (b *B) defaultAzureName() { if b.Spec.AzureName == "" { b.Spec.AzureName = b.Name } } +// defaultImpl applies the code generated defaults to the B resource +func (b *B) defaultImpl() { b.defaultAzureName() } + var _ genruntime.KubernetesResource = &B{} // AzureName returns the Azure name of the resource @@ -114,6 +210,76 @@ func (b *B) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: b.Namespace, Name: b.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-b,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=bs,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.bs.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &B{} + +// ValidateCreate validates the creation of the resource +func (b *B) ValidateCreate() error { + validations := b.createValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (b *B) ValidateDelete() error { + validations := b.deleteValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (b *B) ValidateUpdate(old runtime.Object) error { + validations := b.updateValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (b *B) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (b *B) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (b *B) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/B type BList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_has_embedded_resource_inside_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_has_embedded_resource_inside_azure.golden index 325f1085567..6be715368b3 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_has_embedded_resource_inside_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_has_embedded_resource_inside_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type A struct { var _ admission.Defaulter = &A{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the A resource func (a *A) Default() { + a.defaultImpl() + var temp interface{} = a + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (a *A) defaultAzureName() { if a.Spec.AzureName == "" { a.Spec.AzureName = a.Name } } +// defaultImpl applies the code generated defaults to the A resource +func (a *A) defaultImpl() { a.defaultAzureName() } + var _ genruntime.KubernetesResource = &A{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (a *A) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: a.Namespace, Name: a.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-a,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=as,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.as.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &A{} + +// ValidateCreate validates the creation of the resource +func (a *A) ValidateCreate() error { + validations := a.createValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (a *A) ValidateDelete() error { + validations := a.deleteValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (a *A) ValidateUpdate(old runtime.Object) error { + validations := a.updateValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (a *A) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (a *A) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (a *A) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/A type AList struct { @@ -94,13 +178,25 @@ type B struct { var _ admission.Defaulter = &B{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the B resource func (b *B) Default() { + b.defaultImpl() + var temp interface{} = b + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (b *B) defaultAzureName() { if b.Spec.AzureName == "" { b.Spec.AzureName = b.Name } } +// defaultImpl applies the code generated defaults to the B resource +func (b *B) defaultImpl() { b.defaultAzureName() } + var _ genruntime.KubernetesResource = &B{} // AzureName returns the Azure name of the resource @@ -114,6 +210,76 @@ func (b *B) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: b.Namespace, Name: b.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-b,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=bs,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.bs.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &B{} + +// ValidateCreate validates the creation of the resource +func (b *B) ValidateCreate() error { + validations := b.createValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (b *B) ValidateDelete() error { + validations := b.deleteValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (b *B) ValidateUpdate(old runtime.Object) error { + validations := b.updateValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (b *B) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (b *B) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (b *B) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/B type BList struct { @@ -162,13 +328,25 @@ type C struct { var _ admission.Defaulter = &C{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the C resource func (c *C) Default() { + c.defaultImpl() + var temp interface{} = c + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (c *C) defaultAzureName() { if c.Spec.AzureName == "" { c.Spec.AzureName = c.Name } } +// defaultImpl applies the code generated defaults to the C resource +func (c *C) defaultImpl() { c.defaultAzureName() } + var _ genruntime.KubernetesResource = &C{} // AzureName returns the Azure name of the resource @@ -182,6 +360,76 @@ func (c *C) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: c.Namespace, Name: c.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-c,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=cs,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.cs.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &C{} + +// ValidateCreate validates the creation of the resource +func (c *C) ValidateCreate() error { + validations := c.createValidations() + var temp interface{} = c + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (c *C) ValidateDelete() error { + validations := c.deleteValidations() + var temp interface{} = c + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (c *C) ValidateUpdate(old runtime.Object) error { + validations := c.updateValidations() + var temp interface{} = c + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (c *C) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (c *C) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (c *C) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/C type CList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_multiple_contexts_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_multiple_contexts_azure.golden index 2e756484ffe..defbd2474c9 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_multiple_contexts_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_multiple_contexts_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type A struct { var _ admission.Defaulter = &A{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the A resource func (a *A) Default() { + a.defaultImpl() + var temp interface{} = a + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (a *A) defaultAzureName() { if a.Spec.AzureName == "" { a.Spec.AzureName = a.Name } } +// defaultImpl applies the code generated defaults to the A resource +func (a *A) defaultImpl() { a.defaultAzureName() } + var _ genruntime.KubernetesResource = &A{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (a *A) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: a.Namespace, Name: a.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-a,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=as,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.as.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &A{} + +// ValidateCreate validates the creation of the resource +func (a *A) ValidateCreate() error { + validations := a.createValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (a *A) ValidateDelete() error { + validations := a.deleteValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (a *A) ValidateUpdate(old runtime.Object) error { + validations := a.updateValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (a *A) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (a *A) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (a *A) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/A type AList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_removed_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_removed_azure.golden index 59ca79cfe23..69a882cb905 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_removed_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_resource_removed_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type A struct { var _ admission.Defaulter = &A{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the A resource func (a *A) Default() { + a.defaultImpl() + var temp interface{} = a + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (a *A) defaultAzureName() { if a.Spec.AzureName == "" { a.Spec.AzureName = a.Name } } +// defaultImpl applies the code generated defaults to the A resource +func (a *A) defaultImpl() { a.defaultAzureName() } + var _ genruntime.KubernetesResource = &A{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (a *A) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: a.Namespace, Name: a.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-a,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=as,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.as.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &A{} + +// ValidateCreate validates the creation of the resource +func (a *A) ValidateCreate() error { + validations := a.createValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (a *A) ValidateDelete() error { + validations := a.deleteValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (a *A) ValidateUpdate(old runtime.Object) error { + validations := a.updateValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (a *A) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (a *A) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (a *A) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/A type AList struct { @@ -94,13 +178,25 @@ type B struct { var _ admission.Defaulter = &B{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the B resource func (b *B) Default() { + b.defaultImpl() + var temp interface{} = b + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (b *B) defaultAzureName() { if b.Spec.AzureName == "" { b.Spec.AzureName = b.Name } } +// defaultImpl applies the code generated defaults to the B resource +func (b *B) defaultImpl() { b.defaultAzureName() } + var _ genruntime.KubernetesResource = &B{} // AzureName returns the Azure name of the resource @@ -114,6 +210,76 @@ func (b *B) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: b.Namespace, Name: b.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-b,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=bs,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.bs.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &B{} + +// ValidateCreate validates the creation of the resource +func (b *B) ValidateCreate() error { + validations := b.createValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (b *B) ValidateDelete() error { + validations := b.deleteValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (b *B) ValidateUpdate(old runtime.Object) error { + validations := b.updateValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (b *B) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (b *B) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (b *B) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/B type BList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_subresource_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_subresource_azure.golden index 44ce7f49741..d8170773c43 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_subresource_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_subresource_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type A struct { var _ admission.Defaulter = &A{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the A resource func (a *A) Default() { + a.defaultImpl() + var temp interface{} = a + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (a *A) defaultAzureName() { if a.Spec.AzureName == "" { a.Spec.AzureName = a.Name } } +// defaultImpl applies the code generated defaults to the A resource +func (a *A) defaultImpl() { a.defaultAzureName() } + var _ genruntime.KubernetesResource = &A{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (a *A) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: a.Namespace, Name: a.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-a,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=as,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.as.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &A{} + +// ValidateCreate validates the creation of the resource +func (a *A) ValidateCreate() error { + validations := a.createValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (a *A) ValidateDelete() error { + validations := a.deleteValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (a *A) ValidateUpdate(old runtime.Object) error { + validations := a.updateValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (a *A) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (a *A) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (a *A) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/A type AList struct { @@ -94,13 +178,25 @@ type B struct { var _ admission.Defaulter = &B{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the B resource func (b *B) Default() { + b.defaultImpl() + var temp interface{} = b + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (b *B) defaultAzureName() { if b.Spec.AzureName == "" { b.Spec.AzureName = b.Name } } +// defaultImpl applies the code generated defaults to the B resource +func (b *B) defaultImpl() { b.defaultAzureName() } + var _ genruntime.KubernetesResource = &B{} // AzureName returns the Azure name of the resource @@ -114,6 +210,76 @@ func (b *B) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: b.Namespace, Name: b.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-b,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=bs,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.bs.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &B{} + +// ValidateCreate validates the creation of the resource +func (b *B) ValidateCreate() error { + validations := b.createValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (b *B) ValidateDelete() error { + validations := b.deleteValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (b *B) ValidateUpdate(old runtime.Object) error { + validations := b.updateValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (b *B) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (b *B) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (b *B) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/B type BList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_subresource_same_properties_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_subresource_same_properties_azure.golden index ad1e0aec895..800bc62b0c1 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_subresource_same_properties_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_embedded_subresource_same_properties_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type A struct { var _ admission.Defaulter = &A{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the A resource func (a *A) Default() { + a.defaultImpl() + var temp interface{} = a + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (a *A) defaultAzureName() { if a.Spec.AzureName == "" { a.Spec.AzureName = a.Name } } +// defaultImpl applies the code generated defaults to the A resource +func (a *A) defaultImpl() { a.defaultAzureName() } + var _ genruntime.KubernetesResource = &A{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (a *A) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: a.Namespace, Name: a.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-a,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=as,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.as.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &A{} + +// ValidateCreate validates the creation of the resource +func (a *A) ValidateCreate() error { + validations := a.createValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (a *A) ValidateDelete() error { + validations := a.deleteValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (a *A) ValidateUpdate(old runtime.Object) error { + validations := a.updateValidations() + var temp interface{} = a + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (a *A) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (a *A) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (a *A) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/A type AList struct { @@ -94,13 +178,25 @@ type B struct { var _ admission.Defaulter = &B{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the B resource func (b *B) Default() { + b.defaultImpl() + var temp interface{} = b + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (b *B) defaultAzureName() { if b.Spec.AzureName == "" { b.Spec.AzureName = b.Name } } +// defaultImpl applies the code generated defaults to the B resource +func (b *B) defaultImpl() { b.defaultAzureName() } + var _ genruntime.KubernetesResource = &B{} // AzureName returns the Azure name of the resource @@ -114,6 +210,76 @@ func (b *B) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: b.Namespace, Name: b.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-b,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=bs,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.bs.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &B{} + +// ValidateCreate validates the creation of the resource +func (b *B) ValidateCreate() error { + validations := b.createValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (b *B) ValidateDelete() error { + validations := b.deleteValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (b *B) ValidateUpdate(old runtime.Object) error { + validations := b.updateValidations() + var temp interface{} = b + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (b *B) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (b *B) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (b *B) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/B type BList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_id_resource_reference_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_id_resource_reference_azure.golden index 09d068c1985..42744748902 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_id_resource_reference_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_id_resource_reference_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type FakeResource struct { var _ admission.Defaulter = &FakeResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the FakeResource resource func (fakeResource *FakeResource) Default() { + fakeResource.defaultImpl() + var temp interface{} = fakeResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (fakeResource *FakeResource) defaultAzureName() { if fakeResource.Spec.AzureName == "" { fakeResource.Spec.AzureName = fakeResource.Name } } +// defaultImpl applies the code generated defaults to the FakeResource resource +func (fakeResource *FakeResource) defaultImpl() { fakeResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &FakeResource{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (fakeResource *FakeResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: fakeResource.Namespace, Name: fakeResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-fakeresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=fakeresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.fakeresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &FakeResource{} + +// ValidateCreate validates the creation of the resource +func (fakeResource *FakeResource) ValidateCreate() error { + validations := fakeResource.createValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (fakeResource *FakeResource) ValidateDelete() error { + validations := fakeResource.deleteValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (fakeResource *FakeResource) ValidateUpdate(old runtime.Object) error { + validations := fakeResource.updateValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (fakeResource *FakeResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (fakeResource *FakeResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (fakeResource *FakeResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/FakeResource type FakeResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_required_and_optional_resource_references_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_required_and_optional_resource_references_azure.golden index a3cfdf0bd29..005c620970c 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_required_and_optional_resource_references_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_required_and_optional_resource_references_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type FakeResource struct { var _ admission.Defaulter = &FakeResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the FakeResource resource func (fakeResource *FakeResource) Default() { + fakeResource.defaultImpl() + var temp interface{} = fakeResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (fakeResource *FakeResource) defaultAzureName() { if fakeResource.Spec.AzureName == "" { fakeResource.Spec.AzureName = fakeResource.Name } } +// defaultImpl applies the code generated defaults to the FakeResource resource +func (fakeResource *FakeResource) defaultImpl() { fakeResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &FakeResource{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (fakeResource *FakeResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: fakeResource.Namespace, Name: fakeResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-fakeresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=fakeresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.fakeresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &FakeResource{} + +// ValidateCreate validates the creation of the resource +func (fakeResource *FakeResource) ValidateCreate() error { + validations := fakeResource.createValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (fakeResource *FakeResource) ValidateDelete() error { + validations := fakeResource.deleteValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (fakeResource *FakeResource) ValidateUpdate(old runtime.Object) error { + validations := fakeResource.updateValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (fakeResource *FakeResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (fakeResource *FakeResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (fakeResource *FakeResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/FakeResource type FakeResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_array_properties_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_array_properties_azure.golden index 6786d0a5db6..27eb0061178 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_array_properties_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_array_properties_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type FakeResource struct { var _ admission.Defaulter = &FakeResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the FakeResource resource func (fakeResource *FakeResource) Default() { + fakeResource.defaultImpl() + var temp interface{} = fakeResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (fakeResource *FakeResource) defaultAzureName() { if fakeResource.Spec.AzureName == "" { fakeResource.Spec.AzureName = fakeResource.Name } } +// defaultImpl applies the code generated defaults to the FakeResource resource +func (fakeResource *FakeResource) defaultImpl() { fakeResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &FakeResource{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (fakeResource *FakeResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: fakeResource.Namespace, Name: fakeResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-fakeresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=fakeresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.fakeresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &FakeResource{} + +// ValidateCreate validates the creation of the resource +func (fakeResource *FakeResource) ValidateCreate() error { + validations := fakeResource.createValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (fakeResource *FakeResource) ValidateDelete() error { + validations := fakeResource.deleteValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (fakeResource *FakeResource) ValidateUpdate(old runtime.Object) error { + validations := fakeResource.updateValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (fakeResource *FakeResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (fakeResource *FakeResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (fakeResource *FakeResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/FakeResource type FakeResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_complex_properties_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_complex_properties_azure.golden index 3ddc34b6daf..c7eeb3d71b4 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_complex_properties_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_complex_properties_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type FakeResource struct { var _ admission.Defaulter = &FakeResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the FakeResource resource func (fakeResource *FakeResource) Default() { + fakeResource.defaultImpl() + var temp interface{} = fakeResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (fakeResource *FakeResource) defaultAzureName() { if fakeResource.Spec.AzureName == "" { fakeResource.Spec.AzureName = fakeResource.Name } } +// defaultImpl applies the code generated defaults to the FakeResource resource +func (fakeResource *FakeResource) defaultImpl() { fakeResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &FakeResource{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (fakeResource *FakeResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: fakeResource.Namespace, Name: fakeResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-fakeresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=fakeresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.fakeresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &FakeResource{} + +// ValidateCreate validates the creation of the resource +func (fakeResource *FakeResource) ValidateCreate() error { + validations := fakeResource.createValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (fakeResource *FakeResource) ValidateDelete() error { + validations := fakeResource.deleteValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (fakeResource *FakeResource) ValidateUpdate(old runtime.Object) error { + validations := fakeResource.updateValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (fakeResource *FakeResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (fakeResource *FakeResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (fakeResource *FakeResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/FakeResource type FakeResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_json_fields_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_json_fields_azure.golden index 27038ce813c..8cc9b28ea0c 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_json_fields_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_json_fields_azure.golden @@ -8,6 +8,8 @@ import ( "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -27,13 +29,25 @@ type FakeResource struct { var _ admission.Defaulter = &FakeResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the FakeResource resource func (fakeResource *FakeResource) Default() { + fakeResource.defaultImpl() + var temp interface{} = fakeResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (fakeResource *FakeResource) defaultAzureName() { if fakeResource.Spec.AzureName == "" { fakeResource.Spec.AzureName = fakeResource.Name } } +// defaultImpl applies the code generated defaults to the FakeResource resource +func (fakeResource *FakeResource) defaultImpl() { fakeResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &FakeResource{} // AzureName returns the Azure name of the resource @@ -47,6 +61,76 @@ func (fakeResource *FakeResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: fakeResource.Namespace, Name: fakeResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-fakeresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=fakeresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.fakeresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &FakeResource{} + +// ValidateCreate validates the creation of the resource +func (fakeResource *FakeResource) ValidateCreate() error { + validations := fakeResource.createValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (fakeResource *FakeResource) ValidateDelete() error { + validations := fakeResource.deleteValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (fakeResource *FakeResource) ValidateUpdate(old runtime.Object) error { + validations := fakeResource.updateValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (fakeResource *FakeResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (fakeResource *FakeResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (fakeResource *FakeResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/FakeResource type FakeResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_map_properties_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_map_properties_azure.golden index 0388ca2f356..281f390c5d0 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_map_properties_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_map_properties_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type FakeResource struct { var _ admission.Defaulter = &FakeResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the FakeResource resource func (fakeResource *FakeResource) Default() { + fakeResource.defaultImpl() + var temp interface{} = fakeResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (fakeResource *FakeResource) defaultAzureName() { if fakeResource.Spec.AzureName == "" { fakeResource.Spec.AzureName = fakeResource.Name } } +// defaultImpl applies the code generated defaults to the FakeResource resource +func (fakeResource *FakeResource) defaultImpl() { fakeResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &FakeResource{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (fakeResource *FakeResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: fakeResource.Namespace, Name: fakeResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-fakeresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=fakeresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.fakeresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &FakeResource{} + +// ValidateCreate validates the creation of the resource +func (fakeResource *FakeResource) ValidateCreate() error { + validations := fakeResource.createValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (fakeResource *FakeResource) ValidateDelete() error { + validations := fakeResource.deleteValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (fakeResource *FakeResource) ValidateUpdate(old runtime.Object) error { + validations := fakeResource.updateValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (fakeResource *FakeResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (fakeResource *FakeResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (fakeResource *FakeResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/FakeResource type FakeResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_renders_spec_azure.golden b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_renders_spec_azure.golden index bd88489ee31..38a12e6374b 100644 --- a/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_renders_spec_azure.golden +++ b/hack/generator/pkg/codegen/testdata/ArmResource/Arm_test_simple_resource_renders_spec_azure.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type FakeResource struct { var _ admission.Defaulter = &FakeResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the FakeResource resource func (fakeResource *FakeResource) Default() { + fakeResource.defaultImpl() + var temp interface{} = fakeResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (fakeResource *FakeResource) defaultAzureName() { if fakeResource.Spec.AzureName == "" { fakeResource.Spec.AzureName = fakeResource.Name } } +// defaultImpl applies the code generated defaults to the FakeResource resource +func (fakeResource *FakeResource) defaultImpl() { fakeResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &FakeResource{} // AzureName returns the Azure name of the resource @@ -46,6 +60,76 @@ func (fakeResource *FakeResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: fakeResource.Namespace, Name: fakeResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-fakeresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=fakeresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.fakeresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &FakeResource{} + +// ValidateCreate validates the creation of the resource +func (fakeResource *FakeResource) ValidateCreate() error { + validations := fakeResource.createValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (fakeResource *FakeResource) ValidateDelete() error { + validations := fakeResource.deleteValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (fakeResource *FakeResource) ValidateUpdate(old runtime.Object) error { + validations := fakeResource.updateValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (fakeResource *FakeResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (fakeResource *FakeResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (fakeResource *FakeResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/FakeResource type FakeResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/EmbeddedTypes/Embedded_type_simple_resource.golden b/hack/generator/pkg/codegen/testdata/EmbeddedTypes/Embedded_type_simple_resource.golden index afd927180c5..d5655ebd3b2 100644 --- a/hack/generator/pkg/codegen/testdata/EmbeddedTypes/Embedded_type_simple_resource.golden +++ b/hack/generator/pkg/codegen/testdata/EmbeddedTypes/Embedded_type_simple_resource.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -30,13 +32,25 @@ type FakeResource struct { var _ admission.Defaulter = &FakeResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the FakeResource resource func (fakeResource *FakeResource) Default() { + fakeResource.defaultImpl() + var temp interface{} = fakeResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (fakeResource *FakeResource) defaultAzureName() { if fakeResource.Spec.AzureName == "" { fakeResource.Spec.AzureName = fakeResource.Name } } +// defaultImpl applies the code generated defaults to the FakeResource resource +func (fakeResource *FakeResource) defaultImpl() { fakeResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &FakeResource{} // AzureName returns the Azure name of the resource @@ -50,6 +64,76 @@ func (fakeResource *FakeResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: fakeResource.Namespace, Name: fakeResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-fakeresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=fakeresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.fakeresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &FakeResource{} + +// ValidateCreate validates the creation of the resource +func (fakeResource *FakeResource) ValidateCreate() error { + validations := fakeResource.createValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (fakeResource *FakeResource) ValidateDelete() error { + validations := fakeResource.deleteValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (fakeResource *FakeResource) ValidateUpdate(old runtime.Object) error { + validations := fakeResource.updateValidations() + var temp interface{} = fakeResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (fakeResource *FakeResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (fakeResource *FakeResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (fakeResource *FakeResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/FakeResource type FakeResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/EnumNames/Multi_valued_enum_name.golden b/hack/generator/pkg/codegen/testdata/EnumNames/Multi_valued_enum_name.golden index 8b76555fd9d..70c06601d23 100644 --- a/hack/generator/pkg/codegen/testdata/EnumNames/Multi_valued_enum_name.golden +++ b/hack/generator/pkg/codegen/testdata/EnumNames/Multi_valued_enum_name.golden @@ -7,6 +7,8 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -26,13 +28,25 @@ type AResource struct { var _ admission.Defaulter = &AResource{} -// Default defaults the Azure name of the resource to the Kubernetes name +// Default applies defaults to the AResource resource func (aResource *AResource) Default() { + aResource.defaultImpl() + var temp interface{} = aResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultAzureName defaults the Azure name of the resource to the Kubernetes name +func (aResource *AResource) defaultAzureName() { if aResource.Spec.AzureName == "" { aResource.Spec.AzureName = aResource.Name } } +// defaultImpl applies the code generated defaults to the AResource resource +func (aResource *AResource) defaultImpl() { aResource.defaultAzureName() } + var _ genruntime.KubernetesResource = &AResource{} // AzureName returns the Azure name of the resource (string representation of github.com/Azure/azure-service-operator/testing/test/v1alpha1api20200101/AResourceSpecName) @@ -46,6 +60,76 @@ func (aResource *AResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: aResource.Namespace, Name: aResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-aresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=aresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.aresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &AResource{} + +// ValidateCreate validates the creation of the resource +func (aResource *AResource) ValidateCreate() error { + validations := aResource.createValidations() + var temp interface{} = aResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (aResource *AResource) ValidateDelete() error { + validations := aResource.deleteValidations() + var temp interface{} = aResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (aResource *AResource) ValidateUpdate(old runtime.Object) error { + validations := aResource.updateValidations() + var temp interface{} = aResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (aResource *AResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (aResource *AResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (aResource *AResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/AResource type AResourceList struct { diff --git a/hack/generator/pkg/codegen/testdata/EnumNames/Single_valued_enum_name.golden b/hack/generator/pkg/codegen/testdata/EnumNames/Single_valued_enum_name.golden index 377d388dc57..4cdc368ccfe 100644 --- a/hack/generator/pkg/codegen/testdata/EnumNames/Single_valued_enum_name.golden +++ b/hack/generator/pkg/codegen/testdata/EnumNames/Single_valued_enum_name.golden @@ -7,6 +7,9 @@ import ( "fmt" "github.com/Azure/azure-service-operator/hack/generated/pkg/genruntime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) // +kubebuilder:rbac:groups=test.infra.azure.com,resources=aresources,verbs=get;list;watch;create;update;patch;delete @@ -21,6 +24,22 @@ type AResource struct { Spec AResource_Spec `json:"spec,omitempty"` } +// +kubebuilder:webhook:path=/mutate-test-infra-azure-com-v1alpha1api20200101-aresource,mutating=true,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=aresources,verbs=create;update,versions=v1alpha1api20200101,name=default.v1alpha1api20200101.aresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Defaulter = &AResource{} + +// Default applies defaults to the AResource resource +func (aResource *AResource) Default() { + aResource.defaultImpl() + var temp interface{} = aResource + if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok { + runtimeDefaulter.CustomDefault() + } +} + +// defaultImpl applies the code generated defaults to the AResource resource +func (aResource *AResource) defaultImpl() {} + var _ genruntime.KubernetesResource = &AResource{} // AzureName returns the Azure name of the resource (always "onlyonevalue") @@ -34,6 +53,76 @@ func (aResource *AResource) Owner() *genruntime.ResourceReference { return &genruntime.ResourceReference{Group: group, Kind: kind, Namespace: aResource.Namespace, Name: aResource.Spec.Owner.Name} } +// +kubebuilder:webhook:path=/validate-test-infra-azure-com-v1alpha1api20200101-aresource,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=test.infra.azure.com,resources=aresources,verbs=create;update,versions=v1alpha1api20200101,name=validate.v1alpha1api20200101.aresources.test.infra.azure.com,admissionReviewVersions=v1beta1 + +var _ admission.Validator = &AResource{} + +// ValidateCreate validates the creation of the resource +func (aResource *AResource) ValidateCreate() error { + validations := aResource.createValidations() + var temp interface{} = aResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.CreateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateDelete validates the deletion of the resource +func (aResource *AResource) ValidateDelete() error { + validations := aResource.deleteValidations() + var temp interface{} = aResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.DeleteValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation() + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// ValidateUpdate validates an update of the resource +func (aResource *AResource) ValidateUpdate(old runtime.Object) error { + validations := aResource.updateValidations() + var temp interface{} = aResource + if runtimeValidator, ok := temp.(genruntime.Validator); ok { + validations = append(validations, runtimeValidator.UpdateValidations()...) + } + var errs []error + for _, validation := range validations { + err := validation(old) + if err != nil { + errs = append(errs, err) + } + } + return kerrors.NewAggregate(errs) +} + +// createValidations validates the creation of the resource +func (aResource *AResource) createValidations() []func() error { + return nil +} + +// deleteValidations validates the deletion of the resource +func (aResource *AResource) deleteValidations() []func() error { + return nil +} + +// updateValidations validates the update of the resource +func (aResource *AResource) updateValidations() []func(old runtime.Object) error { + return nil +} + // +kubebuilder:object:root=true //Generated from: https://test.test/schemas/2020-01-01/test.json#/resourceDefinitions/AResource type AResourceList struct {