Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
水淹萌龙
kubesphere
提交
ce3cd21a
K
kubesphere
项目概览
水淹萌龙
/
kubesphere
与 Fork 源项目一致
Fork自
KubeSphere / kubesphere
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kubesphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
未验证
提交
ce3cd21a
编写于
5月 29, 2020
作者:
H
hongming
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update user's role templates API
Signed-off-by:
N
hongming
<
talonwan@yunify.com
>
上级
2f650dba
变更
17
展开全部
隐藏空白更改
内联
并排
Showing
17 changed file
with
1407 addition
and
169 deletion
+1407
-169
cmd/controller-manager/app/controllers.go
cmd/controller-manager/app/controllers.go
+5
-0
cmd/controller-manager/app/server.go
cmd/controller-manager/app/server.go
+3
-4
pkg/apis/iam/v1alpha2/register.go
pkg/apis/iam/v1alpha2/register.go
+1
-0
pkg/apis/iam/v1alpha2/types.go
pkg/apis/iam/v1alpha2/types.go
+30
-2
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
+123
-1
pkg/apiserver/authorization/authorizerfactory/rbac.go
pkg/apiserver/authorization/authorizerfactory/rbac.go
+50
-31
pkg/apiserver/authorization/authorizerfactory/rbac_test.go
pkg/apiserver/authorization/authorizerfactory/rbac_test.go
+671
-30
pkg/controller/clusterrolebinding/clusterrolebinding_controller.go
...oller/clusterrolebinding/clusterrolebinding_controller.go
+0
-12
pkg/controller/globalrolebinding/globalrolebinding_controller.go
...troller/globalrolebinding/globalrolebinding_controller.go
+334
-0
pkg/kapis/iam/v1alpha2/handler.go
pkg/kapis/iam/v1alpha2/handler.go
+86
-62
pkg/kapis/iam/v1alpha2/register.go
pkg/kapis/iam/v1alpha2/register.go
+56
-17
pkg/kapis/tenant/v1alpha2/register.go
pkg/kapis/tenant/v1alpha2/register.go
+6
-0
pkg/models/iam/am/am.go
pkg/models/iam/am/am.go
+35
-6
pkg/models/iam/im/im.go
pkg/models/iam/im/im.go
+1
-0
pkg/models/resources/v1alpha3/role/roles.go
pkg/models/resources/v1alpha3/role/roles.go
+1
-1
pkg/models/resources/v1alpha3/user/users.go
pkg/models/resources/v1alpha3/user/users.go
+1
-1
pkg/models/tenant/tenant.go
pkg/models/tenant/tenant.go
+4
-2
未找到文件。
cmd/controller-manager/app/controllers.go
浏览文件 @
ce3cd21a
...
...
@@ -25,6 +25,7 @@ import (
"kubesphere.io/kubesphere/pkg/controller/destinationrule"
"kubesphere.io/kubesphere/pkg/controller/devopscredential"
"kubesphere.io/kubesphere/pkg/controller/devopsproject"
"kubesphere.io/kubesphere/pkg/controller/globalrolebinding"
"kubesphere.io/kubesphere/pkg/controller/job"
"kubesphere.io/kubesphere/pkg/controller/network/nsnetworkpolicy"
"kubesphere.io/kubesphere/pkg/controller/network/provider"
...
...
@@ -47,6 +48,7 @@ func AddControllers(
informerFactory
informers
.
InformerFactory
,
devopsClient
devops
.
Interface
,
s3Client
s3
.
Interface
,
multiClusterEnabled
bool
,
stopCh
<-
chan
struct
{})
error
{
kubernetesInformer
:=
informerFactory
.
KubernetesSharedInformerFactory
()
...
...
@@ -125,6 +127,8 @@ func AddControllers(
clusterRoleBindingController
:=
clusterrolebinding
.
NewController
(
client
.
Kubernetes
(),
kubernetesInformer
,
kubesphereInformer
)
globalRoleBindingController
:=
globalrolebinding
.
NewController
(
client
.
Kubernetes
(),
kubernetesInformer
,
kubesphereInformer
,
multiClusterEnabled
)
clusterController
:=
cluster
.
NewClusterController
(
client
.
Kubernetes
(),
client
.
Config
(),
...
...
@@ -158,6 +162,7 @@ func AddControllers(
"nsnp-controller"
:
nsnpController
,
"csr-controller"
:
csrController
,
"clusterrolebinding-controller"
:
clusterRoleBindingController
,
"globalrolebinding-controller"
:
globalRoleBindingController
,
}
for
name
,
ctrl
:=
range
controllers
{
...
...
cmd/controller-manager/app/server.go
浏览文件 @
ce3cd21a
...
...
@@ -36,17 +36,16 @@ import (
"kubesphere.io/kubesphere/pkg/controller/network/nsnetworkpolicy"
"kubesphere.io/kubesphere/pkg/controller/user"
"kubesphere.io/kubesphere/pkg/controller/workspace"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/s3"
"kubesphere.io/kubesphere/pkg/utils/term"
"os"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
"sigs.k8s.io/controller-runtime/pkg/webhook"
)
func
NewControllerManagerCommand
()
*
cobra
.
Command
{
...
...
@@ -147,7 +146,7 @@ func Run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
klog
.
Fatal
(
"Unable to create namespace controller"
)
}
if
err
:=
AddControllers
(
mgr
,
kubernetesClient
,
informerFactory
,
devopsClient
,
s3Client
,
stopCh
);
err
!=
nil
{
if
err
:=
AddControllers
(
mgr
,
kubernetesClient
,
informerFactory
,
devopsClient
,
s3Client
,
s
.
MultiClusterOptions
.
Enable
,
s
topCh
);
err
!=
nil
{
klog
.
Fatalf
(
"unable to register controllers to the manager: %v"
,
err
)
}
...
...
pkg/apis/iam/v1alpha2/register.go
浏览文件 @
ce3cd21a
...
...
@@ -59,6 +59,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&
WorkspaceRoleList
{},
&
WorkspaceRoleBinding
{},
&
WorkspaceRoleBindingList
{},
&
FederatedClusterRoleBinding
{},
)
metav1
.
AddToGroupVersion
(
scheme
,
SchemeGroupVersion
)
return
nil
...
...
pkg/apis/iam/v1alpha2/types.go
浏览文件 @
ce3cd21a
...
...
@@ -64,8 +64,7 @@ const (
ScopeWorkspace
=
"workspace"
ScopeCluster
=
"cluster"
ScopeNamespace
=
"namespace"
LocalCluster
=
"local"
GlobalAdmin
=
"global-admin"
PlatformAdmin
=
"platform-admin"
ClusterAdmin
=
"cluster-admin"
)
...
...
@@ -284,3 +283,32 @@ type WorkspaceRoleBindingList struct {
metav1
.
ListMeta
`json:"metadata,omitempty"`
Items
[]
WorkspaceRoleBinding
`json:"items"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type
FederatedClusterRoleBinding
struct
{
metav1
.
TypeMeta
`json:",inline"`
metav1
.
ObjectMeta
`json:"metadata,omitempty"`
Spec
FederatedClusterRoleBindingSpec
`json:"spec"`
}
type
FederatedClusterRoleBindingSpec
struct
{
Template
Template
`json:"template"`
Placement
Placement
`json:"placement"`
}
type
Template
struct
{
Subjects
[]
rbacv1
.
Subject
`json:"subjects,omitempty"`
RoleRef
rbacv1
.
RoleRef
`json:"roleRef"`
}
type
Placement
struct
{
Clusters
[]
Cluster
`json:"clusters,omitempty"`
ClusterSelector
ClusterSelector
`json:"clusterSelector,omitempty"`
}
type
ClusterSelector
struct
{
MatchLabels
map
[
string
]
string
`json:"matchLabels,omitempty"`
}
type
Cluster
struct
{
Name
string
`json:"name"`
}
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
浏览文件 @
ce3cd21a
// +build !ignore_autogenerated
/*
Copyright 20
19
The KubeSphere Authors.
Copyright 20
20
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.
...
...
@@ -25,6 +25,86 @@ import (
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
Cluster
)
DeepCopyInto
(
out
*
Cluster
)
{
*
out
=
*
in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
func
(
in
*
Cluster
)
DeepCopy
()
*
Cluster
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
Cluster
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
ClusterSelector
)
DeepCopyInto
(
out
*
ClusterSelector
)
{
*
out
=
*
in
if
in
.
MatchLabels
!=
nil
{
in
,
out
:=
&
in
.
MatchLabels
,
&
out
.
MatchLabels
*
out
=
make
(
map
[
string
]
string
,
len
(
*
in
))
for
key
,
val
:=
range
*
in
{
(
*
out
)[
key
]
=
val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSelector.
func
(
in
*
ClusterSelector
)
DeepCopy
()
*
ClusterSelector
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
ClusterSelector
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
FederatedClusterRoleBinding
)
DeepCopyInto
(
out
*
FederatedClusterRoleBinding
)
{
*
out
=
*
in
out
.
TypeMeta
=
in
.
TypeMeta
in
.
ObjectMeta
.
DeepCopyInto
(
&
out
.
ObjectMeta
)
in
.
Spec
.
DeepCopyInto
(
&
out
.
Spec
)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedClusterRoleBinding.
func
(
in
*
FederatedClusterRoleBinding
)
DeepCopy
()
*
FederatedClusterRoleBinding
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
FederatedClusterRoleBinding
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func
(
in
*
FederatedClusterRoleBinding
)
DeepCopyObject
()
runtime
.
Object
{
if
c
:=
in
.
DeepCopy
();
c
!=
nil
{
return
c
}
return
nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
FederatedClusterRoleBindingSpec
)
DeepCopyInto
(
out
*
FederatedClusterRoleBindingSpec
)
{
*
out
=
*
in
in
.
Template
.
DeepCopyInto
(
&
out
.
Template
)
in
.
Placement
.
DeepCopyInto
(
&
out
.
Placement
)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedClusterRoleBindingSpec.
func
(
in
*
FederatedClusterRoleBindingSpec
)
DeepCopy
()
*
FederatedClusterRoleBindingSpec
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
FederatedClusterRoleBindingSpec
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
GlobalRole
)
DeepCopyInto
(
out
*
GlobalRole
)
{
*
out
=
*
in
...
...
@@ -152,6 +232,48 @@ func (in *GlobalRoleList) DeepCopyObject() runtime.Object {
return
nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
Placement
)
DeepCopyInto
(
out
*
Placement
)
{
*
out
=
*
in
if
in
.
Clusters
!=
nil
{
in
,
out
:=
&
in
.
Clusters
,
&
out
.
Clusters
*
out
=
make
([]
Cluster
,
len
(
*
in
))
copy
(
*
out
,
*
in
)
}
in
.
ClusterSelector
.
DeepCopyInto
(
&
out
.
ClusterSelector
)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Placement.
func
(
in
*
Placement
)
DeepCopy
()
*
Placement
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
Placement
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
Template
)
DeepCopyInto
(
out
*
Template
)
{
*
out
=
*
in
if
in
.
Subjects
!=
nil
{
in
,
out
:=
&
in
.
Subjects
,
&
out
.
Subjects
*
out
=
make
([]
v1
.
Subject
,
len
(
*
in
))
copy
(
*
out
,
*
in
)
}
out
.
RoleRef
=
in
.
RoleRef
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Template.
func
(
in
*
Template
)
DeepCopy
()
*
Template
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
Template
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
User
)
DeepCopyInto
(
out
*
User
)
{
*
out
=
*
in
...
...
pkg/apiserver/authorization/authorizerfactory/rbac.go
浏览文件 @
ce3cd21a
...
...
@@ -78,7 +78,7 @@ type ruleAccumulator struct {
errors
[]
error
}
func
(
r
*
ruleAccumulator
)
visit
(
source
fmt
.
Stringer
,
_
string
,
rule
*
rbacv1
.
PolicyRule
,
err
error
)
bool
{
func
(
r
*
ruleAccumulator
)
visit
(
_
fmt
.
Stringer
,
_
string
,
rule
*
rbacv1
.
PolicyRule
,
err
error
)
bool
{
if
rule
!=
nil
{
r
.
rules
=
append
(
r
.
rules
,
*
rule
)
}
...
...
@@ -200,6 +200,7 @@ func (r *RBACAuthorizer) rulesFor(requestAttributes authorizer.Attributes) ([]rb
}
func
(
r
*
RBACAuthorizer
)
visitRulesFor
(
requestAttributes
authorizer
.
Attributes
,
visitor
func
(
source
fmt
.
Stringer
,
regoPolicy
string
,
rule
*
rbacv1
.
PolicyRule
,
err
error
)
bool
)
{
if
globalRoleBindings
,
err
:=
r
.
am
.
ListGlobalRoleBindings
(
""
);
err
!=
nil
{
if
!
visitor
(
nil
,
""
,
nil
,
err
)
{
return
...
...
@@ -229,7 +230,54 @@ func (r *RBACAuthorizer) visitRulesFor(requestAttributes authorizer.Attributes,
}
}
if
requestAttributes
.
GetResourceScope
()
==
request
.
WorkspaceScope
{
if
requestAttributes
.
GetResourceScope
()
==
request
.
ClusterScope
||
requestAttributes
.
GetResourceScope
()
==
request
.
NamespaceScope
{
if
clusterRoleBindings
,
err
:=
r
.
am
.
ListClusterRoleBindings
(
""
);
err
!=
nil
{
if
!
visitor
(
nil
,
""
,
nil
,
err
)
{
return
}
}
else
{
sourceDescriber
:=
&
clusterRoleBindingDescriber
{}
for
_
,
clusterRoleBinding
:=
range
clusterRoleBindings
{
subjectIndex
,
applies
:=
appliesTo
(
requestAttributes
.
GetUser
(),
clusterRoleBinding
.
Subjects
,
""
)
if
!
applies
{
continue
}
regoPolicy
,
rules
,
err
:=
r
.
am
.
GetRoleReferenceRules
(
clusterRoleBinding
.
RoleRef
,
""
)
if
err
!=
nil
{
visitor
(
nil
,
""
,
nil
,
err
)
continue
}
sourceDescriber
.
binding
=
clusterRoleBinding
sourceDescriber
.
subject
=
&
clusterRoleBinding
.
Subjects
[
subjectIndex
]
if
!
visitor
(
sourceDescriber
,
regoPolicy
,
nil
,
nil
)
{
return
}
for
i
:=
range
rules
{
if
!
visitor
(
sourceDescriber
,
""
,
&
rules
[
i
],
nil
)
{
return
}
}
}
}
}
if
requestAttributes
.
GetResourceScope
()
==
request
.
WorkspaceScope
||
requestAttributes
.
GetResourceScope
()
==
request
.
NamespaceScope
{
var
workspace
string
var
err
error
if
requestAttributes
.
GetResourceScope
()
==
request
.
NamespaceScope
{
if
workspace
,
err
=
r
.
am
.
GetControlledWorkspace
(
requestAttributes
.
GetNamespace
());
err
!=
nil
{
if
!
visitor
(
nil
,
""
,
nil
,
err
)
{
return
}
}
}
if
workspace
==
""
{
workspace
=
requestAttributes
.
GetWorkspace
()
}
if
workspaceRoleBindings
,
err
:=
r
.
am
.
ListWorkspaceRoleBindings
(
""
,
requestAttributes
.
GetWorkspace
());
err
!=
nil
{
if
!
visitor
(
nil
,
""
,
nil
,
err
)
{
return
...
...
@@ -290,35 +338,6 @@ func (r *RBACAuthorizer) visitRulesFor(requestAttributes authorizer.Attributes,
}
}
}
if
clusterRoleBindings
,
err
:=
r
.
am
.
ListClusterRoleBindings
(
""
);
err
!=
nil
{
if
!
visitor
(
nil
,
""
,
nil
,
err
)
{
return
}
}
else
{
sourceDescriber
:=
&
clusterRoleBindingDescriber
{}
for
_
,
clusterRoleBinding
:=
range
clusterRoleBindings
{
subjectIndex
,
applies
:=
appliesTo
(
requestAttributes
.
GetUser
(),
clusterRoleBinding
.
Subjects
,
""
)
if
!
applies
{
continue
}
regoPolicy
,
rules
,
err
:=
r
.
am
.
GetRoleReferenceRules
(
clusterRoleBinding
.
RoleRef
,
""
)
if
err
!=
nil
{
visitor
(
nil
,
""
,
nil
,
err
)
continue
}
sourceDescriber
.
binding
=
clusterRoleBinding
sourceDescriber
.
subject
=
&
clusterRoleBinding
.
Subjects
[
subjectIndex
]
if
!
visitor
(
sourceDescriber
,
regoPolicy
,
nil
,
nil
)
{
return
}
for
i
:=
range
rules
{
if
!
visitor
(
sourceDescriber
,
""
,
&
rules
[
i
],
nil
)
{
return
}
}
}
}
}
// appliesTo returns whether any of the bindingSubjects applies to the specified subject,
...
...
pkg/apiserver/authorization/authorizerfactory/rbac_test.go
浏览文件 @
ce3cd21a
此差异已折叠。
点击以展开。
pkg/controller/clusterrolebinding/clusterrolebinding_controller.go
浏览文件 @
ce3cd21a
...
...
@@ -18,7 +18,6 @@ package clusterrolebinding
import
(
"fmt"
"golang.org/x/crypto/bcrypt"
corev1
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
...
...
@@ -209,7 +208,6 @@ func (c *Controller) reconcile(key string) error {
}
isClusterAdmin
:=
clusterRoleBinding
.
RoleRef
.
Name
==
iamv1alpha2
.
ClusterAdmin
if
isClusterAdmin
{
for
_
,
subject
:=
range
clusterRoleBinding
.
Subjects
{
if
subject
.
Kind
==
iamv1alpha2
.
ResourceKindUser
{
...
...
@@ -229,13 +227,3 @@ func (c *Controller) reconcile(key string) error {
func
(
c
*
Controller
)
Start
(
stopCh
<-
chan
struct
{})
error
{
return
c
.
Run
(
4
,
stopCh
)
}
func
encrypt
(
password
string
)
(
string
,
error
)
{
// when user is already mapped to another identity, password is empty by default
// unable to log in directly until password reset
if
password
==
""
{
return
""
,
nil
}
bytes
,
err
:=
bcrypt
.
GenerateFromPassword
([]
byte
(
password
),
bcrypt
.
DefaultCost
)
return
string
(
bytes
),
err
}
pkg/controller/globalrolebinding/globalrolebinding_controller.go
0 → 100644
浏览文件 @
ce3cd21a
/*
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.
*/
package
globalrolebinding
import
(
"encoding/json"
"fmt"
corev1
"k8s.io/api/core/v1"
rbacv1
"k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
k8sinformers
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
typedcorev1
"k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"k8s.io/klog"
iamv1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
ksinformers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
iamv1alpha2informers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/iam/v1alpha2"
iamv1alpha2listers
"kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"time"
)
const
(
// SuccessSynced is used as part of the Event 'reason' when a Foo is synced
successSynced
=
"Synced"
// is synced successfully
messageResourceSynced
=
"GlobalRoleBinding synced successfully"
controllerName
=
"globalrolebinding-controller"
federatedClusterRoleBindingKind
=
"FederatedClusterRoleBinding"
federatedResourceVersion
=
"types.kubefed.io/v1beta1"
federatedResourceAPIPath
=
"/apis/types.kubefed.io/v1beta1/federatedclusterrolebindings"
)
type
Controller
struct
{
k8sClient
kubernetes
.
Interface
informer
iamv1alpha2informers
.
GlobalRoleBindingInformer
lister
iamv1alpha2listers
.
GlobalRoleBindingLister
synced
cache
.
InformerSynced
// workqueue is a rate limited work queue. This is used to queue work to be
// processed instead of performing it as soon as a change happens. This
// means we can ensure we only process a fixed amount of resources at a
// time, and makes it easy to ensure we are never processing the same item
// simultaneously in two different workers.
workqueue
workqueue
.
RateLimitingInterface
// recorder is an event recorder for recording Event resources to the
// Kubernetes API.
recorder
record
.
EventRecorder
multiClusterEnabled
bool
}
func
NewController
(
k8sClient
kubernetes
.
Interface
,
k8sInformer
k8sinformers
.
SharedInformerFactory
,
ksInformer
ksinformers
.
SharedInformerFactory
,
multiClusterEnabled
bool
)
*
Controller
{
// Create event broadcaster
// Add sample-controller types to the default Kubernetes Scheme so Events can be
// logged for sample-controller types.
klog
.
V
(
4
)
.
Info
(
"Creating event broadcaster"
)
eventBroadcaster
:=
record
.
NewBroadcaster
()
eventBroadcaster
.
StartLogging
(
klog
.
Infof
)
eventBroadcaster
.
StartRecordingToSink
(
&
typedcorev1
.
EventSinkImpl
{
Interface
:
k8sClient
.
CoreV1
()
.
Events
(
""
)})
recorder
:=
eventBroadcaster
.
NewRecorder
(
scheme
.
Scheme
,
corev1
.
EventSource
{
Component
:
controllerName
})
informer
:=
ksInformer
.
Iam
()
.
V1alpha2
()
.
GlobalRoleBindings
()
ctl
:=
&
Controller
{
k8sClient
:
k8sClient
,
informer
:
informer
,
lister
:
informer
.
Lister
(),
synced
:
informer
.
Informer
()
.
HasSynced
,
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"ClusterRoleBinding"
),
recorder
:
recorder
,
multiClusterEnabled
:
multiClusterEnabled
,
}
klog
.
Info
(
"Setting up event handlers"
)
informer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
AddFunc
:
ctl
.
enqueueClusterRoleBinding
,
UpdateFunc
:
func
(
old
,
new
interface
{})
{
ctl
.
enqueueClusterRoleBinding
(
new
)
},
DeleteFunc
:
ctl
.
enqueueClusterRoleBinding
,
})
return
ctl
}
func
(
c
*
Controller
)
Run
(
threadiness
int
,
stopCh
<-
chan
struct
{})
error
{
defer
utilruntime
.
HandleCrash
()
defer
c
.
workqueue
.
ShutDown
()
//init client
// Start the informer factories to begin populating the informer caches
klog
.
Info
(
"Starting User controller"
)
// Wait for the caches to be synced before starting workers
klog
.
Info
(
"Waiting for informer caches to sync"
)
if
ok
:=
cache
.
WaitForCacheSync
(
stopCh
,
c
.
synced
);
!
ok
{
return
fmt
.
Errorf
(
"failed to wait for caches to sync"
)
}
klog
.
Info
(
"Starting workers"
)
// Launch two workers to process Foo resources
for
i
:=
0
;
i
<
threadiness
;
i
++
{
go
wait
.
Until
(
c
.
runWorker
,
time
.
Second
,
stopCh
)
}
klog
.
Info
(
"Started workers"
)
<-
stopCh
klog
.
Info
(
"Shutting down workers"
)
return
nil
}
func
(
c
*
Controller
)
enqueueClusterRoleBinding
(
obj
interface
{})
{
var
key
string
var
err
error
if
key
,
err
=
cache
.
MetaNamespaceKeyFunc
(
obj
);
err
!=
nil
{
utilruntime
.
HandleError
(
err
)
return
}
c
.
workqueue
.
Add
(
key
)
}
func
(
c
*
Controller
)
runWorker
()
{
for
c
.
processNextWorkItem
()
{
}
}
func
(
c
*
Controller
)
processNextWorkItem
()
bool
{
obj
,
shutdown
:=
c
.
workqueue
.
Get
()
if
shutdown
{
return
false
}
// We wrap this block in a func so we can defer c.workqueue.Done.
err
:=
func
(
obj
interface
{})
error
{
// We call Done here so the workqueue knows we have finished
// processing this item. We also must remember to call Forget if we
// do not want this work item being re-queued. For example, we do
// not call Forget if a transient error occurs, instead the item is
// put back on the workqueue and attempted again after a back-off
// period.
defer
c
.
workqueue
.
Done
(
obj
)
var
key
string
var
ok
bool
// We expect strings to come off the workqueue. These are of the
// form namespace/name. We do this as the delayed nature of the
// workqueue means the items in the informer cache may actually be
// more up to date that when the item was initially put onto the
// workqueue.
if
key
,
ok
=
obj
.
(
string
);
!
ok
{
// As the item in the workqueue is actually invalid, we call
// Forget here else we'd go into a loop of attempting to
// process a work item that is invalid.
c
.
workqueue
.
Forget
(
obj
)
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"expected string in workqueue but got %#v"
,
obj
))
return
nil
}
// Run the reconcile, passing it the namespace/name string of the
// Foo resource to be synced.
if
err
:=
c
.
reconcile
(
key
);
err
!=
nil
{
// Put the item back on the workqueue to handle any transient errors.
c
.
workqueue
.
AddRateLimited
(
key
)
return
fmt
.
Errorf
(
"error syncing '%s': %s, requeuing"
,
key
,
err
.
Error
())
}
// Finally, if no error occurs we Forget this item so it does not
// get queued again until another change happens.
c
.
workqueue
.
Forget
(
obj
)
klog
.
Infof
(
"Successfully synced %s:%s"
,
"key"
,
key
)
return
nil
}(
obj
)
if
err
!=
nil
{
utilruntime
.
HandleError
(
err
)
return
true
}
return
true
}
// syncHandler compares the actual state with the desired, and attempts to
// converge the two. It then updates the Status block of the Foo resource
// with the current status of the resource.
func
(
c
*
Controller
)
reconcile
(
key
string
)
error
{
// Get the clusterRoleBinding with this name
globalRoleBinding
,
err
:=
c
.
lister
.
Get
(
key
)
if
err
!=
nil
{
// The user may no longer exist, in which case we stop
// processing.
if
errors
.
IsNotFound
(
err
)
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"clusterrolebinding '%s' in work queue no longer exists"
,
key
))
return
nil
}
klog
.
Error
(
err
)
return
err
}
isPlatformAdmin
:=
globalRoleBinding
.
RoleRef
.
Name
==
iamv1alpha2
.
PlatformAdmin
if
isPlatformAdmin
{
if
err
:=
c
.
relateToClusterAdmin
(
globalRoleBinding
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
}
c
.
recorder
.
Event
(
globalRoleBinding
,
corev1
.
EventTypeNormal
,
successSynced
,
messageResourceSynced
)
return
nil
}
func
(
c
*
Controller
)
Start
(
stopCh
<-
chan
struct
{})
error
{
return
c
.
Run
(
4
,
stopCh
)
}
func
(
c
*
Controller
)
relateToClusterAdmin
(
globalRoleBinding
*
iamv1alpha2
.
GlobalRoleBinding
)
error
{
if
c
.
multiClusterEnabled
{
federatedClusterRoleBinding
:=
&
iamv1alpha2
.
FederatedClusterRoleBinding
{
TypeMeta
:
metav1
.
TypeMeta
{
Kind
:
federatedClusterRoleBindingKind
,
APIVersion
:
federatedResourceVersion
,
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
fmt
.
Sprintf
(
"fed-%s"
,
globalRoleBinding
.
Name
),
},
Spec
:
iamv1alpha2
.
FederatedClusterRoleBindingSpec
{
Template
:
iamv1alpha2
.
Template
{
Subjects
:
ensureSubjectAPIVersionIsValid
(
globalRoleBinding
.
Subjects
),
RoleRef
:
rbacv1
.
RoleRef
{
APIGroup
:
"rbac.authorization.k8s.io"
,
Kind
:
iamv1alpha2
.
ResourceKindClusterRole
,
Name
:
iamv1alpha2
.
ClusterAdmin
,
},
},
Placement
:
iamv1alpha2
.
Placement
{
ClusterSelector
:
iamv1alpha2
.
ClusterSelector
{},
},
},
}
// rbac.authorization.k8s.io
err
:=
controllerutil
.
SetControllerReference
(
globalRoleBinding
,
federatedClusterRoleBinding
,
scheme
.
Scheme
)
if
err
!=
nil
{
return
err
}
data
,
err
:=
json
.
Marshal
(
federatedClusterRoleBinding
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Post
()
.
AbsPath
(
federatedResourceAPIPath
)
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
}
}
else
{
clusterRoleBinding
:=
&
rbacv1
.
ClusterRoleBinding
{
TypeMeta
:
metav1
.
TypeMeta
{},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
fmt
.
Sprintf
(
"fed-%s"
,
globalRoleBinding
.
Name
),
},
Subjects
:
ensureSubjectAPIVersionIsValid
(
globalRoleBinding
.
Subjects
),
RoleRef
:
rbacv1
.
RoleRef
{
APIGroup
:
"rbac.authorization.k8s.io"
,
Kind
:
iamv1alpha2
.
ResourceKindClusterRole
,
Name
:
iamv1alpha2
.
ClusterAdmin
,
},
}
err
:=
controllerutil
.
SetControllerReference
(
globalRoleBinding
,
clusterRoleBinding
,
scheme
.
Scheme
)
if
err
!=
nil
{
return
err
}
_
,
err
=
c
.
k8sClient
.
RbacV1
()
.
ClusterRoleBindings
()
.
Create
(
clusterRoleBinding
)
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
}
}
return
nil
}
func
ensureSubjectAPIVersionIsValid
(
subjects
[]
rbacv1
.
Subject
)
[]
rbacv1
.
Subject
{
validSubjects
:=
make
([]
rbacv1
.
Subject
,
0
)
for
_
,
subject
:=
range
subjects
{
if
subject
.
Kind
==
iamv1alpha2
.
ResourceKindUser
{
validSubject
:=
rbacv1
.
Subject
{
Kind
:
iamv1alpha2
.
ResourceKindUser
,
APIGroup
:
"rbac.authorization.k8s.io"
,
Name
:
subject
.
Name
,
}
validSubjects
=
append
(
validSubjects
,
validSubject
)
}
}
return
validSubjects
}
pkg/kapis/iam/v1alpha2/handler.go
浏览文件 @
ce3cd21a
...
...
@@ -10,7 +10,6 @@ import (
iamv1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
authoptions
"kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
"kubesphere.io/kubesphere/pkg/apiserver/query"
apirequeset
"kubesphere.io/kubesphere/pkg/apiserver/request"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/im"
servererr
"kubesphere.io/kubesphere/pkg/server/errors"
...
...
@@ -34,14 +33,7 @@ type Member struct {
RoleRef
string
`json:"roleRef"`
}
func
(
h
*
iamHandler
)
DescribeUserOrClusterMember
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
requestInfo
,
ok
:=
apirequeset
.
RequestInfoFrom
(
request
.
Request
.
Context
())
if
ok
&&
requestInfo
.
ResourceScope
==
apirequeset
.
ClusterScope
{
h
.
DescribeClusterMember
(
request
,
response
)
return
}
func
(
h
*
iamHandler
)
DescribeUser
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
username
:=
request
.
PathParameter
(
"user"
)
user
,
err
:=
h
.
im
.
DescribeUser
(
username
)
...
...
@@ -68,67 +60,121 @@ func (h *iamHandler) DescribeUserOrClusterMember(request *restful.Request, respo
response
.
WriteEntity
(
user
)
}
func
(
h
*
iamHandler
)
RetrieveMemberRole
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
username
:=
req
.
PathParameter
(
"user"
)
func
(
h
*
iamHandler
)
RetrieveMemberRole
Templates
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
username
:=
req
uest
.
PathParameter
(
"user"
)
if
strings
.
HasSuffix
(
req
.
Request
.
URL
.
Path
,
iamv1alpha2
.
ResourcesSingular
GlobalRole
)
{
if
strings
.
HasSuffix
(
req
uest
.
Request
.
URL
.
Path
,
iamv1alpha2
.
ResourcesPlural
GlobalRole
)
{
globalRole
,
err
:=
h
.
am
.
GetGlobalRoleOfUser
(
username
)
if
err
!=
nil
{
api
.
HandleInternalError
(
resp
,
req
,
err
)
api
.
HandleInternalError
(
response
,
request
,
err
)
return
}
result
,
err
:=
h
.
am
.
ListGlobalRoles
(
&
query
.
Query
{
Pagination
:
query
.
NoPagination
,
SortBy
:
""
,
Ascending
:
false
,
Filters
:
map
[
query
.
Field
]
query
.
Value
{
iamv1alpha2
.
AggregateTo
:
query
.
Value
(
globalRole
.
Name
)},
})
if
err
!=
nil
{
api
.
HandleInternalError
(
response
,
request
,
err
)
return
}
resp
.
WriteEntity
(
globalRole
)
response
.
WriteEntity
(
result
.
Items
)
return
}
if
strings
.
HasSuffix
(
req
.
Request
.
URL
.
Path
,
iamv1alpha2
.
ResourcesSingular
ClusterRole
)
{
if
strings
.
HasSuffix
(
req
uest
.
Request
.
URL
.
Path
,
iamv1alpha2
.
ResourcesPlural
ClusterRole
)
{
clusterRole
,
err
:=
h
.
am
.
GetClusterRoleOfUser
(
username
)
if
err
!=
nil
{
api
.
HandleInternalError
(
resp
,
req
,
err
)
api
.
HandleInternalError
(
response
,
request
,
err
)
return
}
result
,
err
:=
h
.
am
.
ListClusterRoles
(
&
query
.
Query
{
Pagination
:
query
.
NoPagination
,
SortBy
:
""
,
Ascending
:
false
,
Filters
:
map
[
query
.
Field
]
query
.
Value
{
iamv1alpha2
.
AggregateTo
:
query
.
Value
(
clusterRole
.
Name
)},
})
if
err
!=
nil
{
api
.
HandleInternalError
(
response
,
request
,
err
)
return
}
resp
.
WriteEntity
(
clusterRole
)
response
.
WriteEntity
(
result
.
Items
)
return
}
if
strings
.
HasSuffix
(
req
.
Request
.
URL
.
Path
,
iamv1alpha2
.
ResourcesSingular
WorkspaceRole
)
{
workspace
:=
req
.
PathParameter
(
"workspace"
)
if
strings
.
HasSuffix
(
req
uest
.
Request
.
URL
.
Path
,
iamv1alpha2
.
ResourcesPlural
WorkspaceRole
)
{
workspace
:=
req
uest
.
PathParameter
(
"workspace"
)
workspaceRole
,
err
:=
h
.
am
.
GetWorkspaceRoleOfUser
(
username
,
workspace
)
if
err
!=
nil
{
api
.
HandleInternalError
(
resp
,
req
,
err
)
api
.
HandleInternalError
(
response
,
request
,
err
)
return
}
result
,
err
:=
h
.
am
.
ListWorkspaceRoles
(
&
query
.
Query
{
Pagination
:
query
.
NoPagination
,
SortBy
:
""
,
Ascending
:
false
,
Filters
:
map
[
query
.
Field
]
query
.
Value
{
iamv1alpha2
.
AggregateTo
:
query
.
Value
(
workspaceRole
.
Name
)},
})
if
err
!=
nil
{
api
.
HandleInternalError
(
response
,
request
,
err
)
return
}
resp
.
WriteEntity
(
workspaceRole
)
resp
onse
.
WriteEntity
(
result
.
Items
)
return
}
if
strings
.
HasSuffix
(
req
.
Request
.
URL
.
Path
,
iamv1alpha2
.
ResourcesSingularRole
)
{
namespace
:=
req
.
PathParameter
(
"namespace"
)
if
strings
.
HasSuffix
(
request
.
Request
.
URL
.
Path
,
iamv1alpha2
.
ResourcesPluralRole
)
{
namespace
,
err
:=
h
.
resolveNamespace
(
request
.
PathParameter
(
"namespace"
),
request
.
PathParameter
(
"devops"
))
if
err
!=
nil
{
klog
.
Error
(
err
)
if
errors
.
IsNotFound
(
err
)
{
api
.
HandleNotFound
(
response
,
request
,
err
)
return
}
api
.
HandleInternalError
(
response
,
request
,
err
)
return
}
role
,
err
:=
h
.
am
.
GetNamespaceRoleOfUser
(
username
,
namespace
)
if
err
!=
nil
{
api
.
HandleInternalError
(
resp
,
req
,
err
)
api
.
HandleInternalError
(
resp
onse
,
request
,
err
)
return
}
resp
.
WriteEntity
(
role
)
return
}
}
func
(
h
*
iamHandler
)
ListUsersOrClusterMembers
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
requestInfo
,
ok
:=
apirequeset
.
RequestInfoFrom
(
request
.
Request
.
Context
())
result
,
err
:=
h
.
am
.
ListRoles
(
namespace
,
&
query
.
Query
{
Pagination
:
query
.
NoPagination
,
SortBy
:
""
,
Ascending
:
false
,
Filters
:
map
[
query
.
Field
]
query
.
Value
{
iamv1alpha2
.
AggregateTo
:
query
.
Value
(
role
.
Name
)},
})
if
err
!=
nil
{
api
.
HandleInternalError
(
response
,
request
,
err
)
return
}
if
ok
&&
requestInfo
.
ResourceScope
==
apirequeset
.
ClusterScope
{
h
.
ListClusterMembers
(
request
,
response
)
response
.
WriteEntity
(
result
.
Items
)
return
}
}
func
(
h
*
iamHandler
)
ListUsers
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
queryParam
:=
query
.
ParseQueryParameter
(
request
)
result
,
err
:=
h
.
im
.
ListUsers
(
queryParam
)
if
err
!=
nil
{
...
...
@@ -409,15 +455,7 @@ func (h *iamHandler) DeleteWorkspaceRole(request *restful.Request, response *res
response
.
WriteEntity
(
servererr
.
None
)
}
func
(
h
*
iamHandler
)
CreateUserOrClusterMembers
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
requestInfo
,
ok
:=
apirequeset
.
RequestInfoFrom
(
request
.
Request
.
Context
())
if
ok
&&
requestInfo
.
ResourceScope
==
apirequeset
.
ClusterScope
{
h
.
CreateClusterMembers
(
request
,
response
)
return
}
func
(
h
*
iamHandler
)
CreateUser
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
var
user
iamv1alpha2
.
User
err
:=
request
.
ReadEntity
(
&
user
)
...
...
@@ -477,14 +515,7 @@ func (h *iamHandler) CreateUserOrClusterMembers(request *restful.Request, respon
response
.
WriteEntity
(
created
)
}
func
(
h
*
iamHandler
)
UpdateUserOrClusterMember
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
requestInfo
,
ok
:=
apirequeset
.
RequestInfoFrom
(
request
.
Request
.
Context
())
if
ok
&&
requestInfo
.
ResourceScope
==
apirequeset
.
ClusterScope
{
h
.
UpdateClusterMember
(
request
,
response
)
return
}
func
(
h
*
iamHandler
)
UpdateUser
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
username
:=
request
.
PathParameter
(
"user"
)
var
user
iamv1alpha2
.
User
...
...
@@ -538,14 +569,7 @@ func (h *iamHandler) UpdateUserOrClusterMember(request *restful.Request, respons
response
.
WriteEntity
(
updated
)
}
func
(
h
*
iamHandler
)
DeleteUserOrClusterMember
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
requestInfo
,
ok
:=
apirequeset
.
RequestInfoFrom
(
request
.
Request
.
Context
())
if
ok
&&
requestInfo
.
ResourceScope
==
apirequeset
.
ClusterScope
{
h
.
RemoveClusterMember
(
request
,
response
)
return
}
func
(
h
*
iamHandler
)
DeleteUser
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
username
:=
request
.
PathParameter
(
"user"
)
err
:=
h
.
im
.
DeleteUser
(
username
)
...
...
@@ -1127,7 +1151,7 @@ func (h *iamHandler) CreateClusterMembers(request *restful.Request, response *re
}
func
(
h
*
iamHandler
)
RemoveClusterMember
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
username
:=
request
.
PathParameter
(
"
us
er"
)
username
:=
request
.
PathParameter
(
"
clustermemb
er"
)
err
:=
h
.
am
.
RemoveUserFromCluster
(
username
)
...
...
@@ -1145,7 +1169,7 @@ func (h *iamHandler) RemoveClusterMember(request *restful.Request, response *res
}
func
(
h
*
iamHandler
)
UpdateClusterMember
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
username
:=
request
.
PathParameter
(
"
us
er"
)
username
:=
request
.
PathParameter
(
"
clustermemb
er"
)
var
member
Member
...
...
@@ -1183,11 +1207,11 @@ func (h *iamHandler) UpdateClusterMember(request *restful.Request, response *res
}
func
(
h
*
iamHandler
)
DescribeClusterMember
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
username
:=
request
.
PathParameter
(
"
us
er"
)
username
:=
request
.
PathParameter
(
"
clustermemb
er"
)
queryParam
:=
query
.
New
()
queryParam
.
Filters
[
query
.
FieldName
]
=
query
.
Value
(
username
)
queryParam
.
Filters
[
iamv1alpha2
.
ScopeCluster
]
=
iamv1alpha2
.
LocalCluster
queryParam
.
Filters
[
iamv1alpha2
.
ScopeCluster
]
=
"true"
result
,
err
:=
h
.
im
.
ListUsers
(
queryParam
)
...
...
@@ -1208,7 +1232,7 @@ func (h *iamHandler) DescribeClusterMember(request *restful.Request, response *r
func
(
h
*
iamHandler
)
ListClusterMembers
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
queryParam
:=
query
.
ParseQueryParameter
(
request
)
queryParam
.
Filters
[
iamv1alpha2
.
ScopeCluster
]
=
iamv1alpha2
.
LocalCluster
queryParam
.
Filters
[
iamv1alpha2
.
ScopeCluster
]
=
"true"
result
,
err
:=
h
.
im
.
ListUsers
(
queryParam
)
...
...
pkg/kapis/iam/v1alpha2/register.go
浏览文件 @
ce3cd21a
...
...
@@ -44,33 +44,65 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
// users
ws
.
Route
(
ws
.
POST
(
"/users"
)
.
To
(
handler
.
CreateUser
OrClusterMembers
)
.
To
(
handler
.
CreateUser
)
.
Doc
(
"Create user in global scope."
)
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
iamv1alpha2
.
User
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
DELETE
(
"/users/{user}"
)
.
To
(
handler
.
DeleteUser
OrClusterMember
)
.
To
(
handler
.
DeleteUser
)
.
Doc
(
"Delete user."
)
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
errors
.
None
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
PUT
(
"/users/{user}"
)
.
To
(
handler
.
UpdateUser
OrClusterMember
)
.
To
(
handler
.
UpdateUser
)
.
Doc
(
"Update user info."
)
.
Reads
(
iamv1alpha2
.
User
{})
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
iamv1alpha2
.
User
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/users/{user}"
)
.
To
(
handler
.
DescribeUser
OrClusterMember
)
.
To
(
handler
.
DescribeUser
)
.
Doc
(
"Retrieve user details."
)
.
Param
(
ws
.
PathParameter
(
"user"
,
"username"
))
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
iamv1alpha2
.
User
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/users"
)
.
To
(
handler
.
ListUsers
OrClusterMembers
)
.
To
(
handler
.
ListUsers
)
.
Doc
(
"List all users."
)
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
api
.
ListResult
{
Items
:
[]
interface
{}{
iamv1alpha2
.
User
{}}})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
// clustermembers
ws
.
Route
(
ws
.
POST
(
"/clustermembers"
)
.
To
(
handler
.
CreateClusterMembers
)
.
Doc
(
"Add user to current cluster."
)
.
Reads
([]
Member
{})
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
errors
.
None
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
DELETE
(
"/clustermembers/{clustermember}"
)
.
To
(
handler
.
RemoveClusterMember
)
.
Doc
(
"Delete user from cluster scope."
)
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
errors
.
None
)
.
Param
(
ws
.
PathParameter
(
"clustermember"
,
"username"
))
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
PUT
(
"/clustermembers/{clustermember}"
)
.
To
(
handler
.
UpdateClusterMember
)
.
Doc
(
"Update user cluster role bind."
)
.
Reads
(
Member
{})
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
iamv1alpha2
.
User
{})
.
Param
(
ws
.
PathParameter
(
"clustermember"
,
"username"
))
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/clustermembers/{clustermember}"
)
.
To
(
handler
.
DescribeClusterMember
)
.
Doc
(
"Retrieve user details in cluster."
)
.
Param
(
ws
.
PathParameter
(
"clustermember"
,
"username"
))
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
iamv1alpha2
.
User
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/clustermembers"
)
.
To
(
handler
.
ListClusterMembers
)
.
Doc
(
"List all users in cluster."
)
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
api
.
ListResult
{
Items
:
[]
interface
{}{
iamv1alpha2
.
User
{}}})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}/users"
)
.
To
(
handler
.
ListWorkspaceMembers
)
.
Doc
(
"List all members in the specified workspace."
)
.
...
...
@@ -337,28 +369,35 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
rbacv1
.
ClusterRole
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/users/{user}/globalrole"
)
.
To
(
handler
.
RetrieveMemberRole
)
.
Doc
(
"Retrieve user's global role."
)
.
ws
.
Route
(
ws
.
GET
(
"/users/{user}/globalrole
s
"
)
.
To
(
handler
.
RetrieveMemberRole
Templates
)
.
Doc
(
"Retrieve user's global role
templates
."
)
.
Param
(
ws
.
PathParameter
(
"user"
,
"username"
))
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
iamv1alpha2
.
GlobalRole
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/users/{user}/clusterrole"
)
.
To
(
handler
.
RetrieveMemberRole
)
.
Doc
(
"Retrieve user's role in cluster."
)
.
ws
.
Route
(
ws
.
GET
(
"/users/{user}/clusterrole
s
"
)
.
To
(
handler
.
RetrieveMemberRole
Templates
)
.
Doc
(
"Retrieve user's role
templates
in cluster."
)
.
Param
(
ws
.
PathParameter
(
"user"
,
"username"
))
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
rbacv1
.
ClusterRole
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}/users/{user}/workspacerole"
)
.
To
(
handler
.
RetrieveMemberRole
)
.
Doc
(
"Retrieve member's role in workspace."
)
.
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}/users/{user}/workspacerole
s
"
)
.
To
(
handler
.
RetrieveMemberRole
Templates
)
.
Doc
(
"Retrieve member's role
templates
in workspace."
)
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace"
))
.
Param
(
ws
.
PathParameter
(
"user"
,
"username"
))
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
iamv1alpha2
.
WorkspaceRole
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/namespaces/{namespace}/users/{user}/role"
)
.
To
(
handler
.
RetrieveMemberRole
)
.
Doc
(
"Retrieve member's role in namespace."
)
.
ws
.
Route
(
ws
.
GET
(
"/namespaces/{namespace}/users/{user}/roles"
)
.
To
(
handler
.
RetrieveMemberRoleTemplates
)
.
Doc
(
"Retrieve member's role templates in namespace."
)
.
Param
(
ws
.
PathParameter
(
"namespace"
,
"namespace"
))
.
Param
(
ws
.
PathParameter
(
"user"
,
"username"
))
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
rbacv1
.
Role
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
AccessManagementTag
}))
ws
.
Route
(
ws
.
GET
(
"/devops/{devops}/users/{user}/roles"
)
.
To
(
handler
.
RetrieveMemberRoleTemplates
)
.
Doc
(
"Retrieve member's role templates in devops project."
)
.
Param
(
ws
.
PathParameter
(
"namespace"
,
"namespace"
))
.
Param
(
ws
.
PathParameter
(
"user"
,
"username"
))
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
rbacv1
.
Role
{})
.
...
...
pkg/kapis/tenant/v1alpha2/register.go
浏览文件 @
ce3cd21a
...
...
@@ -82,6 +82,12 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
Doc
(
"List clusters authorized to the specified workspace."
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
TenantResourcesTag
}))
ws
.
Route
(
ws
.
GET
(
"/namespaces"
)
.
To
(
handler
.
ListNamespaces
)
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Doc
(
"List the namespaces for the current user"
)
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
[]
corev1
.
Namespace
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
TenantResourcesTag
}))
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}/namespaces"
)
.
To
(
handler
.
ListNamespaces
)
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
...
...
pkg/models/iam/am/am.go
浏览文件 @
ce3cd21a
...
...
@@ -18,6 +18,7 @@ package am
import
(
"encoding/json"
"fmt"
corev1
"k8s.io/api/core/v1"
rbacv1
"k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
...
...
@@ -39,7 +40,7 @@ type AccessManagementInterface interface {
GetWorkspaceRoleOfUser
(
username
,
workspace
string
)
(
*
iamv1alpha2
.
WorkspaceRole
,
error
)
GetClusterRoleOfUser
(
username
string
)
(
*
rbacv1
.
ClusterRole
,
error
)
GetNamespaceRoleOfUser
(
username
,
namespace
string
)
(
*
rbacv1
.
Role
,
error
)
ListRoles
(
usernam
e
string
,
query
*
query
.
Query
)
(
*
api
.
ListResult
,
error
)
ListRoles
(
namespac
e
string
,
query
*
query
.
Query
)
(
*
api
.
ListResult
,
error
)
ListClusterRoles
(
query
*
query
.
Query
)
(
*
api
.
ListResult
,
error
)
ListWorkspaceRoles
(
query
*
query
.
Query
)
(
*
api
.
ListResult
,
error
)
ListGlobalRoles
(
query
*
query
.
Query
)
(
*
api
.
ListResult
,
error
)
...
...
@@ -70,6 +71,7 @@ type AccessManagementInterface interface {
CreateOrUpdateClusterRoleBinding
(
username
string
,
role
string
)
error
RemoveUserFromCluster
(
username
string
)
error
GetControlledNamespace
(
devops
string
)
(
string
,
error
)
GetControlledWorkspace
(
namespace
string
)
(
string
,
error
)
}
type
amOperator
struct
{
...
...
@@ -341,11 +343,11 @@ func contains(subjects []rbacv1.Subject, username string) bool {
}
func
(
am
*
amOperator
)
ListRoles
(
namespace
string
,
query
*
query
.
Query
)
(
*
api
.
ListResult
,
error
)
{
return
am
.
resourceGetter
.
List
(
"roles"
,
namespace
,
query
)
return
am
.
resourceGetter
.
List
(
iamv1alpha2
.
ResourcesPluralRole
,
namespace
,
query
)
}
func
(
am
*
amOperator
)
ListClusterRoles
(
query
*
query
.
Query
)
(
*
api
.
ListResult
,
error
)
{
return
am
.
resourceGetter
.
List
(
"clusterroles"
,
""
,
query
)
return
am
.
resourceGetter
.
List
(
iamv1alpha2
.
ResourcesPluralClusterRole
,
""
,
query
)
}
func
(
am
*
amOperator
)
ListWorkspaceRoles
(
queryParam
*
query
.
Query
)
(
*
api
.
ListResult
,
error
)
{
...
...
@@ -495,7 +497,7 @@ func (am *amOperator) CreateOrUpdateWorkspaceRoleBinding(username string, worksp
roleBinding
:=
iamv1alpha2
.
WorkspaceRoleBinding
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
fmt
.
Sprintf
(
"%s-%s
-%s"
,
workspace
,
username
,
rol
e
),
Name
:
fmt
.
Sprintf
(
"%s-%s
"
,
role
,
usernam
e
),
Labels
:
map
[
string
]
string
{
iamv1alpha2
.
UserReferenceLabel
:
username
,
tenantv1alpha1
.
WorkspaceLabel
:
workspace
},
},
...
...
@@ -833,30 +835,44 @@ func (am *amOperator) DeleteNamespaceRole(namespace string, name string) error {
}
// GetRoleReferenceRules attempts to resolve the RoleBinding or ClusterRoleBinding.
func
(
am
*
amOperator
)
GetRoleReferenceRules
(
roleRef
rbacv1
.
RoleRef
,
namespace
string
)
(
string
,
[]
rbacv1
.
PolicyRule
,
error
)
{
func
(
am
*
amOperator
)
GetRoleReferenceRules
(
roleRef
rbacv1
.
RoleRef
,
namespace
string
)
(
regoPolicy
string
,
rules
[]
rbacv1
.
PolicyRule
,
err
error
)
{
empty
:=
make
([]
rbacv1
.
PolicyRule
,
0
)
switch
roleRef
.
Kind
{
case
iamv1alpha2
.
ResourceKindRole
:
role
,
err
:=
am
.
GetNamespaceRole
(
namespace
,
roleRef
.
Name
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
""
,
empty
,
nil
}
return
""
,
nil
,
err
}
return
role
.
Annotations
[
iamv1alpha2
.
RegoOverrideAnnotation
],
role
.
Rules
,
nil
case
iamv1alpha2
.
ResourceKindClusterRole
:
clusterRole
,
err
:=
am
.
GetClusterRole
(
roleRef
.
Name
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
""
,
empty
,
nil
}
return
""
,
nil
,
err
}
return
clusterRole
.
Annotations
[
iamv1alpha2
.
RegoOverrideAnnotation
],
clusterRole
.
Rules
,
nil
case
iamv1alpha2
.
ResourceKindGlobalRole
:
globalRole
,
err
:=
am
.
GetGlobalRole
(
roleRef
.
Name
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
""
,
empty
,
nil
}
return
""
,
nil
,
err
}
return
globalRole
.
Annotations
[
iamv1alpha2
.
RegoOverrideAnnotation
],
globalRole
.
Rules
,
nil
case
iamv1alpha2
.
ResourceKindWorkspaceRole
:
workspaceRole
,
err
:=
am
.
GetWorkspaceRole
(
""
,
roleRef
.
Name
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
""
,
empty
,
nil
}
return
""
,
nil
,
err
}
return
workspaceRole
.
Annotations
[
iamv1alpha2
.
RegoOverrideAnnotation
],
workspaceRole
.
Rules
,
nil
...
...
@@ -910,3 +926,16 @@ func (am *amOperator) GetControlledNamespace(devops string) (string, error) {
return
devopsProject
.
Status
.
AdminNamespace
,
nil
}
func
(
am
*
amOperator
)
GetControlledWorkspace
(
namespace
string
)
(
string
,
error
)
{
obj
,
err
:=
am
.
resourceGetter
.
Get
(
"namespaces"
,
""
,
namespace
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
""
,
nil
}
klog
.
Error
(
err
)
return
""
,
err
}
ns
:=
obj
.
(
*
corev1
.
Namespace
)
return
ns
.
Labels
[
tenantv1alpha1
.
WorkspaceLabel
],
nil
}
pkg/models/iam/im/im.go
浏览文件 @
ce3cd21a
...
...
@@ -70,6 +70,7 @@ func (im *defaultIMOperator) UpdateUser(user *iamv1alpha2.User) (*iamv1alpha2.Us
old
:=
obj
.
(
*
iamv1alpha2
.
User
)
.
DeepCopy
()
user
.
Annotations
[
iamv1alpha2
.
PasswordEncryptedAnnotation
]
=
old
.
Annotations
[
iamv1alpha2
.
PasswordEncryptedAnnotation
]
user
.
Spec
.
EncryptedPassword
=
old
.
Spec
.
EncryptedPassword
user
.
Status
=
old
.
Status
return
im
.
ksClient
.
IamV1alpha2
()
.
Users
()
.
Update
(
user
)
}
...
...
pkg/models/resources/v1alpha3/role/roles.go
浏览文件 @
ce3cd21a
...
...
@@ -107,7 +107,7 @@ func (d *rolesGetter) fetchAggregationRoles(namespace, name string) ([]*rbacv1.R
if
err
=
json
.
Unmarshal
([]
byte
(
annotation
),
&
roleNames
);
err
==
nil
{
for
_
,
roleName
:=
range
roleNames
{
role
,
err
:=
d
.
Get
(
""
,
roleName
)
role
,
err
:=
d
.
Get
(
namespace
,
roleName
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
...
...
pkg/models/resources/v1alpha3/user/users.go
浏览文件 @
ce3cd21a
...
...
@@ -58,7 +58,7 @@ func (d *usersGetter) List(_ string, query *query.Query) (*api.ListResult, error
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
==
iamv1alpha2
.
LocalCluster
{
}
else
if
cluster
:=
query
.
Filters
[
iamv1alpha2
.
ScopeCluster
];
cluster
==
"true"
{
clusterRole
:=
query
.
Filters
[
iamv1alpha2
.
ResourcesSingularClusterRole
]
users
,
err
=
d
.
listAllUsersInCluster
(
string
(
clusterRole
))
delete
(
query
.
Filters
,
iamv1alpha2
.
ScopeCluster
)
...
...
pkg/models/tenant/tenant.go
浏览文件 @
ce3cd21a
...
...
@@ -183,7 +183,9 @@ func (t *tenantOperator) ListNamespaces(user user.Info, workspace string, queryP
if
decision
==
authorizer
.
DecisionAllow
{
queryParam
.
Filters
[
query
.
FieldLabel
]
=
query
.
Value
(
fmt
.
Sprintf
(
"%s=%s"
,
tenantv1alpha1
.
WorkspaceLabel
,
workspace
))
if
workspace
!=
""
{
queryParam
.
Filters
[
query
.
FieldLabel
]
=
query
.
Value
(
fmt
.
Sprintf
(
"%s=%s"
,
tenantv1alpha1
.
WorkspaceLabel
,
workspace
))
}
result
,
err
:=
t
.
resourceGetter
.
List
(
"namespaces"
,
""
,
queryParam
)
...
...
@@ -213,7 +215,7 @@ func (t *tenantOperator) ListNamespaces(user user.Info, workspace string, queryP
}
// skip if not controlled by the specified workspace
if
ns
:=
namespace
.
(
*
corev1
.
Namespace
);
ns
.
Labels
[
tenantv1alpha1
.
WorkspaceLabel
]
!=
workspace
{
if
ns
:=
namespace
.
(
*
corev1
.
Namespace
);
workspace
!=
""
&&
ns
.
Labels
[
tenantv1alpha1
.
WorkspaceLabel
]
!=
workspace
{
continue
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录