diff --git a/pkg/admission/customresourcevalidation/console/OWNERS b/pkg/admission/customresourcevalidation/console/OWNERS new file mode 100644 index 000000000000..027982c01cdc --- /dev/null +++ b/pkg/admission/customresourcevalidation/console/OWNERS @@ -0,0 +1,8 @@ +reviewers: + - spadgett + - benjaminapetersen + - enj +approvers: + - spadgett + - benjaminapetersen + - enj diff --git a/pkg/admission/customresourcevalidation/console/validate_console.go b/pkg/admission/customresourcevalidation/console/validate_console.go new file mode 100644 index 000000000000..c409b5040c44 --- /dev/null +++ b/pkg/admission/customresourcevalidation/console/validate_console.go @@ -0,0 +1,118 @@ +package console + +import ( + "fmt" + "io" + + "k8s.io/apimachinery/pkg/api/validation" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/admission" + + configv1 "github.com/openshift/api/config/v1" + "github.com/openshift/origin/pkg/admission/customresourcevalidation" +) + +const PluginName = "config.openshift.io/ValidateConsole" + +// Register registers a plugin +func Register(plugins *admission.Plugins) { + plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) { + return customresourcevalidation.NewValidator( + map[schema.GroupResource]bool{ + configv1.GroupVersion.WithResource("consoles").GroupResource(): true, + }, + map[schema.GroupVersionKind]customresourcevalidation.ObjectValidator{ + configv1.GroupVersion.WithKind("Console"): consoleV1{}, + }) + }) +} + +func toConsoleV1(uncastObj runtime.Object) (*configv1.Console, field.ErrorList) { + if uncastObj == nil { + return nil, nil + } + + errs := field.ErrorList{} + + obj, ok := uncastObj.(*configv1.Console) + if !ok { + return nil, append(errs, + field.NotSupported(field.NewPath("kind"), fmt.Sprintf("%T", uncastObj), []string{"Console"}), + field.NotSupported(field.NewPath("apiVersion"), fmt.Sprintf("%T", uncastObj), []string{"config.openshift.io/v1"})) + } + + return obj, nil +} + +type consoleV1 struct{} + +func (consoleV1) ValidateCreate(uncastObj runtime.Object) field.ErrorList { + obj, errs := toConsoleV1(uncastObj) + if len(errs) > 0 { + return errs + } + + errs = append(errs, validation.ValidateObjectMeta(&obj.ObjectMeta, false, customresourcevalidation.RequireNameCluster, field.NewPath("metadata"))...) + errs = append(errs, validateConsoleSpecCreate(obj.Spec)...) + + return errs +} + +func (consoleV1) ValidateUpdate(uncastObj runtime.Object, uncastOldObj runtime.Object) field.ErrorList { + obj, errs := toConsoleV1(uncastObj) + if len(errs) > 0 { + return errs + } + oldObj, errs := toConsoleV1(uncastOldObj) + if len(errs) > 0 { + return errs + } + + errs = append(errs, validation.ValidateObjectMetaUpdate(&obj.ObjectMeta, &oldObj.ObjectMeta, field.NewPath("metadata"))...) + errs = append(errs, validateConsoleSpecUpdate(obj.Spec, oldObj.Spec)...) + + return errs +} + +func (consoleV1) ValidateStatusUpdate(uncastObj runtime.Object, uncastOldObj runtime.Object) field.ErrorList { + obj, errs := toConsoleV1(uncastObj) + if len(errs) > 0 { + return errs + } + oldObj, errs := toConsoleV1(uncastOldObj) + if len(errs) > 0 { + return errs + } + + // TODO validate the obj. remember that status validation should *never* fail on spec validation errors. + errs = append(errs, validation.ValidateObjectMetaUpdate(&obj.ObjectMeta, &oldObj.ObjectMeta, field.NewPath("metadata"))...) + errs = append(errs, validateConsoleStatus(obj.Status)...) + + return errs +} + +func validateConsoleSpecCreate(spec configv1.ConsoleSpec) field.ErrorList { + errs := field.ErrorList{} + + // TODO + + return errs +} + +func validateConsoleSpecUpdate(newSpec, oldSpec configv1.ConsoleSpec) field.ErrorList { + errs := field.ErrorList{} + + // TODO + + return errs +} + +func validateConsoleStatus(status configv1.ConsoleStatus) field.ErrorList { + errs := field.ErrorList{} + + // TODO + + return errs +} diff --git a/pkg/admission/customresourcevalidation/customresourcevalidationregistration/cr_validation_registration.go b/pkg/admission/customresourcevalidation/customresourcevalidationregistration/cr_validation_registration.go index d2f82d2c3d0a..f28594f73aea 100644 --- a/pkg/admission/customresourcevalidation/customresourcevalidationregistration/cr_validation_registration.go +++ b/pkg/admission/customresourcevalidation/customresourcevalidationregistration/cr_validation_registration.go @@ -4,6 +4,7 @@ import ( "k8s.io/apiserver/pkg/admission" "github.com/openshift/origin/pkg/admission/customresourcevalidation/authentication" + "github.com/openshift/origin/pkg/admission/customresourcevalidation/console" "github.com/openshift/origin/pkg/admission/customresourcevalidation/features" "github.com/openshift/origin/pkg/admission/customresourcevalidation/image" "github.com/openshift/origin/pkg/admission/customresourcevalidation/oauth" @@ -15,6 +16,7 @@ var AllCustomResourceValidators = []string{ authentication.PluginName, features.DenyDeleteFeaturesPluginName, features.PluginName, + console.PluginName, image.PluginName, oauth.PluginName, project.PluginName, @@ -24,6 +26,7 @@ func RegisterCustomResourceValidation(plugins *admission.Plugins) { authentication.Register(plugins) features.RegisterDenyDeleteFeatures(plugins) features.Register(plugins) + console.Register(plugins) image.Register(plugins) oauth.Register(plugins) project.Register(plugins)