KEP-3325: Promote SelfSubjectReview to Beta (#116274)

* Promote SelfSubjectReview to Beta

Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com>

* Fix whoami API

Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com>

* Fixes according to code review

Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com>

---------

Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com>
This commit is contained in:
Maksim Nabokikh
2023-03-09 00:42:33 +01:00
committed by GitHub
parent 0a5310fe9a
commit c1431af4f8
37 changed files with 2088 additions and 170 deletions

View File

@@ -166,7 +166,8 @@ type BoundObjectReference struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request.
// When using impersonation, users will receive the user info of the user being impersonated.
// When using impersonation, users will receive the user info of the user being impersonated. If impersonation or
// request header authentication is used, any extra keys will have their case ignored and returned as lowercase.
type SelfSubjectReview struct {
metav1.TypeMeta
// ObjectMeta fulfills the metav1.ObjectMetaAccessor interface so that the stock.

View File

@@ -28,6 +28,7 @@ import (
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
authentication "k8s.io/kubernetes/pkg/apis/authentication"
v1 "k8s.io/kubernetes/pkg/apis/authentication/v1"
)
func init() {
@@ -37,6 +38,26 @@ func init() {
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {
if err := s.AddGeneratedConversionFunc((*v1beta1.SelfSubjectReview)(nil), (*authentication.SelfSubjectReview)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta1_SelfSubjectReview_To_authentication_SelfSubjectReview(a.(*v1beta1.SelfSubjectReview), b.(*authentication.SelfSubjectReview), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*authentication.SelfSubjectReview)(nil), (*v1beta1.SelfSubjectReview)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_authentication_SelfSubjectReview_To_v1beta1_SelfSubjectReview(a.(*authentication.SelfSubjectReview), b.(*v1beta1.SelfSubjectReview), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*v1beta1.SelfSubjectReviewStatus)(nil), (*authentication.SelfSubjectReviewStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta1_SelfSubjectReviewStatus_To_authentication_SelfSubjectReviewStatus(a.(*v1beta1.SelfSubjectReviewStatus), b.(*authentication.SelfSubjectReviewStatus), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*authentication.SelfSubjectReviewStatus)(nil), (*v1beta1.SelfSubjectReviewStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_authentication_SelfSubjectReviewStatus_To_v1beta1_SelfSubjectReviewStatus(a.(*authentication.SelfSubjectReviewStatus), b.(*v1beta1.SelfSubjectReviewStatus), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*v1beta1.TokenReview)(nil), (*authentication.TokenReview)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta1_TokenReview_To_authentication_TokenReview(a.(*v1beta1.TokenReview), b.(*authentication.TokenReview), scope)
}); err != nil {
@@ -80,6 +101,56 @@ func RegisterConversions(s *runtime.Scheme) error {
return nil
}
func autoConvert_v1beta1_SelfSubjectReview_To_authentication_SelfSubjectReview(in *v1beta1.SelfSubjectReview, out *authentication.SelfSubjectReview, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_v1beta1_SelfSubjectReviewStatus_To_authentication_SelfSubjectReviewStatus(&in.Status, &out.Status, s); err != nil {
return err
}
return nil
}
// Convert_v1beta1_SelfSubjectReview_To_authentication_SelfSubjectReview is an autogenerated conversion function.
func Convert_v1beta1_SelfSubjectReview_To_authentication_SelfSubjectReview(in *v1beta1.SelfSubjectReview, out *authentication.SelfSubjectReview, s conversion.Scope) error {
return autoConvert_v1beta1_SelfSubjectReview_To_authentication_SelfSubjectReview(in, out, s)
}
func autoConvert_authentication_SelfSubjectReview_To_v1beta1_SelfSubjectReview(in *authentication.SelfSubjectReview, out *v1beta1.SelfSubjectReview, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_authentication_SelfSubjectReviewStatus_To_v1beta1_SelfSubjectReviewStatus(&in.Status, &out.Status, s); err != nil {
return err
}
return nil
}
// Convert_authentication_SelfSubjectReview_To_v1beta1_SelfSubjectReview is an autogenerated conversion function.
func Convert_authentication_SelfSubjectReview_To_v1beta1_SelfSubjectReview(in *authentication.SelfSubjectReview, out *v1beta1.SelfSubjectReview, s conversion.Scope) error {
return autoConvert_authentication_SelfSubjectReview_To_v1beta1_SelfSubjectReview(in, out, s)
}
func autoConvert_v1beta1_SelfSubjectReviewStatus_To_authentication_SelfSubjectReviewStatus(in *v1beta1.SelfSubjectReviewStatus, out *authentication.SelfSubjectReviewStatus, s conversion.Scope) error {
if err := v1.Convert_v1_UserInfo_To_authentication_UserInfo(&in.UserInfo, &out.UserInfo, s); err != nil {
return err
}
return nil
}
// Convert_v1beta1_SelfSubjectReviewStatus_To_authentication_SelfSubjectReviewStatus is an autogenerated conversion function.
func Convert_v1beta1_SelfSubjectReviewStatus_To_authentication_SelfSubjectReviewStatus(in *v1beta1.SelfSubjectReviewStatus, out *authentication.SelfSubjectReviewStatus, s conversion.Scope) error {
return autoConvert_v1beta1_SelfSubjectReviewStatus_To_authentication_SelfSubjectReviewStatus(in, out, s)
}
func autoConvert_authentication_SelfSubjectReviewStatus_To_v1beta1_SelfSubjectReviewStatus(in *authentication.SelfSubjectReviewStatus, out *v1beta1.SelfSubjectReviewStatus, s conversion.Scope) error {
if err := v1.Convert_authentication_UserInfo_To_v1_UserInfo(&in.UserInfo, &out.UserInfo, s); err != nil {
return err
}
return nil
}
// Convert_authentication_SelfSubjectReviewStatus_To_v1beta1_SelfSubjectReviewStatus is an autogenerated conversion function.
func Convert_authentication_SelfSubjectReviewStatus_To_v1beta1_SelfSubjectReviewStatus(in *authentication.SelfSubjectReviewStatus, out *v1beta1.SelfSubjectReviewStatus, s conversion.Scope) error {
return autoConvert_authentication_SelfSubjectReviewStatus_To_v1beta1_SelfSubjectReviewStatus(in, out, s)
}
func autoConvert_v1beta1_TokenReview_To_authentication_TokenReview(in *v1beta1.TokenReview, out *authentication.TokenReview, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_v1beta1_TokenReviewSpec_To_authentication_TokenReviewSpec(&in.Spec, &out.Spec, s); err != nil {

View File

@@ -31,6 +31,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
authenticationv1 "k8s.io/api/authentication/v1"
authenticationv1alpha1 "k8s.io/api/authentication/v1alpha1"
authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
authorizationapiv1 "k8s.io/api/authorization/v1"
autoscalingapiv1 "k8s.io/api/autoscaling/v1"
autoscalingapiv2 "k8s.io/api/autoscaling/v2"
@@ -705,6 +706,7 @@ var (
}
// betaAPIGroupVersionsDisabledByDefault is for all future beta groupVersions.
betaAPIGroupVersionsDisabledByDefault = []schema.GroupVersion{
authenticationv1beta1.SchemeGroupVersion,
autoscalingapiv2beta1.SchemeGroupVersion,
autoscalingapiv2beta2.SchemeGroupVersion,
batchapiv1beta1.SchemeGroupVersion,

View File

@@ -52,6 +52,7 @@ const (
// owner: @nabokihms
// alpha: v1.26
// beta: v1.27
//
// Enables API to get self subject attributes after authentication.
APISelfSubjectReview featuregate.Feature = "APISelfSubjectReview"
@@ -872,7 +873,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
AnyVolumeDataSource: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.24
APISelfSubjectReview: {Default: false, PreRelease: featuregate.Alpha},
APISelfSubjectReview: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.27
AppArmor: {Default: true, PreRelease: featuregate.Beta},

View File

@@ -172,6 +172,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"k8s.io/api/authentication/v1.UserInfo": schema_k8sio_api_authentication_v1_UserInfo(ref),
"k8s.io/api/authentication/v1alpha1.SelfSubjectReview": schema_k8sio_api_authentication_v1alpha1_SelfSubjectReview(ref),
"k8s.io/api/authentication/v1alpha1.SelfSubjectReviewStatus": schema_k8sio_api_authentication_v1alpha1_SelfSubjectReviewStatus(ref),
"k8s.io/api/authentication/v1beta1.SelfSubjectReview": schema_k8sio_api_authentication_v1beta1_SelfSubjectReview(ref),
"k8s.io/api/authentication/v1beta1.SelfSubjectReviewStatus": schema_k8sio_api_authentication_v1beta1_SelfSubjectReviewStatus(ref),
"k8s.io/api/authentication/v1beta1.TokenReview": schema_k8sio_api_authentication_v1beta1_TokenReview(ref),
"k8s.io/api/authentication/v1beta1.TokenReviewSpec": schema_k8sio_api_authentication_v1beta1_TokenReviewSpec(ref),
"k8s.io/api/authentication/v1beta1.TokenReviewStatus": schema_k8sio_api_authentication_v1beta1_TokenReviewStatus(ref),
@@ -8417,7 +8419,7 @@ func schema_k8sio_api_authentication_v1alpha1_SelfSubjectReview(ref common.Refer
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated.",
Description: "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"kind": {
@@ -8478,6 +8480,71 @@ func schema_k8sio_api_authentication_v1alpha1_SelfSubjectReviewStatus(ref common
}
}
func schema_k8sio_api_authentication_v1beta1_SelfSubjectReview(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"kind": {
SchemaProps: spec.SchemaProps{
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
Type: []string{"string"},
Format: "",
},
},
"apiVersion": {
SchemaProps: spec.SchemaProps{
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
Type: []string{"string"},
Format: "",
},
},
"metadata": {
SchemaProps: spec.SchemaProps{
Description: "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
Default: map[string]interface{}{},
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Status is filled in by the server with the user attributes.",
Default: map[string]interface{}{},
Ref: ref("k8s.io/api/authentication/v1beta1.SelfSubjectReviewStatus"),
},
},
},
},
},
Dependencies: []string{
"k8s.io/api/authentication/v1beta1.SelfSubjectReviewStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}
func schema_k8sio_api_authentication_v1beta1_SelfSubjectReviewStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"userInfo": {
SchemaProps: spec.SchemaProps{
Description: "User attributes of the user making this request.",
Default: map[string]interface{}{},
Ref: ref("k8s.io/api/authentication/v1.UserInfo"),
},
},
},
},
},
Dependencies: []string{
"k8s.io/api/authentication/v1.UserInfo"},
}
}
func schema_k8sio_api_authentication_v1beta1_TokenReview(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{

View File

@@ -19,6 +19,7 @@ package rest
import (
authenticationv1 "k8s.io/api/authentication/v1"
authenticationv1alpha1 "k8s.io/api/authentication/v1alpha1"
authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@@ -52,6 +53,10 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag
apiGroupInfo.VersionedResourcesStorageMap[authenticationv1alpha1.SchemeGroupVersion.Version] = storageMap
}
if storageMap := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[authenticationv1beta1.SchemeGroupVersion.Version] = storageMap
}
if storageMap := p.v1Storage(apiResourceConfigSource, restOptionsGetter); len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[authenticationv1.SchemeGroupVersion.Version] = storageMap
}
@@ -86,6 +91,21 @@ func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstora
return storage
}
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
storage := map[string]rest.Storage{}
// selfsubjectreviews
if resource := "selfsubjectreviews"; apiResourceConfigSource.ResourceEnabled(authenticationv1beta1.SchemeGroupVersion.WithResource(resource)) {
if utilfeature.DefaultFeatureGate.Enabled(features.APISelfSubjectReview) {
selfSRStorage := selfsubjectreview.NewREST()
storage[resource] = selfSRStorage
} else {
klog.Warningln("SelfSubjectReview API is disabled because corresponding feature gate APISelfSubjectReview is not enabled.")
}
}
return storage
}
func (p RESTStorageProvider) GroupName() string {
return authentication.GroupName
}

View File

@@ -29,11 +29,18 @@ import (
authenticationapi "k8s.io/kubernetes/pkg/apis/authentication"
)
var _ interface {
rest.Creater
rest.NamespaceScopedStrategy
rest.Scoper
rest.Storage
} = &REST{}
// REST implements a RESTStorage for selfsubjectreviews.
type REST struct {
}
// NewREST returns a RESTStorage object that will work against selfsubjectrulesreviews.
// NewREST returns a RESTStorage object that will work against selfsubjectreviews.
func NewREST() *REST {
return &REST{}
}
@@ -43,7 +50,7 @@ func (r *REST) NamespaceScoped() bool {
return false
}
// New creates a new selfsubjectrulesreview object.
// New creates a new selfsubjectreview object.
func (r *REST) New() runtime.Object {
return &authenticationapi.SelfSubjectReview{}
}
@@ -74,7 +81,7 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
extra := user.GetExtra()
selfSAR := &authenticationapi.SelfSubjectReview{
selfSR := &authenticationapi.SelfSubjectReview{
ObjectMeta: metav1.ObjectMeta{
CreationTimestamp: metav1.NewTime(time.Now()),
},
@@ -88,14 +95,14 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
},
}
for key, attr := range extra {
selfSAR.Status.UserInfo.Extra[key] = attr
selfSR.Status.UserInfo.Extra[key] = attr
}
return selfSAR, nil
return selfSR, nil
}
var _ rest.SingularNameProvider = &REST{}
func (r *REST) GetSingularName() string {
return "selfsubjectrulesreview"
return "selfsubjectreview"
}