add apiservices/status REST handling
This commit is contained in:
		| @@ -18,16 +18,17 @@ package validation | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/api/validation" | 	"k8s.io/apimachinery/pkg/api/validation" | ||||||
| 	"k8s.io/apimachinery/pkg/api/validation/path" | 	"k8s.io/apimachinery/pkg/api/validation/path" | ||||||
| 	utilvalidation "k8s.io/apimachinery/pkg/util/validation" | 	utilvalidation "k8s.io/apimachinery/pkg/util/validation" | ||||||
| 	"k8s.io/apimachinery/pkg/util/validation/field" | 	"k8s.io/apimachinery/pkg/util/validation/field" | ||||||
|  |  | ||||||
| 	discoveryapi "k8s.io/kube-aggregator/pkg/apis/apiregistration" | 	"k8s.io/kube-aggregator/pkg/apis/apiregistration" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func ValidateAPIService(apiService *discoveryapi.APIService) field.ErrorList { | func ValidateAPIService(apiService *apiregistration.APIService) field.ErrorList { | ||||||
| 	requiredName := apiService.Spec.Version + "." + apiService.Spec.Group | 	requiredName := apiService.Spec.Version + "." + apiService.Spec.Group | ||||||
|  |  | ||||||
| 	allErrs := validation.ValidateObjectMeta(&apiService.ObjectMeta, false, | 	allErrs := validation.ValidateObjectMeta(&apiService.ObjectMeta, false, | ||||||
| @@ -86,9 +87,29 @@ func ValidateAPIService(apiService *discoveryapi.APIService) field.ErrorList { | |||||||
| 	return allErrs | 	return allErrs | ||||||
| } | } | ||||||
|  |  | ||||||
| func ValidateAPIServiceUpdate(newAPIService *discoveryapi.APIService, oldAPIService *discoveryapi.APIService) field.ErrorList { | func ValidateAPIServiceUpdate(newAPIService *apiregistration.APIService, oldAPIService *apiregistration.APIService) field.ErrorList { | ||||||
| 	allErrs := validation.ValidateObjectMetaUpdate(&newAPIService.ObjectMeta, &oldAPIService.ObjectMeta, field.NewPath("metadata")) | 	allErrs := validation.ValidateObjectMetaUpdate(&newAPIService.ObjectMeta, &oldAPIService.ObjectMeta, field.NewPath("metadata")) | ||||||
| 	allErrs = append(allErrs, ValidateAPIService(newAPIService)...) | 	allErrs = append(allErrs, ValidateAPIService(newAPIService)...) | ||||||
|  |  | ||||||
| 	return allErrs | 	return allErrs | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func ValidateAPIServiceStatus(status *apiregistration.APIServiceStatus, fldPath *field.Path) field.ErrorList { | ||||||
|  | 	allErrs := field.ErrorList{} | ||||||
|  |  | ||||||
|  | 	for i, condition := range status.Conditions { | ||||||
|  | 		if condition.Status != apiregistration.ConditionTrue && | ||||||
|  | 			condition.Status != apiregistration.ConditionFalse && | ||||||
|  | 			condition.Status != apiregistration.ConditionUnknown { | ||||||
|  | 			allErrs = append(allErrs, field.NotSupported(fldPath.Child("conditions").Index(i).Child("status"), condition.Status, []string{apiregistration.ConditionTrue, apiregistration.ConditionFalse, apiregistration.ConditionUnknown})) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return allErrs | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ValidateAPIServiceStatusUpdate(newAPIService *apiregistration.APIService, oldAPIService *apiregistration.APIService) field.ErrorList { | ||||||
|  | 	allErrs := validation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta, field.NewPath("metadata")) | ||||||
|  | 	allErrs = append(allErrs, ValidateAPIServiceStatus(&update.Status, field.NewPath("status"))...) | ||||||
|  | 	return allErrs | ||||||
|  | } | ||||||
|   | |||||||
| @@ -163,7 +163,9 @@ func (c completedConfig) NewWithDelegate(delegationTarget genericapiserver.Deleg | |||||||
| 	apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiregistration.GroupName, registry, Scheme, metav1.ParameterCodec, Codecs) | 	apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiregistration.GroupName, registry, Scheme, metav1.ParameterCodec, Codecs) | ||||||
| 	apiGroupInfo.GroupMeta.GroupVersion = v1alpha1.SchemeGroupVersion | 	apiGroupInfo.GroupMeta.GroupVersion = v1alpha1.SchemeGroupVersion | ||||||
| 	v1alpha1storage := map[string]rest.Storage{} | 	v1alpha1storage := map[string]rest.Storage{} | ||||||
| 	v1alpha1storage["apiservices"] = apiservicestorage.NewREST(Scheme, c.GenericConfig.RESTOptionsGetter) | 	apiServiceREST := apiservicestorage.NewREST(Scheme, c.GenericConfig.RESTOptionsGetter) | ||||||
|  | 	v1alpha1storage["apiservices"] = apiServiceREST | ||||||
|  | 	v1alpha1storage["apiservices/status"] = apiservicestorage.NewStatusREST(Scheme, apiServiceREST) | ||||||
| 	apiGroupInfo.VersionedResourcesStorageMap["v1alpha1"] = v1alpha1storage | 	apiGroupInfo.VersionedResourcesStorageMap["v1alpha1"] = v1alpha1storage | ||||||
|  |  | ||||||
| 	if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil { | 	if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil { | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apiserver/pkg/registry/generic" | 	"k8s.io/apiserver/pkg/registry/generic" | ||||||
| 	genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" | 	genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" | ||||||
|  | 	"k8s.io/apiserver/pkg/registry/rest" | ||||||
| 	"k8s.io/kube-aggregator/pkg/apis/apiregistration" | 	"k8s.io/kube-aggregator/pkg/apis/apiregistration" | ||||||
| 	"k8s.io/kube-aggregator/pkg/registry/apiservice" | 	"k8s.io/kube-aggregator/pkg/registry/apiservice" | ||||||
| ) | ) | ||||||
| @@ -50,3 +51,28 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST | |||||||
| 	} | 	} | ||||||
| 	return &REST{store} | 	return &REST{store} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // NewStatusREST makes a RESTStorage for status that has more limited options. | ||||||
|  | // It is based on the original REST so that we can share the same underlying store | ||||||
|  | func NewStatusREST(scheme *runtime.Scheme, rest *REST) *StatusREST { | ||||||
|  | 	statusStore := *rest.store | ||||||
|  | 	statusStore.CreateStrategy = nil | ||||||
|  | 	statusStore.DeleteStrategy = nil | ||||||
|  | 	statusStore.UpdateStrategy = apiservice.NewStatusStrategy(scheme) | ||||||
|  | 	return &REST{store: statusStore} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type StatusREST struct { | ||||||
|  | 	store *genericregistry.Store | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var _ = rest.Updater(&StatusREST{}) | ||||||
|  |  | ||||||
|  | func (r *StatusREST) New() runtime.Object { | ||||||
|  | 	return &extensions.Deployment{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Update alters the status subset of an object. | ||||||
|  | func (r *StatusREST) Update(ctx genericapirequest.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { | ||||||
|  | 	return r.store.Update(ctx, name, objInfo) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -46,7 +46,8 @@ func (apiServerStrategy) NamespaceScoped() bool { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (apiServerStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { | func (apiServerStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { | ||||||
| 	_ = obj.(*apiregistration.APIService) | 	apiservice = obj.(*apiregistration.APIService) | ||||||
|  | 	apiservice.Status = apiregistration.APIServiceStatus{} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (apiServerStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) { | func (apiServerStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) { | ||||||
| @@ -74,6 +75,44 @@ func (apiServerStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old | |||||||
| 	return validation.ValidateAPIServiceUpdate(obj.(*apiregistration.APIService), old.(*apiregistration.APIService)) | 	return validation.ValidateAPIServiceUpdate(obj.(*apiregistration.APIService), old.(*apiregistration.APIService)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type apiServerStatusStrategy struct { | ||||||
|  | 	runtime.ObjectTyper | ||||||
|  | 	names.NameGenerator | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func NewStatusStrategy(typer runtime.ObjectTyper) apiServerStatusStrategy { | ||||||
|  | 	return apiServerStrategy{typer, names.SimpleNameGenerator} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (apiServerStrategy) NamespaceScoped() bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (apiServerStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) { | ||||||
|  | 	newAPIService := obj.(*apiregistration.APIService) | ||||||
|  | 	oldAPIService := old.(*apiregistration.APIService) | ||||||
|  | 	newAPIService.Spec = oldAPIService.Spec | ||||||
|  | 	newAPIService.Labels = oldAPIService.Labels | ||||||
|  | 	newAPIService.Annotations = oldAPIService.Annotations | ||||||
|  | 	newAPIService.Finalizers = oldAPIService.Finalizers | ||||||
|  | 	newAPIService.OwnerReferences = oldAPIService.OwnerReferences | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (apiServerStrategy) AllowCreateOnUpdate() bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (apiServerStrategy) AllowUnconditionalUpdate() bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (apiServerStrategy) Canonicalize(obj runtime.Object) { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (apiServerStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList { | ||||||
|  | 	return validation.ValidateAPIServiceStatusUpdate(obj.(*apiregistration.APIService), old.(*apiregistration.APIService)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { | func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { | ||||||
| 	apiserver, ok := obj.(*apiregistration.APIService) | 	apiserver, ok := obj.(*apiregistration.APIService) | ||||||
| 	if !ok { | 	if !ok { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 deads2k
					deads2k