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,80 +1,85 @@
/*
Copyright 2019 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 (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
k8sinformers "k8s.io/client-go/informers"
"k8s.io/klog/v2"
"context"
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
tenantv1alpha1 "kubesphere.io/api/tenant/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
tenantv1beta1 "kubesphere.io/api/tenant/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/query"
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
)
type usersGetter struct {
ksInformer ksinformers.SharedInformerFactory
k8sInformer k8sinformers.SharedInformerFactory
cache runtimeclient.Reader
}
func New(ksinformer ksinformers.SharedInformerFactory, k8sinformer k8sinformers.SharedInformerFactory) v1alpha3.Interface {
return &usersGetter{ksInformer: ksinformer, k8sInformer: k8sinformer}
func New(cache runtimeclient.Reader) v1alpha3.Interface {
return &usersGetter{cache: cache}
}
func (d *usersGetter) Get(_, name string) (runtime.Object, error) {
return d.ksInformer.Iam().V1alpha2().Users().Lister().Get(name)
user := &iamv1beta1.User{}
return user, d.cache.Get(context.Background(), types.NamespacedName{Name: name}, user)
}
func (d *usersGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
var users []*iamv1alpha2.User
var users []*iamv1beta1.User
var err error
if namespace := query.Filters[iamv1alpha2.ScopeNamespace]; namespace != "" {
role := query.Filters[iamv1alpha2.ResourcesSingularRole]
if namespace := query.Filters[iamv1beta1.ScopeNamespace]; namespace != "" {
role := query.Filters[iamv1beta1.ResourcesSingularRole]
users, err = d.listAllUsersInNamespace(string(namespace), string(role))
delete(query.Filters, iamv1alpha2.ScopeNamespace)
delete(query.Filters, iamv1alpha2.ResourcesSingularRole)
} else if workspace := query.Filters[iamv1alpha2.ScopeWorkspace]; workspace != "" {
workspaceRole := query.Filters[iamv1alpha2.ResourcesSingularWorkspaceRole]
if err != nil {
return nil, err
}
delete(query.Filters, iamv1beta1.ScopeNamespace)
delete(query.Filters, iamv1beta1.ResourcesSingularRole)
} else if workspace := query.Filters[iamv1beta1.ScopeWorkspace]; workspace != "" {
workspaceRole := query.Filters[iamv1beta1.ResourcesSingularWorkspaceRole]
users, err = d.listAllUsersInWorkspace(string(workspace), string(workspaceRole))
delete(query.Filters, iamv1alpha2.ScopeWorkspace)
delete(query.Filters, iamv1alpha2.ResourcesSingularWorkspaceRole)
} else if cluster := query.Filters[iamv1alpha2.ScopeCluster]; cluster == "true" {
clusterRole := query.Filters[iamv1alpha2.ResourcesSingularClusterRole]
if err != nil {
return nil, err
}
delete(query.Filters, iamv1beta1.ScopeWorkspace)
delete(query.Filters, iamv1beta1.ResourcesSingularWorkspaceRole)
} else if cluster := query.Filters[iamv1beta1.ScopeCluster]; cluster == "true" {
clusterRole := query.Filters[iamv1beta1.ResourcesSingularClusterRole]
users, err = d.listAllUsersInCluster(string(clusterRole))
delete(query.Filters, iamv1alpha2.ScopeCluster)
delete(query.Filters, iamv1alpha2.ResourcesSingularClusterRole)
} else if globalRole := query.Filters[iamv1alpha2.ResourcesSingularGlobalRole]; globalRole != "" {
if err != nil {
return nil, err
}
delete(query.Filters, iamv1beta1.ScopeCluster)
delete(query.Filters, iamv1beta1.ResourcesSingularClusterRole)
} else if globalRole := query.Filters[iamv1beta1.ResourcesSingularGlobalRole]; globalRole != "" {
users, err = d.listAllUsersByGlobalRole(string(globalRole))
delete(query.Filters, iamv1alpha2.ResourcesSingularGlobalRole)
if err != nil {
return nil, err
}
delete(query.Filters, iamv1beta1.ResourcesSingularGlobalRole)
} else {
users, err = d.ksInformer.Iam().V1alpha2().Users().Lister().List(query.Selector())
}
if err != nil {
return nil, err
userList := &iamv1beta1.UserList{}
if err := d.cache.List(context.Background(), userList,
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
return nil, err
}
users = make([]*iamv1beta1.User, 0)
for _, item := range userList.Items {
users = append(users, item.DeepCopy())
}
}
var result []runtime.Object
@@ -87,12 +92,12 @@ func (d *usersGetter) List(_ string, query *query.Query) (*api.ListResult, error
func (d *usersGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
leftUser, ok := left.(*iamv1alpha2.User)
leftUser, ok := left.(*iamv1beta1.User)
if !ok {
return false
}
rightUser, ok := right.(*iamv1alpha2.User)
rightUser, ok := right.(*iamv1beta1.User)
if !ok {
return false
}
@@ -101,41 +106,39 @@ func (d *usersGetter) compare(left runtime.Object, right runtime.Object, field q
}
func (d *usersGetter) filter(object runtime.Object, filter query.Filter) bool {
user, ok := object.(*iamv1alpha2.User)
user, ok := object.(*iamv1beta1.User)
if !ok {
return false
}
switch filter.Field {
case iamv1alpha2.FieldEmail:
case iamv1beta1.FieldEmail:
return user.Spec.Email == string(filter.Value)
case iamv1alpha2.InGroup:
case iamv1beta1.InGroup:
return sliceutil.HasString(user.Spec.Groups, string(filter.Value))
case iamv1alpha2.NotInGroup:
case iamv1beta1.NotInGroup:
return !sliceutil.HasString(user.Spec.Groups, string(filter.Value))
default:
return v1alpha3.DefaultObjectMetaFilter(user.ObjectMeta, filter)
}
}
func (d *usersGetter) listAllUsersInWorkspace(workspace, role string) ([]*iamv1alpha2.User, error) {
var users []*iamv1alpha2.User
var err error
workspaceRoleBindings, err := d.ksInformer.Iam().V1alpha2().
WorkspaceRoleBindings().Lister().List(labels.SelectorFromValidatedSet(labels.Set{tenantv1alpha1.WorkspaceLabel: workspace}))
if err != nil {
func (d *usersGetter) listAllUsersInWorkspace(workspace, role string) ([]*iamv1beta1.User, error) {
var users []*iamv1beta1.User
workspaceRoleBindingList := &iamv1beta1.WorkspaceRoleBindingList{}
if err := d.cache.List(context.Background(), workspaceRoleBindingList,
client.MatchingLabels{tenantv1beta1.WorkspaceLabel: workspace}); err != nil {
klog.Error(err)
return nil, err
}
for _, roleBinding := range workspaceRoleBindings {
for _, roleBinding := range workspaceRoleBindingList.Items {
if role != "" && roleBinding.RoleRef.Name != role {
continue
}
for _, subject := range roleBinding.Subjects {
if subject.Kind == iamv1alpha2.ResourceKindUser {
if subject.Kind == iamv1beta1.ResourceKindUser {
if contains(users, subject.Name) {
klog.Warningf("conflict role binding found: %s, username:%s", roleBinding.ObjectMeta.String(), subject.Name)
@@ -153,12 +156,12 @@ func (d *usersGetter) listAllUsersInWorkspace(workspace, role string) ([]*iamv1a
return nil, err
}
user := obj.(*iamv1alpha2.User)
user := obj.(*iamv1beta1.User)
user = user.DeepCopy()
if user.Annotations == nil {
user.Annotations = make(map[string]string, 0)
}
user.Annotations[iamv1alpha2.WorkspaceRoleAnnotation] = roleBinding.RoleRef.Name
user.Annotations[iamv1beta1.WorkspaceRoleAnnotation] = roleBinding.RoleRef.Name
users = append(users, user)
}
}
@@ -167,24 +170,21 @@ func (d *usersGetter) listAllUsersInWorkspace(workspace, role string) ([]*iamv1a
return users, nil
}
func (d *usersGetter) listAllUsersInNamespace(namespace, role string) ([]*iamv1alpha2.User, error) {
var users []*iamv1alpha2.User
var err error
func (d *usersGetter) listAllUsersInNamespace(namespace, role string) ([]*iamv1beta1.User, error) {
var users []*iamv1beta1.User
roleBindings, err := d.k8sInformer.Rbac().V1().
RoleBindings().Lister().RoleBindings(namespace).List(labels.Everything())
if err != nil {
roleBindingList := &iamv1beta1.RoleBindingList{}
if err := d.cache.List(context.Background(), roleBindingList, client.InNamespace(namespace)); err != nil {
klog.Error(err)
return nil, err
}
for _, roleBinding := range roleBindings {
for _, roleBinding := range roleBindingList.Items {
if role != "" && roleBinding.RoleRef.Name != role {
continue
}
for _, subject := range roleBinding.Subjects {
if subject.Kind == iamv1alpha2.ResourceKindUser {
if subject.Kind == iamv1beta1.ResourceKindUser {
if contains(users, subject.Name) {
klog.Warningf("conflict role binding found: %s, username:%s", roleBinding.ObjectMeta.String(), subject.Name)
continue
@@ -201,12 +201,12 @@ func (d *usersGetter) listAllUsersInNamespace(namespace, role string) ([]*iamv1a
return nil, err
}
user := obj.(*iamv1alpha2.User)
user := obj.(*iamv1beta1.User)
user = user.DeepCopy()
if user.Annotations == nil {
user.Annotations = make(map[string]string, 0)
}
user.Annotations[iamv1alpha2.RoleAnnotation] = roleBinding.RoleRef.Name
user.Annotations[iamv1beta1.RoleAnnotation] = roleBinding.RoleRef.Name
users = append(users, user)
}
}
@@ -215,24 +215,20 @@ func (d *usersGetter) listAllUsersInNamespace(namespace, role string) ([]*iamv1a
return users, nil
}
func (d *usersGetter) listAllUsersByGlobalRole(globalRole string) ([]*iamv1alpha2.User, error) {
var users []*iamv1alpha2.User
var err error
globalRoleBindings, err := d.ksInformer.Iam().V1alpha2().
GlobalRoleBindings().Lister().List(labels.Everything())
if err != nil {
func (d *usersGetter) listAllUsersByGlobalRole(globalRole string) ([]*iamv1beta1.User, error) {
var users []*iamv1beta1.User
globalRoleBindingList := &iamv1beta1.GlobalRoleBindingList{}
if err := d.cache.List(context.Background(), globalRoleBindingList); err != nil {
klog.Error(err)
return nil, err
}
for _, roleBinding := range globalRoleBindings {
for _, roleBinding := range globalRoleBindingList.Items {
if roleBinding.RoleRef.Name != globalRole {
continue
}
for _, subject := range roleBinding.Subjects {
if subject.Kind == iamv1alpha2.ResourceKindUser {
if subject.Kind == iamv1beta1.ResourceKindUser {
if contains(users, subject.Name) {
klog.Warningf("conflict role binding found: %s, username:%s", roleBinding.ObjectMeta.String(), subject.Name)
@@ -250,12 +246,12 @@ func (d *usersGetter) listAllUsersByGlobalRole(globalRole string) ([]*iamv1alpha
return nil, err
}
user := obj.(*iamv1alpha2.User)
user := obj.(*iamv1beta1.User)
user = user.DeepCopy()
if user.Annotations == nil {
user.Annotations = make(map[string]string, 0)
}
user.Annotations[iamv1alpha2.GlobalRoleAnnotation] = roleBinding.RoleRef.Name
user.Annotations[iamv1beta1.GlobalRoleAnnotation] = roleBinding.RoleRef.Name
users = append(users, user)
}
}
@@ -264,23 +260,21 @@ func (d *usersGetter) listAllUsersByGlobalRole(globalRole string) ([]*iamv1alpha
return users, nil
}
func (d *usersGetter) listAllUsersInCluster(clusterRole string) ([]*iamv1alpha2.User, error) {
var users []*iamv1alpha2.User
var err error
func (d *usersGetter) listAllUsersInCluster(clusterRole string) ([]*iamv1beta1.User, error) {
var users []*iamv1beta1.User
roleBindings, err := d.k8sInformer.Rbac().V1().ClusterRoleBindings().Lister().List(labels.Everything())
if err != nil {
clusterRoleBindingList := &iamv1beta1.WorkspaceRoleBindingList{}
if err := d.cache.List(context.Background(), clusterRoleBindingList); err != nil {
klog.Error(err)
return nil, err
}
for _, roleBinding := range roleBindings {
for _, roleBinding := range clusterRoleBindingList.Items {
if clusterRole != "" && roleBinding.RoleRef.Name != clusterRole {
continue
}
for _, subject := range roleBinding.Subjects {
if subject.Kind == iamv1alpha2.ResourceKindUser {
if subject.Kind == iamv1beta1.ResourceKindUser {
if contains(users, subject.Name) {
klog.Warningf("conflict role binding found: %s, username:%s", roleBinding.ObjectMeta.String(), subject.Name)
continue
@@ -297,12 +291,12 @@ func (d *usersGetter) listAllUsersInCluster(clusterRole string) ([]*iamv1alpha2.
return nil, err
}
user := obj.(*iamv1alpha2.User)
user := obj.(*iamv1beta1.User)
user = user.DeepCopy()
if user.Annotations == nil {
user.Annotations = make(map[string]string, 0)
}
user.Annotations[iamv1alpha2.ClusterRoleAnnotation] = roleBinding.RoleRef.Name
user.Annotations[iamv1beta1.ClusterRoleAnnotation] = roleBinding.RoleRef.Name
users = append(users, user)
}
}
@@ -311,7 +305,7 @@ func (d *usersGetter) listAllUsersInCluster(clusterRole string) ([]*iamv1alpha2.
return users, nil
}
func contains(users []*iamv1alpha2.User, username string) bool {
func contains(users []*iamv1beta1.User, username string) bool {
for _, user := range users {
if user.Name == username {
return true