feat: kubesphere 4.0 (#6115)

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

---------

Signed-off-by: ci-bot <ci-bot@kubesphere.io>
Co-authored-by: ks-ci-bot <ks-ci-bot@example.com>
Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
KubeSphere CI Bot
2024-09-06 11:05:52 +08:00
committed by GitHub
parent b5015ec7b9
commit 447a51f08b
8557 changed files with 546695 additions and 1146174 deletions

View File

@@ -1,63 +1,86 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
* Please refer to the LICENSE file in the root directory of the project.
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
*/
package user
import (
"context"
"fmt"
"net/http"
"net/mail"
"k8s.io/apimachinery/pkg/runtime"
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
"kubesphere.io/api/iam/v1alpha2"
kscontroller "kubesphere.io/kubesphere/pkg/controller"
)
type EmailValidator struct {
Client client.Client
decoder *admission.Decoder
const webhookName = "user-webhook"
func (v *Webhook) Name() string {
return webhookName
}
func (a *EmailValidator) Handle(ctx context.Context, req admission.Request) admission.Response {
user := &v1alpha2.User{}
err := a.decoder.Decode(req, user)
if err != nil {
return admission.Errored(http.StatusBadRequest, err)
var _ kscontroller.Controller = &Webhook{}
var _ admission.CustomValidator = &Webhook{}
type Webhook struct {
client.Client
}
func (v *Webhook) SetupWithManager(mgr *kscontroller.Manager) error {
v.Client = mgr.GetClient()
return builder.WebhookManagedBy(mgr).
For(&iamv1beta1.User{}).
WithValidator(v).
WithDefaulter(v).
Complete()
}
func (v *Webhook) Default(ctx context.Context, obj runtime.Object) error {
return nil
}
// validate admits a pod if a specific annotation exists.
func (v *Webhook) validate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
user, ok := obj.(*iamv1beta1.User)
if !ok {
return nil, fmt.Errorf("expected a User but got a %T", obj)
}
allUsers := v1alpha2.UserList{}
if err = a.Client.List(ctx, &allUsers, &client.ListOptions{}); err != nil {
return admission.Errored(http.StatusInternalServerError, err)
allUsers := iamv1beta1.UserList{}
if err := v.List(ctx, &allUsers, &client.ListOptions{}); err != nil {
return nil, err
}
if _, err := mail.ParseAddress(user.Spec.Email); user.Spec.Email != "" && err != nil {
return admission.Errored(http.StatusBadRequest, fmt.Errorf("invalid email address:%s", user.Spec.Email))
return nil, fmt.Errorf("invalid email address:%s", user.Spec.Email)
}
alreadyExist := emailAlreadyExist(allUsers, user)
if alreadyExist {
return admission.Errored(http.StatusConflict, fmt.Errorf("user email: %s already exists", user.Spec.Email))
return nil, fmt.Errorf("user email: %s already exists", user.Spec.Email)
}
return admission.Allowed("")
return nil, nil
}
func emailAlreadyExist(users v1alpha2.UserList, user *v1alpha2.User) bool {
func (v *Webhook) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
return v.validate(ctx, obj)
}
func (v *Webhook) ValidateUpdate(ctx context.Context, _, newObj runtime.Object) (admission.Warnings, error) {
return v.validate(ctx, newObj)
}
func (v *Webhook) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
return v.validate(ctx, obj)
}
func emailAlreadyExist(users iamv1beta1.UserList, user *iamv1beta1.User) bool {
// empty email is allowed
if user.Spec.Email == "" {
return false
@@ -69,9 +92,3 @@ func emailAlreadyExist(users v1alpha2.UserList, user *v1alpha2.User) bool {
}
return false
}
// InjectDecoder injects the decoder.
func (a *EmailValidator) InjectDecoder(d *admission.Decoder) error {
a.decoder = d
return nil
}