Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
KubeSphere
kubesphere
提交
4fcaa78b
K
kubesphere
项目概览
KubeSphere
/
kubesphere
通知
138
Star
32
Fork
5
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
2
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kubesphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
2
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
4fcaa78b
编写于
6月 15, 2020
作者:
H
hongming
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
improve multicluster resource controller
Signed-off-by:
N
hongming
<
talonwan@yunify.com
>
上级
61d827db
变更
51
隐藏空白更改
内联
并排
Showing
51 changed file
with
3560 addition
and
358 deletion
+3560
-358
cmd/controller-manager/app/controllers.go
cmd/controller-manager/app/controllers.go
+95
-6
config/crds/iam.kubesphere.io_federatedclusterrolebindings.yaml
.../crds/iam.kubesphere.io_federatedclusterrolebindings.yaml
+0
-125
config/crds/iam.kubesphere.io_rolebases.yaml
config/crds/iam.kubesphere.io_rolebases.yaml
+50
-0
config/crds/tenant.kubesphere.io_workspacetemplates.yaml
config/crds/tenant.kubesphere.io_workspacetemplates.yaml
+29
-0
pkg/apis/iam/v1alpha2/federated_types.go
pkg/apis/iam/v1alpha2/federated_types.go
+161
-0
pkg/apis/iam/v1alpha2/register.go
pkg/apis/iam/v1alpha2/register.go
+2
-1
pkg/apis/iam/v1alpha2/types.go
pkg/apis/iam/v1alpha2/types.go
+13
-20
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
+179
-17
pkg/apis/tenant/v1alpha2/workspacetemplate_types.go
pkg/apis/tenant/v1alpha2/workspacetemplate_types.go
+60
-1
pkg/apis/tenant/v1alpha2/zz_generated.deepcopy.go
pkg/apis/tenant/v1alpha2/zz_generated.deepcopy.go
+163
-1
pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_iam_client.go
...tset/versioned/typed/iam/v1alpha2/fake/fake_iam_client.go
+4
-0
pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_rolebase.go
...entset/versioned/typed/iam/v1alpha2/fake/fake_rolebase.go
+120
-0
pkg/client/clientset/versioned/typed/iam/v1alpha2/generated_expansion.go
...ntset/versioned/typed/iam/v1alpha2/generated_expansion.go
+2
-0
pkg/client/clientset/versioned/typed/iam/v1alpha2/iam_client.go
...ient/clientset/versioned/typed/iam/v1alpha2/iam_client.go
+5
-0
pkg/client/clientset/versioned/typed/iam/v1alpha2/rolebase.go
...client/clientset/versioned/typed/iam/v1alpha2/rolebase.go
+164
-0
pkg/client/clientset/versioned/typed/storage/v1alpha1/doc.go
pkg/client/clientset/versioned/typed/storage/v1alpha1/doc.go
+1
-1
pkg/client/clientset/versioned/typed/storage/v1alpha1/fake/doc.go
...nt/clientset/versioned/typed/storage/v1alpha1/fake/doc.go
+1
-1
pkg/client/clientset/versioned/typed/storage/v1alpha1/fake/fake_storage_client.go
...sioned/typed/storage/v1alpha1/fake/fake_storage_client.go
+1
-1
pkg/client/clientset/versioned/typed/storage/v1alpha1/fake/fake_storageclasscapability.go
...yped/storage/v1alpha1/fake/fake_storageclasscapability.go
+1
-1
pkg/client/clientset/versioned/typed/storage/v1alpha1/generated_expansion.go
...t/versioned/typed/storage/v1alpha1/generated_expansion.go
+1
-1
pkg/client/clientset/versioned/typed/storage/v1alpha1/storage_client.go
...entset/versioned/typed/storage/v1alpha1/storage_client.go
+1
-1
pkg/client/clientset/versioned/typed/storage/v1alpha1/storageclasscapability.go
...ersioned/typed/storage/v1alpha1/storageclasscapability.go
+1
-1
pkg/client/informers/externalversions/generic.go
pkg/client/informers/externalversions/generic.go
+2
-0
pkg/client/informers/externalversions/iam/v1alpha2/interface.go
...ient/informers/externalversions/iam/v1alpha2/interface.go
+7
-0
pkg/client/informers/externalversions/iam/v1alpha2/rolebase.go
...lient/informers/externalversions/iam/v1alpha2/rolebase.go
+88
-0
pkg/client/informers/externalversions/storage/interface.go
pkg/client/informers/externalversions/storage/interface.go
+1
-1
pkg/client/informers/externalversions/storage/v1alpha1/interface.go
.../informers/externalversions/storage/v1alpha1/interface.go
+1
-1
pkg/client/informers/externalversions/storage/v1alpha1/storageclasscapability.go
...ternalversions/storage/v1alpha1/storageclasscapability.go
+1
-1
pkg/client/listers/iam/v1alpha2/expansion_generated.go
pkg/client/listers/iam/v1alpha2/expansion_generated.go
+4
-0
pkg/client/listers/iam/v1alpha2/rolebase.go
pkg/client/listers/iam/v1alpha2/rolebase.go
+65
-0
pkg/client/listers/storage/v1alpha1/expansion_generated.go
pkg/client/listers/storage/v1alpha1/expansion_generated.go
+1
-1
pkg/client/listers/storage/v1alpha1/storageclasscapability.go
...client/listers/storage/v1alpha1/storageclasscapability.go
+1
-1
pkg/constants/constants.go
pkg/constants/constants.go
+1
-0
pkg/controller/certificatesigningrequest/certificatesigningrequest_controller.go
...atesigningrequest/certificatesigningrequest_controller.go
+7
-16
pkg/controller/clusterrolebinding/clusterrolebinding_controller.go
...oller/clusterrolebinding/clusterrolebinding_controller.go
+1
-3
pkg/controller/globalrole/globalrole_controller.go
pkg/controller/globalrole/globalrole_controller.go
+354
-0
pkg/controller/globalrolebinding/globalrolebinding_controller.go
...troller/globalrolebinding/globalrolebinding_controller.go
+197
-84
pkg/controller/namespace/namespace_controller.go
pkg/controller/namespace/namespace_controller.go
+108
-13
pkg/controller/user/user_controller.go
pkg/controller/user/user_controller.go
+184
-30
pkg/controller/user/user_controller_test.go
pkg/controller/user/user_controller_test.go
+1
-1
pkg/controller/workspace/workspace_controller.go
pkg/controller/workspace/workspace_controller.go
+50
-0
pkg/controller/workspacerole/workspacerole.go
pkg/controller/workspacerole/workspacerole.go
+354
-0
pkg/controller/workspacerolebinding/workspacerolebinding_controller.go
...r/workspacerolebinding/workspacerolebinding_controller.go
+432
-0
pkg/controller/workspacetemplate/workspacetemplate_controller.go
...troller/workspacetemplate/workspacetemplate_controller.go
+494
-0
pkg/kapis/resources/v1alpha2/handler.go
pkg/kapis/resources/v1alpha2/handler.go
+1
-1
pkg/kapis/tenant/v1alpha2/handler.go
pkg/kapis/tenant/v1alpha2/handler.go
+23
-0
pkg/kapis/tenant/v1alpha2/register.go
pkg/kapis/tenant/v1alpha2/register.go
+7
-2
pkg/models/iam/am/am.go
pkg/models/iam/am/am.go
+6
-6
pkg/models/iam/im/im.go
pkg/models/iam/im/im.go
+9
-8
pkg/models/kubeconfig/kubeconfig.go
pkg/models/kubeconfig/kubeconfig.go
+21
-11
pkg/models/tenant/tenant.go
pkg/models/tenant/tenant.go
+85
-0
未找到文件。
cmd/controller-manager/app/controllers.go
浏览文件 @
4fcaa78b
...
...
@@ -18,7 +18,11 @@ package app
import
(
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/cache"
"k8s.io/klog"
iamv1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
tenantv1alpha2
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha2"
"kubesphere.io/kubesphere/pkg/controller/application"
"kubesphere.io/kubesphere/pkg/controller/certificatesigningrequest"
"kubesphere.io/kubesphere/pkg/controller/cluster"
...
...
@@ -26,6 +30,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/globalrole"
"kubesphere.io/kubesphere/pkg/controller/globalrolebinding"
"kubesphere.io/kubesphere/pkg/controller/job"
"kubesphere.io/kubesphere/pkg/controller/network/nsnetworkpolicy"
...
...
@@ -37,11 +42,15 @@ import (
"kubesphere.io/kubesphere/pkg/controller/storage/expansion"
"kubesphere.io/kubesphere/pkg/controller/user"
"kubesphere.io/kubesphere/pkg/controller/virtualservice"
"kubesphere.io/kubesphere/pkg/controller/workspacerole"
"kubesphere.io/kubesphere/pkg/controller/workspacerolebinding"
"kubesphere.io/kubesphere/pkg/controller/workspacetemplate"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/s3"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/kubefed/pkg/controller/util"
)
func
AddControllers
(
...
...
@@ -133,16 +142,86 @@ func AddControllers(
kubernetesInformer
.
Apps
()
.
V1
()
.
ReplicaSets
(),
kubernetesInformer
.
Apps
()
.
V1
()
.
StatefulSets
())
var
fedUserCache
,
fedGlobalRoleBindingCache
,
fedGlobalRoleCache
,
fedWorkspaceCache
,
fedWorkspaceRoleCache
,
fedWorkspaceRoleBindingCache
cache
.
Store
var
fedUserCacheController
,
fedGlobalRoleBindingCacheController
,
fedGlobalRoleCacheController
,
fedWorkspaceCacheController
,
fedWorkspaceRoleCacheController
,
fedWorkspaceRoleBindingCacheController
cache
.
Controller
if
multiClusterEnabled
{
fedUserClient
,
err
:=
util
.
NewResourceClient
(
client
.
Config
(),
&
iamv1alpha2
.
FedUserResource
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
fedGlobalRoleClient
,
err
:=
util
.
NewResourceClient
(
client
.
Config
(),
&
iamv1alpha2
.
FedGlobalRoleResource
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
fedGlobalRoleBindingClient
,
err
:=
util
.
NewResourceClient
(
client
.
Config
(),
&
iamv1alpha2
.
FedGlobalRoleBindingResource
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
fedWorkspaceClient
,
err
:=
util
.
NewResourceClient
(
client
.
Config
(),
&
tenantv1alpha2
.
FedWorkspaceResource
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
fedWorkspaceRoleClient
,
err
:=
util
.
NewResourceClient
(
client
.
Config
(),
&
iamv1alpha2
.
FedWorkspaceRoleResource
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
fedWorkspaceRoleBindingClient
,
err
:=
util
.
NewResourceClient
(
client
.
Config
(),
&
iamv1alpha2
.
FedWorkspaceRoleBindingResource
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
fedUserCache
,
fedUserCacheController
=
util
.
NewResourceInformer
(
fedUserClient
,
""
,
&
iamv1alpha2
.
FedUserResource
,
func
(
object
runtime
.
Object
)
{})
fedGlobalRoleCache
,
fedGlobalRoleCacheController
=
util
.
NewResourceInformer
(
fedGlobalRoleClient
,
""
,
&
iamv1alpha2
.
FedGlobalRoleResource
,
func
(
object
runtime
.
Object
)
{})
fedGlobalRoleBindingCache
,
fedGlobalRoleBindingCacheController
=
util
.
NewResourceInformer
(
fedGlobalRoleBindingClient
,
""
,
&
iamv1alpha2
.
FedGlobalRoleBindingResource
,
func
(
object
runtime
.
Object
)
{})
fedWorkspaceCache
,
fedWorkspaceCacheController
=
util
.
NewResourceInformer
(
fedWorkspaceClient
,
""
,
&
tenantv1alpha2
.
FedWorkspaceResource
,
func
(
object
runtime
.
Object
)
{})
fedWorkspaceRoleCache
,
fedWorkspaceRoleCacheController
=
util
.
NewResourceInformer
(
fedWorkspaceRoleClient
,
""
,
&
iamv1alpha2
.
FedWorkspaceRoleResource
,
func
(
object
runtime
.
Object
)
{})
fedWorkspaceRoleBindingCache
,
fedWorkspaceRoleBindingCacheController
=
util
.
NewResourceInformer
(
fedWorkspaceRoleBindingClient
,
""
,
&
iamv1alpha2
.
FedWorkspaceRoleBindingResource
,
func
(
object
runtime
.
Object
)
{})
go
fedUserCacheController
.
Run
(
stopCh
)
go
fedGlobalRoleCacheController
.
Run
(
stopCh
)
go
fedGlobalRoleBindingCacheController
.
Run
(
stopCh
)
go
fedWorkspaceCacheController
.
Run
(
stopCh
)
go
fedWorkspaceRoleCacheController
.
Run
(
stopCh
)
go
fedWorkspaceRoleBindingCacheController
.
Run
(
stopCh
)
}
userController
:=
user
.
NewController
(
client
.
Kubernetes
(),
client
.
KubeSphere
(),
client
.
Config
(),
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
Users
())
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
Users
(),
fedUserCache
,
fedUserCacheController
,
kubernetesInformer
.
Core
()
.
V1
()
.
ConfigMaps
(),
multiClusterEnabled
)
csrController
:=
certificatesigningrequest
.
NewController
(
client
.
Kubernetes
(),
kubernetesInformer
,
client
.
Config
())
csrController
:=
certificatesigningrequest
.
NewController
(
client
.
Kubernetes
(),
kubernetesInformer
.
Certificates
()
.
V1beta1
()
.
CertificateSigningRequests
(),
kubernetesInformer
.
Core
()
.
V1
()
.
ConfigMaps
(),
client
.
Config
())
clusterRoleBindingController
:=
clusterrolebinding
.
NewController
(
client
.
Kubernetes
(),
kubernetesInformer
.
Rbac
()
.
V1
()
.
ClusterRoleBindings
(),
kubernetesInformer
.
Apps
()
.
V1
()
.
Deployments
(),
kubernetesInformer
.
Core
()
.
V1
()
.
Pods
(),
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
Users
())
globalRoleBindingController
:=
globalrolebinding
.
NewController
(
client
.
Kubernetes
(),
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
GlobalRoleBindings
(),
multiClusterEnabled
)
globalRoleController
:=
globalrole
.
NewController
(
client
.
Kubernetes
(),
client
.
KubeSphere
(),
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
GlobalRoles
(),
fedGlobalRoleCache
,
fedGlobalRoleCacheController
)
workspaceRoleController
:=
workspacerole
.
NewController
(
client
.
Kubernetes
(),
client
.
KubeSphere
(),
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
WorkspaceRoles
(),
fedWorkspaceRoleCache
,
fedWorkspaceRoleCacheController
)
globalRoleBindingController
:=
globalrolebinding
.
NewController
(
client
.
Kubernetes
(),
client
.
KubeSphere
(),
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
GlobalRoleBindings
(),
fedGlobalRoleBindingCache
,
fedGlobalRoleBindingCacheController
,
multiClusterEnabled
)
workspaceRoleBindingController
:=
workspacerolebinding
.
NewController
(
client
.
Kubernetes
(),
client
.
KubeSphere
(),
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
WorkspaceRoleBindings
(),
fedWorkspaceRoleBindingCache
,
fedWorkspaceRoleBindingCacheController
)
workspaceTemplateController
:=
workspacetemplate
.
NewController
(
client
.
Kubernetes
(),
client
.
KubeSphere
(),
kubesphereInformer
.
Tenant
()
.
V1alpha2
()
.
WorkspaceTemplates
(),
kubesphereInformer
.
Tenant
()
.
V1alpha1
()
.
Workspaces
(),
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
RoleBases
(),
kubesphereInformer
.
Iam
()
.
V1alpha2
()
.
WorkspaceRoles
(),
fedWorkspaceCache
,
fedWorkspaceCacheController
,
multiClusterEnabled
)
clusterController
:=
cluster
.
NewClusterController
(
client
.
Kubernetes
(),
...
...
@@ -169,21 +248,31 @@ func AddControllers(
"s2ibinary-controller"
:
s2iBinaryController
,
"s2irun-controller"
:
s2iRunController
,
"volumeexpansion-controller"
:
volumeExpansionController
,
"devopsprojects-controller"
:
devopsProjectController
,
"pipeline-controller"
:
devopsPipelineController
,
"devopscredential-controller"
:
devopsCredentialController
,
"user-controller"
:
userController
,
"cluster-controller"
:
clusterController
,
"nsnp-controller"
:
nsnpController
,
"csr-controller"
:
csrController
,
"clusterrolebinding-controller"
:
clusterRoleBindingController
,
"globalrolebinding-controller"
:
globalRoleBindingController
,
"workspacetemplate-controller"
:
workspaceTemplateController
,
}
if
devopsClient
!=
nil
{
controllers
[
"pipeline-controller"
]
=
devopsPipelineController
controllers
[
"devopsprojects-controller"
]
=
devopsProjectController
controllers
[
"devopscredential-controller"
]
=
devopsCredentialController
}
if
storageCapabilityController
.
IsValidKubernetesVersion
()
{
controllers
[
"storagecapability-controller"
]
=
storageCapabilityController
}
if
multiClusterEnabled
{
controllers
[
"globalrole-controller"
]
=
globalRoleController
controllers
[
"workspacerole-controller"
]
=
workspaceRoleController
controllers
[
"workspacerolebinding-controller"
]
=
workspaceRoleBindingController
}
for
name
,
ctrl
:=
range
controllers
{
if
err
:=
mgr
.
Add
(
ctrl
);
err
!=
nil
{
klog
.
Error
(
err
,
"add controller to manager failed"
,
"name"
,
name
)
...
...
config/crds/iam.kubesphere.io_federatedclusterrolebindings.yaml
已删除
100644 → 0
浏览文件 @
61d827db
---
apiVersion
:
apiextensions.k8s.io/v1beta1
kind
:
CustomResourceDefinition
metadata
:
annotations
:
controller-gen.kubebuilder.io/version
:
(devel)
creationTimestamp
:
null
name
:
federatedclusterrolebindings.iam.kubesphere.io
spec
:
group
:
iam.kubesphere.io
names
:
kind
:
FederatedClusterRoleBinding
listKind
:
FederatedClusterRoleBindingList
plural
:
federatedclusterrolebindings
singular
:
federatedclusterrolebinding
scope
:
Namespaced
validation
:
openAPIV3Schema
:
properties
:
apiVersion
:
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
kind
:
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
metadata
:
type
:
object
spec
:
properties
:
placement
:
properties
:
clusterSelector
:
properties
:
matchLabels
:
additionalProperties
:
type
:
string
type
:
object
type
:
object
clusters
:
items
:
properties
:
name
:
type
:
string
required
:
-
name
type
:
object
type
:
array
type
:
object
template
:
properties
:
roleRef
:
description
:
RoleRef contains information that points to the role
being used
properties
:
apiGroup
:
description
:
APIGroup is the group for the resource being referenced
type
:
string
kind
:
description
:
Kind is the type of resource being referenced
type
:
string
name
:
description
:
Name is the name of resource being referenced
type
:
string
required
:
-
apiGroup
-
kind
-
name
type
:
object
subjects
:
items
:
description
:
Subject contains a reference to the object or user
identities a role binding applies to. This can either hold
a direct API object reference, or a value for non-objects such
as user and group names.
properties
:
apiGroup
:
description
:
APIGroup holds the API group of the referenced
subject. Defaults to "" for ServiceAccount subjects. Defaults
to "rbac.authorization.k8s.io" for User and Group subjects.
type
:
string
kind
:
description
:
Kind of object being referenced. Values defined
by this API group are "User", "Group", and "ServiceAccount".
If the Authorizer does not recognized the kind value, the
Authorizer should report an error.
type
:
string
name
:
description
:
Name of the object being referenced.
type
:
string
namespace
:
description
:
Namespace of the referenced object. If the object
kind is non-namespace, such as "User" or "Group", and this
value is not empty the Authorizer should report an error.
type
:
string
required
:
-
kind
-
name
type
:
object
type
:
array
required
:
-
roleRef
type
:
object
required
:
-
placement
-
template
type
:
object
required
:
-
spec
type
:
object
version
:
v1alpha2
versions
:
-
name
:
v1alpha2
served
:
true
storage
:
true
status
:
acceptedNames
:
kind
:
"
"
plural
:
"
"
conditions
:
[]
storedVersions
:
[]
config/crds/iam.kubesphere.io_rolebases.yaml
0 → 100644
浏览文件 @
4fcaa78b
---
apiVersion
:
apiextensions.k8s.io/v1beta1
kind
:
CustomResourceDefinition
metadata
:
annotations
:
controller-gen.kubebuilder.io/version
:
(devel)
creationTimestamp
:
null
name
:
rolebases.iam.kubesphere.io
spec
:
group
:
iam.kubesphere.io
names
:
categories
:
-
iam
kind
:
RoleBase
listKind
:
RoleBaseList
plural
:
rolebases
singular
:
rolebase
scope
:
Cluster
validation
:
openAPIV3Schema
:
properties
:
apiVersion
:
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
kind
:
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
metadata
:
type
:
object
role
:
type
:
object
required
:
-
role
type
:
object
version
:
v1alpha2
versions
:
-
name
:
v1alpha2
served
:
true
storage
:
true
status
:
acceptedNames
:
kind
:
"
"
plural
:
"
"
conditions
:
[]
storedVersions
:
[]
config/crds/tenant.kubesphere.io_workspacetemplates.yaml
浏览文件 @
4fcaa78b
...
...
@@ -44,6 +44,35 @@ spec:
type
:
string
networkIsolation
:
type
:
boolean
overrides
:
items
:
properties
:
clusterName
:
type
:
string
clusterOverrides
:
items
:
properties
:
op
:
type
:
string
path
:
type
:
string
value
:
anyOf
:
-
type
:
string
-
type
:
integer
-
type
:
boolean
-
type
:
object
-
type
:
array
required
:
-
path
-
value
type
:
object
type
:
array
required
:
-
clusterName
-
clusterOverrides
type
:
object
type
:
array
type
:
object
type
:
object
version
:
v1alpha2
...
...
pkg/apis/iam/v1alpha2/federated_types.go
0 → 100644
浏览文件 @
4fcaa78b
/*
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.
*/
package
v1alpha2
import
(
rbacv1
"k8s.io/api/rbac/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
const
(
ResourcesSingularFedUser
=
"federateduser"
ResourcesSingularFedGlobalRoleBinding
=
"federatedglobalrolebinding"
ResourcesSingularFedWorkspaceRoleBinding
=
"federatedworkspacerolebinding"
ResourcesSingularFedGlobalRole
=
"federatedglobalrole"
ResourcesSingularFedWorkspaceRole
=
"federatedworkspacerole"
ResourcesPluralFedUser
=
"federatedusers"
ResourcesPluralFedGlobalRoleBinding
=
"federatedglobalrolebindings"
ResourcesPluralFedWorkspaceRoleBinding
=
"federatedworkspacerolebindings"
ResourcesPluralFedGlobalRole
=
"federatedglobalroles"
ResourcesPluralFedWorkspaceRole
=
"federatedworkspaceroles"
FedClusterRoleBindingKind
=
"FederatedClusterRoleBinding"
FedClusterRoleKind
=
"FederatedClusterRole"
FedGlobalRoleKind
=
"FederatedGlobalRole"
FedWorkspaceRoleKind
=
"FederatedWorkspaceRole"
FedGlobalRoleBindingKind
=
"FederatedGlobalRoleBinding"
FedWorkspaceRoleBindingKind
=
"FederatedWorkspaceRoleBinding"
fedResourceGroup
=
"types.kubefed.io"
fedResourceVersion
=
"v1beta1"
FedUserKind
=
"FederatedUser"
)
var
(
FedUserResource
=
metav1
.
APIResource
{
Name
:
ResourcesPluralFedUser
,
SingularName
:
ResourcesSingularFedUser
,
Namespaced
:
false
,
Group
:
fedResourceGroup
,
Version
:
fedResourceVersion
,
Kind
:
FedUserKind
,
}
FedGlobalRoleBindingResource
=
metav1
.
APIResource
{
Name
:
ResourcesPluralFedGlobalRoleBinding
,
SingularName
:
ResourcesSingularFedGlobalRoleBinding
,
Namespaced
:
false
,
Group
:
fedResourceGroup
,
Version
:
fedResourceVersion
,
Kind
:
FedGlobalRoleBindingKind
,
}
FedWorkspaceRoleBindingResource
=
metav1
.
APIResource
{
Name
:
ResourcesPluralFedWorkspaceRoleBinding
,
SingularName
:
ResourcesSingularFedWorkspaceRoleBinding
,
Namespaced
:
false
,
Group
:
fedResourceGroup
,
Version
:
fedResourceVersion
,
Kind
:
FedWorkspaceRoleBindingKind
,
}
FedGlobalRoleResource
=
metav1
.
APIResource
{
Name
:
ResourcesPluralFedGlobalRole
,
SingularName
:
ResourcesSingularFedGlobalRole
,
Namespaced
:
false
,
Group
:
fedResourceGroup
,
Version
:
fedResourceVersion
,
Kind
:
FedGlobalRoleKind
,
}
FedWorkspaceRoleResource
=
metav1
.
APIResource
{
Name
:
ResourcesPluralFedWorkspaceRole
,
SingularName
:
ResourcesSingularFedWorkspaceRole
,
Namespaced
:
false
,
Group
:
fedResourceGroup
,
Version
:
fedResourceVersion
,
Kind
:
FedWorkspaceRoleKind
,
}
FederatedClusterRoleBindingResource
=
schema
.
GroupVersionResource
{
Group
:
fedResourceGroup
,
Version
:
fedResourceVersion
,
Resource
:
"federatedclusterrolebindings"
,
}
)
type
FederatedRoleBinding
struct
{
metav1
.
TypeMeta
`json:",inline"`
metav1
.
ObjectMeta
`json:"metadata,omitempty"`
Spec
FederatedRoleBindingSpec
`json:"spec"`
}
type
FederatedRoleBindingSpec
struct
{
Template
RoleBindingTemplate
`json:"template"`
Placement
Placement
`json:"placement"`
}
type
RoleBindingTemplate
struct
{
metav1
.
ObjectMeta
`json:"metadata,omitempty"`
Subjects
[]
rbacv1
.
Subject
`json:"subjects,omitempty"`
RoleRef
rbacv1
.
RoleRef
`json:"roleRef"`
}
type
FederatedRole
struct
{
metav1
.
TypeMeta
`json:",inline"`
metav1
.
ObjectMeta
`json:"metadata,omitempty"`
Spec
FederatedRoleSpec
`json:"spec"`
}
type
FederatedRoleSpec
struct
{
Template
RoleTemplate
`json:"template"`
Placement
Placement
`json:"placement"`
}
type
RoleTemplate
struct
{
metav1
.
ObjectMeta
`json:"metadata,omitempty"`
// +optional
Rules
[]
rbacv1
.
PolicyRule
`json:"rules" protobuf:"bytes,2,rep,name=rules"`
}
type
FederatedUser
struct
{
metav1
.
TypeMeta
`json:",inline"`
metav1
.
ObjectMeta
`json:"metadata,omitempty"`
Spec
FederatedUserSpec
`json:"spec"`
}
type
FederatedUserSpec
struct
{
Template
UserTemplate
`json:"template"`
Placement
Placement
`json:"placement"`
}
type
UserTemplate
struct
{
metav1
.
ObjectMeta
`json:"metadata,omitempty"`
Spec
UserSpec
`json:"spec"`
// +optional
Status
UserStatus
`json:"status,omitempty"`
}
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/register.go
浏览文件 @
4fcaa78b
...
...
@@ -59,7 +59,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&
WorkspaceRoleList
{},
&
WorkspaceRoleBinding
{},
&
WorkspaceRoleBindingList
{},
&
FederatedClusterRoleBinding
{},
&
RoleBase
{},
&
RoleBaseList
{},
)
metav1
.
AddToGroupVersion
(
scheme
,
SchemeGroupVersion
)
return
nil
...
...
pkg/apis/iam/v1alpha2/types.go
浏览文件 @
4fcaa78b
...
...
@@ -19,6 +19,7 @@ package v1alpha2
import
(
rbacv1
"k8s.io/api/rbac/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
const
(
...
...
@@ -65,6 +66,7 @@ const (
ScopeCluster
=
"cluster"
ScopeNamespace
=
"namespace"
PlatformAdmin
=
"platform-admin"
NamespaceAdmin
=
"admin"
ClusterAdmin
=
"cluster-admin"
)
...
...
@@ -284,31 +286,22 @@ type WorkspaceRoleBindingList struct {
Items
[]
WorkspaceRoleBinding
`json:"items"`
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type
FederatedClusterRoleBinding
struct
{
// +kubebuilder:resource:categories="iam",scope="Cluster"
type
RoleBase
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"`
Role
runtime
.
RawExtension
`json:"role"`
}
type
Placement
struct
{
Clusters
[]
Cluster
`json:"clusters,omitempty"`
ClusterSelector
ClusterSelector
`json:"clusterSelector,omitempty"`
}
type
ClusterSelector
struct
{
MatchLabels
map
[
string
]
string
`json:"matchLabels,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type
Cluster
struct
{
Name
string
`json:"name"`
// RoleBaseList contains a list of RoleBase
type
RoleBaseList
struct
{
metav1
.
TypeMeta
`json:",inline"`
metav1
.
ListMeta
`json:"metadata,omitempty"`
Items
[]
RoleBase
`json:"items"`
}
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
浏览文件 @
4fcaa78b
...
...
@@ -63,44 +63,106 @@ func (in *ClusterSelector) DeepCopy() *ClusterSelector {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
Federated
ClusterRoleBinding
)
DeepCopyInto
(
out
*
FederatedClusterRoleBinding
)
{
func
(
in
*
Federated
Role
)
DeepCopyInto
(
out
*
FederatedRole
)
{
*
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 Federated
ClusterRoleBinding
.
func
(
in
*
Federated
ClusterRoleBinding
)
DeepCopy
()
*
FederatedClusterRoleBinding
{
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Federated
Role
.
func
(
in
*
Federated
Role
)
DeepCopy
()
*
FederatedRole
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
Federated
ClusterRoleBinding
)
out
:=
new
(
Federated
Role
)
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
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
FederatedRoleBinding
)
DeepCopyInto
(
out
*
FederatedRoleBinding
)
{
*
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 FederatedRoleBinding.
func
(
in
*
FederatedRoleBinding
)
DeepCopy
()
*
FederatedRoleBinding
{
if
in
==
nil
{
return
nil
}
return
nil
out
:=
new
(
FederatedRoleBinding
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
FederatedRoleBindingSpec
)
DeepCopyInto
(
out
*
FederatedRoleBindingSpec
)
{
*
out
=
*
in
in
.
Template
.
DeepCopyInto
(
&
out
.
Template
)
in
.
Placement
.
DeepCopyInto
(
&
out
.
Placement
)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedRoleBindingSpec.
func
(
in
*
FederatedRoleBindingSpec
)
DeepCopy
()
*
FederatedRoleBindingSpec
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
FederatedRoleBindingSpec
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
FederatedRoleSpec
)
DeepCopyInto
(
out
*
FederatedRoleSpec
)
{
*
out
=
*
in
in
.
Template
.
DeepCopyInto
(
&
out
.
Template
)
in
.
Placement
.
DeepCopyInto
(
&
out
.
Placement
)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedRoleSpec.
func
(
in
*
FederatedRoleSpec
)
DeepCopy
()
*
FederatedRoleSpec
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
FederatedRoleSpec
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
FederatedUser
)
DeepCopyInto
(
out
*
FederatedUser
)
{
*
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 FederatedUser.
func
(
in
*
FederatedUser
)
DeepCopy
()
*
FederatedUser
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
FederatedUser
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
Federated
ClusterRoleBindingSpec
)
DeepCopyInto
(
out
*
FederatedClusterRoleBinding
Spec
)
{
func
(
in
*
Federated
UserSpec
)
DeepCopyInto
(
out
*
FederatedUser
Spec
)
{
*
out
=
*
in
in
.
Template
.
DeepCopyInto
(
&
out
.
Template
)
in
.
Placement
.
DeepCopyInto
(
&
out
.
Placement
)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Federated
ClusterRoleBinding
Spec.
func
(
in
*
Federated
ClusterRoleBindingSpec
)
DeepCopy
()
*
FederatedClusterRoleBinding
Spec
{
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Federated
User
Spec.
func
(
in
*
Federated
UserSpec
)
DeepCopy
()
*
FederatedUser
Spec
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
Federated
ClusterRoleBinding
Spec
)
out
:=
new
(
Federated
User
Spec
)
in
.
DeepCopyInto
(
out
)
return
out
}
...
...
@@ -254,8 +316,67 @@ func (in *Placement) DeepCopy() *Placement {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
Template
)
DeepCopyInto
(
out
*
Templat
e
)
{
func
(
in
*
RoleBase
)
DeepCopyInto
(
out
*
RoleBas
e
)
{
*
out
=
*
in
out
.
TypeMeta
=
in
.
TypeMeta
in
.
ObjectMeta
.
DeepCopyInto
(
&
out
.
ObjectMeta
)
in
.
Role
.
DeepCopyInto
(
&
out
.
Role
)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleBase.
func
(
in
*
RoleBase
)
DeepCopy
()
*
RoleBase
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
RoleBase
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func
(
in
*
RoleBase
)
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
*
RoleBaseList
)
DeepCopyInto
(
out
*
RoleBaseList
)
{
*
out
=
*
in
out
.
TypeMeta
=
in
.
TypeMeta
in
.
ListMeta
.
DeepCopyInto
(
&
out
.
ListMeta
)
if
in
.
Items
!=
nil
{
in
,
out
:=
&
in
.
Items
,
&
out
.
Items
*
out
=
make
([]
RoleBase
,
len
(
*
in
))
for
i
:=
range
*
in
{
(
*
in
)[
i
]
.
DeepCopyInto
(
&
(
*
out
)[
i
])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleBaseList.
func
(
in
*
RoleBaseList
)
DeepCopy
()
*
RoleBaseList
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
RoleBaseList
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func
(
in
*
RoleBaseList
)
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
*
RoleBindingTemplate
)
DeepCopyInto
(
out
*
RoleBindingTemplate
)
{
*
out
=
*
in
in
.
ObjectMeta
.
DeepCopyInto
(
&
out
.
ObjectMeta
)
if
in
.
Subjects
!=
nil
{
in
,
out
:=
&
in
.
Subjects
,
&
out
.
Subjects
*
out
=
make
([]
v1
.
Subject
,
len
(
*
in
))
...
...
@@ -264,12 +385,35 @@ func (in *Template) DeepCopyInto(out *Template) {
out
.
RoleRef
=
in
.
RoleRef
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Template.
func
(
in
*
Template
)
DeepCopy
()
*
Template
{
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new
RoleBinding
Template.
func
(
in
*
RoleBindingTemplate
)
DeepCopy
()
*
RoleBinding
Template
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
Template
)
out
:=
new
(
RoleBindingTemplate
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
RoleTemplate
)
DeepCopyInto
(
out
*
RoleTemplate
)
{
*
out
=
*
in
in
.
ObjectMeta
.
DeepCopyInto
(
&
out
.
ObjectMeta
)
if
in
.
Rules
!=
nil
{
in
,
out
:=
&
in
.
Rules
,
&
out
.
Rules
*
out
=
make
([]
v1
.
PolicyRule
,
len
(
*
in
))
for
i
:=
range
*
in
{
(
*
in
)[
i
]
.
DeepCopyInto
(
&
(
*
out
)[
i
])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleTemplate.
func
(
in
*
RoleTemplate
)
DeepCopy
()
*
RoleTemplate
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
RoleTemplate
)
in
.
DeepCopyInto
(
out
)
return
out
}
...
...
@@ -391,6 +535,24 @@ func (in *UserStatus) DeepCopy() *UserStatus {
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
UserTemplate
)
DeepCopyInto
(
out
*
UserTemplate
)
{
*
out
=
*
in
in
.
ObjectMeta
.
DeepCopyInto
(
&
out
.
ObjectMeta
)
in
.
Spec
.
DeepCopyInto
(
&
out
.
Spec
)
in
.
Status
.
DeepCopyInto
(
&
out
.
Status
)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserTemplate.
func
(
in
*
UserTemplate
)
DeepCopy
()
*
UserTemplate
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
UserTemplate
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
WorkspaceRole
)
DeepCopyInto
(
out
*
WorkspaceRole
)
{
*
out
=
*
in
...
...
pkg/apis/tenant/v1alpha2/workspacetemplate_types.go
浏览文件 @
4fcaa78b
...
...
@@ -18,6 +18,7 @@ package v1alpha2
import
(
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
)
...
...
@@ -25,6 +26,22 @@ const (
ResourceKindWorkspaceTemplate
=
"WorkspaceTemplate"
ResourceSingularWorkspaceTemplate
=
"workspacetemplate"
ResourcePluralWorkspaceTemplate
=
"workspacetemplates"
ResourcesPluralFedWorkspace
=
"federatedworkspaces"
ResourcesSingularFedWorkspace
=
"federatedworkspace"
FedWorkspaceKind
=
"FederatedWorkspace"
fedResourceGroup
=
"types.kubefed.io"
fedResourceVersion
=
"v1beta1"
)
var
(
FedWorkspaceResource
=
metav1
.
APIResource
{
Name
:
ResourcesPluralFedWorkspace
,
SingularName
:
ResourcesSingularFedWorkspace
,
Namespaced
:
false
,
Group
:
fedResourceGroup
,
Version
:
fedResourceVersion
,
Kind
:
FedWorkspaceKind
,
}
)
// +genclient
...
...
@@ -44,7 +61,8 @@ type WorkspaceTemplateSpec struct {
v1alpha1
.
WorkspaceSpec
`json:",inline"`
// authorized clusters
// +optional
Clusters
[]
string
`json:"clusters,omitempty"`
Clusters
[]
string
`json:"clusters,omitempty"`
Overrides
[]
Override
`json:"overrides,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
...
...
@@ -60,3 +78,44 @@ type WorkspaceTemplateList struct {
func
init
()
{
SchemeBuilder
.
Register
(
&
WorkspaceTemplate
{},
&
WorkspaceTemplateList
{})
}
type
FederatedWorkspace
struct
{
metav1
.
TypeMeta
`json:",inline"`
metav1
.
ObjectMeta
`json:"metadata,omitempty"`
Spec
FederatedWorkspaceSpec
`json:"spec"`
}
type
FederatedWorkspaceSpec
struct
{
Template
Template
`json:"template"`
Placement
Placement
`json:"placement"`
Overrides
[]
Override
`json:"overrides,omitempty"`
}
type
Template
struct
{
metav1
.
ObjectMeta
`json:"metadata,omitempty"`
Spec
v1alpha1
.
WorkspaceSpec
`json:"spec"`
}
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"`
}
type
Override
struct
{
ClusterName
string
`json:"clusterName"`
ClusterOverrides
[]
ClusterOverride
`json:"clusterOverrides"`
}
type
ClusterOverride
struct
{
Path
string
`json:"path"`
Op
string
`json:"op,omitempty"`
Value
runtime
.
RawExtension
`json:"value"`
}
pkg/apis/tenant/v1alpha2/zz_generated.deepcopy.go
浏览文件 @
4fcaa78b
...
...
@@ -21,9 +21,164 @@ limitations under the License.
package
v1alpha2
import
(
runtime
"k8s.io/apimachinery/pkg/runtime"
"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
*
ClusterOverride
)
DeepCopyInto
(
out
*
ClusterOverride
)
{
*
out
=
*
in
in
.
Value
.
DeepCopyInto
(
&
out
.
Value
)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterOverride.
func
(
in
*
ClusterOverride
)
DeepCopy
()
*
ClusterOverride
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
ClusterOverride
)
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
*
FederatedWorkspace
)
DeepCopyInto
(
out
*
FederatedWorkspace
)
{
*
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 FederatedWorkspace.
func
(
in
*
FederatedWorkspace
)
DeepCopy
()
*
FederatedWorkspace
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
FederatedWorkspace
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
FederatedWorkspaceSpec
)
DeepCopyInto
(
out
*
FederatedWorkspaceSpec
)
{
*
out
=
*
in
in
.
Template
.
DeepCopyInto
(
&
out
.
Template
)
in
.
Placement
.
DeepCopyInto
(
&
out
.
Placement
)
if
in
.
Overrides
!=
nil
{
in
,
out
:=
&
in
.
Overrides
,
&
out
.
Overrides
*
out
=
make
([]
Override
,
len
(
*
in
))
for
i
:=
range
*
in
{
(
*
in
)[
i
]
.
DeepCopyInto
(
&
(
*
out
)[
i
])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspaceSpec.
func
(
in
*
FederatedWorkspaceSpec
)
DeepCopy
()
*
FederatedWorkspaceSpec
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
FederatedWorkspaceSpec
)
in
.
DeepCopyInto
(
out
)
return
out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
Override
)
DeepCopyInto
(
out
*
Override
)
{
*
out
=
*
in
if
in
.
ClusterOverrides
!=
nil
{
in
,
out
:=
&
in
.
ClusterOverrides
,
&
out
.
ClusterOverrides
*
out
=
make
([]
ClusterOverride
,
len
(
*
in
))
for
i
:=
range
*
in
{
(
*
in
)[
i
]
.
DeepCopyInto
(
&
(
*
out
)[
i
])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Override.
func
(
in
*
Override
)
DeepCopy
()
*
Override
{
if
in
==
nil
{
return
nil
}
out
:=
new
(
Override
)
in
.
DeepCopyInto
(
out
)
return
out
}
// 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
in
.
ObjectMeta
.
DeepCopyInto
(
&
out
.
ObjectMeta
)
out
.
Spec
=
in
.
Spec
}
// 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
*
WorkspaceTemplate
)
DeepCopyInto
(
out
*
WorkspaceTemplate
)
{
*
out
=
*
in
...
...
@@ -91,6 +246,13 @@ func (in *WorkspaceTemplateSpec) DeepCopyInto(out *WorkspaceTemplateSpec) {
*
out
=
make
([]
string
,
len
(
*
in
))
copy
(
*
out
,
*
in
)
}
if
in
.
Overrides
!=
nil
{
in
,
out
:=
&
in
.
Overrides
,
&
out
.
Overrides
*
out
=
make
([]
Override
,
len
(
*
in
))
for
i
:=
range
*
in
{
(
*
in
)[
i
]
.
DeepCopyInto
(
&
(
*
out
)[
i
])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceTemplateSpec.
...
...
pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_iam_client.go
浏览文件 @
4fcaa78b
...
...
@@ -36,6 +36,10 @@ func (c *FakeIamV1alpha2) GlobalRoleBindings() v1alpha2.GlobalRoleBindingInterfa
return
&
FakeGlobalRoleBindings
{
c
}
}
func
(
c
*
FakeIamV1alpha2
)
RoleBases
()
v1alpha2
.
RoleBaseInterface
{
return
&
FakeRoleBases
{
c
}
}
func
(
c
*
FakeIamV1alpha2
)
Users
()
v1alpha2
.
UserInterface
{
return
&
FakeUsers
{
c
}
}
...
...
pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_rolebase.go
0 → 100644
浏览文件 @
4fcaa78b
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package
fake
import
(
v1
"k8s.io/apimachinery/pkg/apis/meta/v1"
labels
"k8s.io/apimachinery/pkg/labels"
schema
"k8s.io/apimachinery/pkg/runtime/schema"
types
"k8s.io/apimachinery/pkg/types"
watch
"k8s.io/apimachinery/pkg/watch"
testing
"k8s.io/client-go/testing"
v1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
)
// FakeRoleBases implements RoleBaseInterface
type
FakeRoleBases
struct
{
Fake
*
FakeIamV1alpha2
}
var
rolebasesResource
=
schema
.
GroupVersionResource
{
Group
:
"iam.kubesphere.io"
,
Version
:
"v1alpha2"
,
Resource
:
"rolebases"
}
var
rolebasesKind
=
schema
.
GroupVersionKind
{
Group
:
"iam.kubesphere.io"
,
Version
:
"v1alpha2"
,
Kind
:
"RoleBase"
}
// Get takes name of the roleBase, and returns the corresponding roleBase object, and an error if there is any.
func
(
c
*
FakeRoleBases
)
Get
(
name
string
,
options
v1
.
GetOptions
)
(
result
*
v1alpha2
.
RoleBase
,
err
error
)
{
obj
,
err
:=
c
.
Fake
.
Invokes
(
testing
.
NewRootGetAction
(
rolebasesResource
,
name
),
&
v1alpha2
.
RoleBase
{})
if
obj
==
nil
{
return
nil
,
err
}
return
obj
.
(
*
v1alpha2
.
RoleBase
),
err
}
// List takes label and field selectors, and returns the list of RoleBases that match those selectors.
func
(
c
*
FakeRoleBases
)
List
(
opts
v1
.
ListOptions
)
(
result
*
v1alpha2
.
RoleBaseList
,
err
error
)
{
obj
,
err
:=
c
.
Fake
.
Invokes
(
testing
.
NewRootListAction
(
rolebasesResource
,
rolebasesKind
,
opts
),
&
v1alpha2
.
RoleBaseList
{})
if
obj
==
nil
{
return
nil
,
err
}
label
,
_
,
_
:=
testing
.
ExtractFromListOptions
(
opts
)
if
label
==
nil
{
label
=
labels
.
Everything
()
}
list
:=
&
v1alpha2
.
RoleBaseList
{
ListMeta
:
obj
.
(
*
v1alpha2
.
RoleBaseList
)
.
ListMeta
}
for
_
,
item
:=
range
obj
.
(
*
v1alpha2
.
RoleBaseList
)
.
Items
{
if
label
.
Matches
(
labels
.
Set
(
item
.
Labels
))
{
list
.
Items
=
append
(
list
.
Items
,
item
)
}
}
return
list
,
err
}
// Watch returns a watch.Interface that watches the requested roleBases.
func
(
c
*
FakeRoleBases
)
Watch
(
opts
v1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
c
.
Fake
.
InvokesWatch
(
testing
.
NewRootWatchAction
(
rolebasesResource
,
opts
))
}
// Create takes the representation of a roleBase and creates it. Returns the server's representation of the roleBase, and an error, if there is any.
func
(
c
*
FakeRoleBases
)
Create
(
roleBase
*
v1alpha2
.
RoleBase
)
(
result
*
v1alpha2
.
RoleBase
,
err
error
)
{
obj
,
err
:=
c
.
Fake
.
Invokes
(
testing
.
NewRootCreateAction
(
rolebasesResource
,
roleBase
),
&
v1alpha2
.
RoleBase
{})
if
obj
==
nil
{
return
nil
,
err
}
return
obj
.
(
*
v1alpha2
.
RoleBase
),
err
}
// Update takes the representation of a roleBase and updates it. Returns the server's representation of the roleBase, and an error, if there is any.
func
(
c
*
FakeRoleBases
)
Update
(
roleBase
*
v1alpha2
.
RoleBase
)
(
result
*
v1alpha2
.
RoleBase
,
err
error
)
{
obj
,
err
:=
c
.
Fake
.
Invokes
(
testing
.
NewRootUpdateAction
(
rolebasesResource
,
roleBase
),
&
v1alpha2
.
RoleBase
{})
if
obj
==
nil
{
return
nil
,
err
}
return
obj
.
(
*
v1alpha2
.
RoleBase
),
err
}
// Delete takes name of the roleBase and deletes it. Returns an error if one occurs.
func
(
c
*
FakeRoleBases
)
Delete
(
name
string
,
options
*
v1
.
DeleteOptions
)
error
{
_
,
err
:=
c
.
Fake
.
Invokes
(
testing
.
NewRootDeleteAction
(
rolebasesResource
,
name
),
&
v1alpha2
.
RoleBase
{})
return
err
}
// DeleteCollection deletes a collection of objects.
func
(
c
*
FakeRoleBases
)
DeleteCollection
(
options
*
v1
.
DeleteOptions
,
listOptions
v1
.
ListOptions
)
error
{
action
:=
testing
.
NewRootDeleteCollectionAction
(
rolebasesResource
,
listOptions
)
_
,
err
:=
c
.
Fake
.
Invokes
(
action
,
&
v1alpha2
.
RoleBaseList
{})
return
err
}
// Patch applies the patch and returns the patched roleBase.
func
(
c
*
FakeRoleBases
)
Patch
(
name
string
,
pt
types
.
PatchType
,
data
[]
byte
,
subresources
...
string
)
(
result
*
v1alpha2
.
RoleBase
,
err
error
)
{
obj
,
err
:=
c
.
Fake
.
Invokes
(
testing
.
NewRootPatchSubresourceAction
(
rolebasesResource
,
name
,
pt
,
data
,
subresources
...
),
&
v1alpha2
.
RoleBase
{})
if
obj
==
nil
{
return
nil
,
err
}
return
obj
.
(
*
v1alpha2
.
RoleBase
),
err
}
pkg/client/clientset/versioned/typed/iam/v1alpha2/generated_expansion.go
浏览文件 @
4fcaa78b
...
...
@@ -22,6 +22,8 @@ type GlobalRoleExpansion interface{}
type
GlobalRoleBindingExpansion
interface
{}
type
RoleBaseExpansion
interface
{}
type
UserExpansion
interface
{}
type
WorkspaceRoleExpansion
interface
{}
...
...
pkg/client/clientset/versioned/typed/iam/v1alpha2/iam_client.go
浏览文件 @
4fcaa78b
...
...
@@ -28,6 +28,7 @@ type IamV1alpha2Interface interface {
RESTClient
()
rest
.
Interface
GlobalRolesGetter
GlobalRoleBindingsGetter
RoleBasesGetter
UsersGetter
WorkspaceRolesGetter
WorkspaceRoleBindingsGetter
...
...
@@ -46,6 +47,10 @@ func (c *IamV1alpha2Client) GlobalRoleBindings() GlobalRoleBindingInterface {
return
newGlobalRoleBindings
(
c
)
}
func
(
c
*
IamV1alpha2Client
)
RoleBases
()
RoleBaseInterface
{
return
newRoleBases
(
c
)
}
func
(
c
*
IamV1alpha2Client
)
Users
()
UserInterface
{
return
newUsers
(
c
)
}
...
...
pkg/client/clientset/versioned/typed/iam/v1alpha2/rolebase.go
0 → 100644
浏览文件 @
4fcaa78b
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package
v1alpha2
import
(
"time"
v1
"k8s.io/apimachinery/pkg/apis/meta/v1"
types
"k8s.io/apimachinery/pkg/types"
watch
"k8s.io/apimachinery/pkg/watch"
rest
"k8s.io/client-go/rest"
v1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
scheme
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
)
// RoleBasesGetter has a method to return a RoleBaseInterface.
// A group's client should implement this interface.
type
RoleBasesGetter
interface
{
RoleBases
()
RoleBaseInterface
}
// RoleBaseInterface has methods to work with RoleBase resources.
type
RoleBaseInterface
interface
{
Create
(
*
v1alpha2
.
RoleBase
)
(
*
v1alpha2
.
RoleBase
,
error
)
Update
(
*
v1alpha2
.
RoleBase
)
(
*
v1alpha2
.
RoleBase
,
error
)
Delete
(
name
string
,
options
*
v1
.
DeleteOptions
)
error
DeleteCollection
(
options
*
v1
.
DeleteOptions
,
listOptions
v1
.
ListOptions
)
error
Get
(
name
string
,
options
v1
.
GetOptions
)
(
*
v1alpha2
.
RoleBase
,
error
)
List
(
opts
v1
.
ListOptions
)
(
*
v1alpha2
.
RoleBaseList
,
error
)
Watch
(
opts
v1
.
ListOptions
)
(
watch
.
Interface
,
error
)
Patch
(
name
string
,
pt
types
.
PatchType
,
data
[]
byte
,
subresources
...
string
)
(
result
*
v1alpha2
.
RoleBase
,
err
error
)
RoleBaseExpansion
}
// roleBases implements RoleBaseInterface
type
roleBases
struct
{
client
rest
.
Interface
}
// newRoleBases returns a RoleBases
func
newRoleBases
(
c
*
IamV1alpha2Client
)
*
roleBases
{
return
&
roleBases
{
client
:
c
.
RESTClient
(),
}
}
// Get takes name of the roleBase, and returns the corresponding roleBase object, and an error if there is any.
func
(
c
*
roleBases
)
Get
(
name
string
,
options
v1
.
GetOptions
)
(
result
*
v1alpha2
.
RoleBase
,
err
error
)
{
result
=
&
v1alpha2
.
RoleBase
{}
err
=
c
.
client
.
Get
()
.
Resource
(
"rolebases"
)
.
Name
(
name
)
.
VersionedParams
(
&
options
,
scheme
.
ParameterCodec
)
.
Do
()
.
Into
(
result
)
return
}
// List takes label and field selectors, and returns the list of RoleBases that match those selectors.
func
(
c
*
roleBases
)
List
(
opts
v1
.
ListOptions
)
(
result
*
v1alpha2
.
RoleBaseList
,
err
error
)
{
var
timeout
time
.
Duration
if
opts
.
TimeoutSeconds
!=
nil
{
timeout
=
time
.
Duration
(
*
opts
.
TimeoutSeconds
)
*
time
.
Second
}
result
=
&
v1alpha2
.
RoleBaseList
{}
err
=
c
.
client
.
Get
()
.
Resource
(
"rolebases"
)
.
VersionedParams
(
&
opts
,
scheme
.
ParameterCodec
)
.
Timeout
(
timeout
)
.
Do
()
.
Into
(
result
)
return
}
// Watch returns a watch.Interface that watches the requested roleBases.
func
(
c
*
roleBases
)
Watch
(
opts
v1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
var
timeout
time
.
Duration
if
opts
.
TimeoutSeconds
!=
nil
{
timeout
=
time
.
Duration
(
*
opts
.
TimeoutSeconds
)
*
time
.
Second
}
opts
.
Watch
=
true
return
c
.
client
.
Get
()
.
Resource
(
"rolebases"
)
.
VersionedParams
(
&
opts
,
scheme
.
ParameterCodec
)
.
Timeout
(
timeout
)
.
Watch
()
}
// Create takes the representation of a roleBase and creates it. Returns the server's representation of the roleBase, and an error, if there is any.
func
(
c
*
roleBases
)
Create
(
roleBase
*
v1alpha2
.
RoleBase
)
(
result
*
v1alpha2
.
RoleBase
,
err
error
)
{
result
=
&
v1alpha2
.
RoleBase
{}
err
=
c
.
client
.
Post
()
.
Resource
(
"rolebases"
)
.
Body
(
roleBase
)
.
Do
()
.
Into
(
result
)
return
}
// Update takes the representation of a roleBase and updates it. Returns the server's representation of the roleBase, and an error, if there is any.
func
(
c
*
roleBases
)
Update
(
roleBase
*
v1alpha2
.
RoleBase
)
(
result
*
v1alpha2
.
RoleBase
,
err
error
)
{
result
=
&
v1alpha2
.
RoleBase
{}
err
=
c
.
client
.
Put
()
.
Resource
(
"rolebases"
)
.
Name
(
roleBase
.
Name
)
.
Body
(
roleBase
)
.
Do
()
.
Into
(
result
)
return
}
// Delete takes name of the roleBase and deletes it. Returns an error if one occurs.
func
(
c
*
roleBases
)
Delete
(
name
string
,
options
*
v1
.
DeleteOptions
)
error
{
return
c
.
client
.
Delete
()
.
Resource
(
"rolebases"
)
.
Name
(
name
)
.
Body
(
options
)
.
Do
()
.
Error
()
}
// DeleteCollection deletes a collection of objects.
func
(
c
*
roleBases
)
DeleteCollection
(
options
*
v1
.
DeleteOptions
,
listOptions
v1
.
ListOptions
)
error
{
var
timeout
time
.
Duration
if
listOptions
.
TimeoutSeconds
!=
nil
{
timeout
=
time
.
Duration
(
*
listOptions
.
TimeoutSeconds
)
*
time
.
Second
}
return
c
.
client
.
Delete
()
.
Resource
(
"rolebases"
)
.
VersionedParams
(
&
listOptions
,
scheme
.
ParameterCodec
)
.
Timeout
(
timeout
)
.
Body
(
options
)
.
Do
()
.
Error
()
}
// Patch applies the patch and returns the patched roleBase.
func
(
c
*
roleBases
)
Patch
(
name
string
,
pt
types
.
PatchType
,
data
[]
byte
,
subresources
...
string
)
(
result
*
v1alpha2
.
RoleBase
,
err
error
)
{
result
=
&
v1alpha2
.
RoleBase
{}
err
=
c
.
client
.
Patch
(
pt
)
.
Resource
(
"rolebases"
)
.
SubResource
(
subresources
...
)
.
Name
(
name
)
.
Body
(
data
)
.
Do
()
.
Into
(
result
)
return
}
pkg/client/clientset/versioned/typed/storage/v1alpha1/doc.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/clientset/versioned/typed/storage/v1alpha1/fake/doc.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/clientset/versioned/typed/storage/v1alpha1/fake/fake_storage_client.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/clientset/versioned/typed/storage/v1alpha1/fake/fake_storageclasscapability.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/clientset/versioned/typed/storage/v1alpha1/generated_expansion.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/clientset/versioned/typed/storage/v1alpha1/storage_client.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/clientset/versioned/typed/storage/v1alpha1/storageclasscapability.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/informers/externalversions/generic.go
浏览文件 @
4fcaa78b
...
...
@@ -85,6 +85,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
return
&
genericInformer
{
resource
:
resource
.
GroupResource
(),
informer
:
f
.
Iam
()
.
V1alpha2
()
.
GlobalRoles
()
.
Informer
()},
nil
case
v1alpha2
.
SchemeGroupVersion
.
WithResource
(
"globalrolebindings"
)
:
return
&
genericInformer
{
resource
:
resource
.
GroupResource
(),
informer
:
f
.
Iam
()
.
V1alpha2
()
.
GlobalRoleBindings
()
.
Informer
()},
nil
case
v1alpha2
.
SchemeGroupVersion
.
WithResource
(
"rolebases"
)
:
return
&
genericInformer
{
resource
:
resource
.
GroupResource
(),
informer
:
f
.
Iam
()
.
V1alpha2
()
.
RoleBases
()
.
Informer
()},
nil
case
v1alpha2
.
SchemeGroupVersion
.
WithResource
(
"users"
)
:
return
&
genericInformer
{
resource
:
resource
.
GroupResource
(),
informer
:
f
.
Iam
()
.
V1alpha2
()
.
Users
()
.
Informer
()},
nil
case
v1alpha2
.
SchemeGroupVersion
.
WithResource
(
"workspaceroles"
)
:
...
...
pkg/client/informers/externalversions/iam/v1alpha2/interface.go
浏览文件 @
4fcaa78b
...
...
@@ -28,6 +28,8 @@ type Interface interface {
GlobalRoles
()
GlobalRoleInformer
// GlobalRoleBindings returns a GlobalRoleBindingInformer.
GlobalRoleBindings
()
GlobalRoleBindingInformer
// RoleBases returns a RoleBaseInformer.
RoleBases
()
RoleBaseInformer
// Users returns a UserInformer.
Users
()
UserInformer
// WorkspaceRoles returns a WorkspaceRoleInformer.
...
...
@@ -57,6 +59,11 @@ func (v *version) GlobalRoleBindings() GlobalRoleBindingInformer {
return
&
globalRoleBindingInformer
{
factory
:
v
.
factory
,
tweakListOptions
:
v
.
tweakListOptions
}
}
// RoleBases returns a RoleBaseInformer.
func
(
v
*
version
)
RoleBases
()
RoleBaseInformer
{
return
&
roleBaseInformer
{
factory
:
v
.
factory
,
tweakListOptions
:
v
.
tweakListOptions
}
}
// Users returns a UserInformer.
func
(
v
*
version
)
Users
()
UserInformer
{
return
&
userInformer
{
factory
:
v
.
factory
,
tweakListOptions
:
v
.
tweakListOptions
}
...
...
pkg/client/informers/externalversions/iam/v1alpha2/rolebase.go
0 → 100644
浏览文件 @
4fcaa78b
/*
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package
v1alpha2
import
(
time
"time"
v1
"k8s.io/apimachinery/pkg/apis/meta/v1"
runtime
"k8s.io/apimachinery/pkg/runtime"
watch
"k8s.io/apimachinery/pkg/watch"
cache
"k8s.io/client-go/tools/cache"
iamv1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
versioned
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
internalinterfaces
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
v1alpha2
"kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
)
// RoleBaseInformer provides access to a shared informer and lister for
// RoleBases.
type
RoleBaseInformer
interface
{
Informer
()
cache
.
SharedIndexInformer
Lister
()
v1alpha2
.
RoleBaseLister
}
type
roleBaseInformer
struct
{
factory
internalinterfaces
.
SharedInformerFactory
tweakListOptions
internalinterfaces
.
TweakListOptionsFunc
}
// NewRoleBaseInformer constructs a new informer for RoleBase type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func
NewRoleBaseInformer
(
client
versioned
.
Interface
,
resyncPeriod
time
.
Duration
,
indexers
cache
.
Indexers
)
cache
.
SharedIndexInformer
{
return
NewFilteredRoleBaseInformer
(
client
,
resyncPeriod
,
indexers
,
nil
)
}
// NewFilteredRoleBaseInformer constructs a new informer for RoleBase type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func
NewFilteredRoleBaseInformer
(
client
versioned
.
Interface
,
resyncPeriod
time
.
Duration
,
indexers
cache
.
Indexers
,
tweakListOptions
internalinterfaces
.
TweakListOptionsFunc
)
cache
.
SharedIndexInformer
{
return
cache
.
NewSharedIndexInformer
(
&
cache
.
ListWatch
{
ListFunc
:
func
(
options
v1
.
ListOptions
)
(
runtime
.
Object
,
error
)
{
if
tweakListOptions
!=
nil
{
tweakListOptions
(
&
options
)
}
return
client
.
IamV1alpha2
()
.
RoleBases
()
.
List
(
options
)
},
WatchFunc
:
func
(
options
v1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
if
tweakListOptions
!=
nil
{
tweakListOptions
(
&
options
)
}
return
client
.
IamV1alpha2
()
.
RoleBases
()
.
Watch
(
options
)
},
},
&
iamv1alpha2
.
RoleBase
{},
resyncPeriod
,
indexers
,
)
}
func
(
f
*
roleBaseInformer
)
defaultInformer
(
client
versioned
.
Interface
,
resyncPeriod
time
.
Duration
)
cache
.
SharedIndexInformer
{
return
NewFilteredRoleBaseInformer
(
client
,
resyncPeriod
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
},
f
.
tweakListOptions
)
}
func
(
f
*
roleBaseInformer
)
Informer
()
cache
.
SharedIndexInformer
{
return
f
.
factory
.
InformerFor
(
&
iamv1alpha2
.
RoleBase
{},
f
.
defaultInformer
)
}
func
(
f
*
roleBaseInformer
)
Lister
()
v1alpha2
.
RoleBaseLister
{
return
v1alpha2
.
NewRoleBaseLister
(
f
.
Informer
()
.
GetIndexer
())
}
pkg/client/informers/externalversions/storage/interface.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/informers/externalversions/storage/v1alpha1/interface.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/informers/externalversions/storage/v1alpha1/storageclasscapability.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/listers/iam/v1alpha2/expansion_generated.go
浏览文件 @
4fcaa78b
...
...
@@ -26,6 +26,10 @@ type GlobalRoleListerExpansion interface{}
// GlobalRoleBindingLister.
type
GlobalRoleBindingListerExpansion
interface
{}
// RoleBaseListerExpansion allows custom methods to be added to
// RoleBaseLister.
type
RoleBaseListerExpansion
interface
{}
// UserListerExpansion allows custom methods to be added to
// UserLister.
type
UserListerExpansion
interface
{}
...
...
pkg/client/listers/iam/v1alpha2/rolebase.go
0 → 100644
浏览文件 @
4fcaa78b
/*
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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package
v1alpha2
import
(
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
v1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
)
// RoleBaseLister helps list RoleBases.
type
RoleBaseLister
interface
{
// List lists all RoleBases in the indexer.
List
(
selector
labels
.
Selector
)
(
ret
[]
*
v1alpha2
.
RoleBase
,
err
error
)
// Get retrieves the RoleBase from the index for a given name.
Get
(
name
string
)
(
*
v1alpha2
.
RoleBase
,
error
)
RoleBaseListerExpansion
}
// roleBaseLister implements the RoleBaseLister interface.
type
roleBaseLister
struct
{
indexer
cache
.
Indexer
}
// NewRoleBaseLister returns a new RoleBaseLister.
func
NewRoleBaseLister
(
indexer
cache
.
Indexer
)
RoleBaseLister
{
return
&
roleBaseLister
{
indexer
:
indexer
}
}
// List lists all RoleBases in the indexer.
func
(
s
*
roleBaseLister
)
List
(
selector
labels
.
Selector
)
(
ret
[]
*
v1alpha2
.
RoleBase
,
err
error
)
{
err
=
cache
.
ListAll
(
s
.
indexer
,
selector
,
func
(
m
interface
{})
{
ret
=
append
(
ret
,
m
.
(
*
v1alpha2
.
RoleBase
))
})
return
ret
,
err
}
// Get retrieves the RoleBase from the index for a given name.
func
(
s
*
roleBaseLister
)
Get
(
name
string
)
(
*
v1alpha2
.
RoleBase
,
error
)
{
obj
,
exists
,
err
:=
s
.
indexer
.
GetByKey
(
name
)
if
err
!=
nil
{
return
nil
,
err
}
if
!
exists
{
return
nil
,
errors
.
NewNotFound
(
v1alpha2
.
Resource
(
"rolebase"
),
name
)
}
return
obj
.
(
*
v1alpha2
.
RoleBase
),
nil
}
pkg/client/listers/storage/v1alpha1/expansion_generated.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/client/listers/storage/v1alpha1/storageclasscapability.go
浏览文件 @
4fcaa78b
/*
Copyright 20
19 The KubeSphere a
uthors.
Copyright 20
20 The KubeSphere A
uthors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
pkg/constants/constants.go
浏览文件 @
4fcaa78b
...
...
@@ -49,6 +49,7 @@ const (
DevopsOwner
=
"owner"
DevopsReporter
=
"reporter"
DevOpsProjectLabelKey
=
"kubesphere.io/devopsproject"
KubefedManagedLabel
=
"kubefed.io/managed"
UserNameHeader
=
"X-Token-Username"
...
...
pkg/controller/certificatesigningrequest/certificatesigningrequest_controller.go
浏览文件 @
4fcaa78b
...
...
@@ -24,14 +24,12 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/informers"
certificatesinformers
"k8s.io/client-go/informers/certificates/v1beta1"
coreinformers
"k8s.io/client-go/informers/core/v1"
core
v1
informers
"k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
typedcorev1
"k8s.io/client-go/kubernetes/typed/core/v1"
certificateslisters
"k8s.io/client-go/listers/certificates/v1beta1"
corelisters
"k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
...
...
@@ -55,11 +53,7 @@ type Controller struct {
csrInformer
certificatesinformers
.
CertificateSigningRequestInformer
csrLister
certificateslisters
.
CertificateSigningRequestLister
csrSynced
cache
.
InformerSynced
cmInformer
coreinformers
.
ConfigMapInformer
cmLister
corelisters
.
ConfigMapLister
cmSynced
cache
.
InformerSynced
cmSynced
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
...
...
@@ -72,7 +66,8 @@ type Controller struct {
kubeconfigOperator
kubeconfig
.
Interface
}
func
NewController
(
k8sClient
kubernetes
.
Interface
,
informerFactory
informers
.
SharedInformerFactory
,
config
*
rest
.
Config
)
*
Controller
{
func
NewController
(
k8sClient
kubernetes
.
Interface
,
csrInformer
certificatesinformers
.
CertificateSigningRequestInformer
,
configMapInformer
corev1informers
.
ConfigMapInformer
,
config
*
rest
.
Config
)
*
Controller
{
// Create event broadcaster
// Add sample-controller types to the default Kubernetes Scheme so Events can be
// logged for sample-controller types.
...
...
@@ -82,17 +77,13 @@ func NewController(k8sClient kubernetes.Interface, informerFactory informers.Sha
eventBroadcaster
.
StartLogging
(
klog
.
Infof
)
eventBroadcaster
.
StartRecordingToSink
(
&
typedcorev1
.
EventSinkImpl
{
Interface
:
k8sClient
.
CoreV1
()
.
Events
(
""
)})
recorder
:=
eventBroadcaster
.
NewRecorder
(
scheme
.
Scheme
,
corev1
.
EventSource
{
Component
:
controllerName
})
csrInformer
:=
informerFactory
.
Certificates
()
.
V1beta1
()
.
CertificateSigningRequests
()
cmInformer
:=
informerFactory
.
Core
()
.
V1
()
.
ConfigMaps
()
ctl
:=
&
Controller
{
k8sclient
:
k8sClient
,
csrInformer
:
csrInformer
,
csrLister
:
csrInformer
.
Lister
(),
csrSynced
:
csrInformer
.
Informer
()
.
HasSynced
,
cmInformer
:
cmInformer
,
cmLister
:
cmInformer
.
Lister
(),
cmSynced
:
cmInformer
.
Informer
()
.
HasSynced
,
kubeconfigOperator
:
kubeconfig
.
NewOperator
(
k8sClient
,
config
,
""
),
cmSynced
:
configMapInformer
.
Informer
()
.
HasSynced
,
kubeconfigOperator
:
kubeconfig
.
NewOperator
(
k8sClient
,
configMapInformer
,
config
),
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"CertificateSigningRequest"
),
recorder
:
recorder
,
}
...
...
@@ -112,7 +103,7 @@ func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error {
defer
c
.
workqueue
.
ShutDown
()
// Start the csrInformer factories to begin populating the csrInformer caches
klog
.
Info
(
"Starting
User
controller"
)
klog
.
Info
(
"Starting
CSR
controller"
)
// Wait for the caches to be csrSynced before starting workers
klog
.
Info
(
"Waiting for csrInformer caches to sync"
)
...
...
pkg/controller/clusterrolebinding/clusterrolebinding_controller.go
浏览文件 @
4fcaa78b
...
...
@@ -100,10 +100,8 @@ 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"
)
klog
.
Info
(
"Starting
ClusterRoleBinding
controller"
)
// Wait for the caches to be synced before starting workers
klog
.
Info
(
"Waiting for informer caches to sync"
)
...
...
pkg/controller/globalrole/globalrole_controller.go
0 → 100644
浏览文件 @
4fcaa78b
/*
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
globalrole
import
(
"encoding/json"
"fmt"
corev1
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"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"
kubesphere
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
iamv1alpha2informers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/iam/v1alpha2"
iamv1alpha2listers
"kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/constants"
"reflect"
"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
=
"GlobalRole synced successfully"
controllerName
=
"globalrole-controller"
)
type
Controller
struct
{
k8sClient
kubernetes
.
Interface
ksClient
kubesphere
.
Interface
globalRoleInformer
iamv1alpha2informers
.
GlobalRoleInformer
globalRoleLister
iamv1alpha2listers
.
GlobalRoleLister
globalRoleSynced
cache
.
InformerSynced
fedGlobalRoleCache
cache
.
Store
fedGlobalRoleCacheController
cache
.
Controller
// 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
}
func
NewController
(
k8sClient
kubernetes
.
Interface
,
ksClient
kubesphere
.
Interface
,
globalRoleInformer
iamv1alpha2informers
.
GlobalRoleInformer
,
fedGlobalRoleCache
cache
.
Store
,
fedGlobalRoleCacheController
cache
.
Controller
)
*
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
})
ctl
:=
&
Controller
{
k8sClient
:
k8sClient
,
ksClient
:
ksClient
,
globalRoleInformer
:
globalRoleInformer
,
globalRoleLister
:
globalRoleInformer
.
Lister
(),
globalRoleSynced
:
globalRoleInformer
.
Informer
()
.
HasSynced
,
fedGlobalRoleCache
:
fedGlobalRoleCache
,
fedGlobalRoleCacheController
:
fedGlobalRoleCacheController
,
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"GlobalRole"
),
recorder
:
recorder
,
}
klog
.
Info
(
"Setting up event handlers"
)
globalRoleInformer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
AddFunc
:
ctl
.
enqueueClusterRole
,
UpdateFunc
:
func
(
old
,
new
interface
{})
{
ctl
.
enqueueClusterRole
(
new
)
},
DeleteFunc
:
ctl
.
enqueueClusterRole
,
})
return
ctl
}
func
(
c
*
Controller
)
Run
(
threadiness
int
,
stopCh
<-
chan
struct
{})
error
{
defer
utilruntime
.
HandleCrash
()
defer
c
.
workqueue
.
ShutDown
()
// Start the informer factories to begin populating the informer caches
klog
.
Info
(
"Starting GlobalRole 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
.
globalRoleSynced
,
c
.
fedGlobalRoleCacheController
.
HasSynced
);
!
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
)
enqueueClusterRole
(
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
{
globalRole
,
err
:=
c
.
globalRoleLister
.
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
(
"globalrole '%s' in work queue no longer exists"
,
key
))
return
nil
}
klog
.
Error
(
err
)
return
err
}
if
err
=
c
.
multiClusterSync
(
globalRole
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
c
.
recorder
.
Event
(
globalRole
,
corev1
.
EventTypeNormal
,
successSynced
,
messageResourceSynced
)
return
nil
}
func
(
c
*
Controller
)
Start
(
stopCh
<-
chan
struct
{})
error
{
return
c
.
Run
(
4
,
stopCh
)
}
func
(
c
*
Controller
)
multiClusterSync
(
globalRole
*
iamv1alpha2
.
GlobalRole
)
error
{
if
err
:=
c
.
ensureNotControlledByKubefed
(
globalRole
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
obj
,
exist
,
err
:=
c
.
fedGlobalRoleCache
.
GetByKey
(
globalRole
.
Name
)
if
!
exist
{
return
c
.
createFederatedGlobalRole
(
globalRole
)
}
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
var
federatedGlobalRole
iamv1alpha2
.
FederatedRole
if
err
=
runtime
.
DefaultUnstructuredConverter
.
FromUnstructured
(
obj
.
(
*
unstructured
.
Unstructured
)
.
Object
,
&
federatedGlobalRole
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
if
!
reflect
.
DeepEqual
(
federatedGlobalRole
.
Spec
.
Template
.
Rules
,
globalRole
.
Rules
)
||
!
reflect
.
DeepEqual
(
federatedGlobalRole
.
Spec
.
Template
.
Labels
,
globalRole
.
Labels
)
||
!
reflect
.
DeepEqual
(
federatedGlobalRole
.
Spec
.
Template
.
Annotations
,
globalRole
.
Annotations
)
{
federatedGlobalRole
.
Spec
.
Template
.
Rules
=
globalRole
.
Rules
federatedGlobalRole
.
Spec
.
Template
.
Annotations
=
globalRole
.
Annotations
federatedGlobalRole
.
Spec
.
Template
.
Labels
=
globalRole
.
Labels
return
c
.
updateFederatedGlobalRole
(
&
federatedGlobalRole
)
}
return
nil
}
func
(
c
*
Controller
)
createFederatedGlobalRole
(
globalRole
*
iamv1alpha2
.
GlobalRole
)
error
{
federatedGlobalRole
:=
&
iamv1alpha2
.
FederatedRole
{
TypeMeta
:
metav1
.
TypeMeta
{
Kind
:
iamv1alpha2
.
FedGlobalRoleKind
,
APIVersion
:
iamv1alpha2
.
FedGlobalRoleResource
.
Group
+
"/"
+
iamv1alpha2
.
FedGlobalRoleResource
.
Version
,
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
globalRole
.
Name
,
},
Spec
:
iamv1alpha2
.
FederatedRoleSpec
{
Template
:
iamv1alpha2
.
RoleTemplate
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Labels
:
globalRole
.
Labels
,
Annotations
:
globalRole
.
Annotations
,
},
Rules
:
globalRole
.
Rules
,
},
Placement
:
iamv1alpha2
.
Placement
{
ClusterSelector
:
iamv1alpha2
.
ClusterSelector
{},
},
},
}
err
:=
controllerutil
.
SetControllerReference
(
globalRole
,
federatedGlobalRole
,
scheme
.
Scheme
)
if
err
!=
nil
{
return
err
}
data
,
err
:=
json
.
Marshal
(
federatedGlobalRole
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Post
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s"
,
iamv1alpha2
.
FedGlobalRoleResource
.
Group
,
iamv1alpha2
.
FedGlobalRoleResource
.
Version
,
iamv1alpha2
.
FedGlobalRoleResource
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
(
c
*
Controller
)
updateFederatedGlobalRole
(
federatedGlobalRole
*
iamv1alpha2
.
FederatedRole
)
error
{
data
,
err
:=
json
.
Marshal
(
federatedGlobalRole
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Put
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s/%s"
,
iamv1alpha2
.
FedGlobalRoleResource
.
Group
,
iamv1alpha2
.
FedGlobalRoleResource
.
Version
,
iamv1alpha2
.
FedGlobalRoleResource
.
Name
,
federatedGlobalRole
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
(
c
*
Controller
)
ensureNotControlledByKubefed
(
globalRole
*
iamv1alpha2
.
GlobalRole
)
error
{
if
globalRole
.
Labels
[
constants
.
KubefedManagedLabel
]
!=
"false"
{
if
globalRole
.
Labels
==
nil
{
globalRole
.
Labels
=
make
(
map
[
string
]
string
,
0
)
}
globalRole
=
globalRole
.
DeepCopy
()
globalRole
.
Labels
[
constants
.
KubefedManagedLabel
]
=
"false"
_
,
err
:=
c
.
ksClient
.
IamV1alpha2
()
.
GlobalRoles
()
.
Update
(
globalRole
)
if
err
!=
nil
{
klog
.
Error
(
err
)
}
}
return
nil
}
pkg/controller/globalrolebinding/globalrolebinding_controller.go
浏览文件 @
4fcaa78b
...
...
@@ -23,6 +23,8 @@ import (
rbacv1
"k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
...
...
@@ -33,8 +35,11 @@ import (
"k8s.io/client-go/util/workqueue"
"k8s.io/klog"
iamv1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
kubesphere
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
iamv1alpha2informers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/iam/v1alpha2"
iamv1alpha2listers
"kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/constants"
"reflect"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"time"
)
...
...
@@ -43,18 +48,18 @@ 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"
messageResourceSynced
=
"GlobalRoleBinding synced successfully"
controllerName
=
"globalrolebinding-controller"
)
type
Controller
struct
{
k8sClient
kubernetes
.
Interface
informer
iamv1alpha2informers
.
GlobalRoleBindingInformer
lister
iamv1alpha2listers
.
GlobalRoleBindingLister
synced
cache
.
InformerSynced
k8sClient
kubernetes
.
Interface
ksClient
kubesphere
.
Interface
globalRoleBindingInformer
iamv1alpha2informers
.
GlobalRoleBindingInformer
globalRoleBindingLister
iamv1alpha2listers
.
GlobalRoleBindingLister
globalRoleBindingSynced
cache
.
InformerSynced
fedGlobalRoleBindingCache
cache
.
Store
fedGlobalRoleBindingCacheController
cache
.
Controller
// 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
...
...
@@ -67,7 +72,8 @@ type Controller struct {
multiClusterEnabled
bool
}
func
NewController
(
k8sClient
kubernetes
.
Interface
,
globalRoleBindingInformer
iamv1alpha2informers
.
GlobalRoleBindingInformer
,
multiClusterEnabled
bool
)
*
Controller
{
func
NewController
(
k8sClient
kubernetes
.
Interface
,
ksClient
kubesphere
.
Interface
,
globalRoleBindingInformer
iamv1alpha2informers
.
GlobalRoleBindingInformer
,
fedGlobalRoleBindingCache
cache
.
Store
,
fedGlobalRoleBindingCacheController
cache
.
Controller
,
multiClusterEnabled
bool
)
*
Controller
{
// Create event broadcaster
// Add sample-controller types to the default Kubernetes Scheme so Events can be
// logged for sample-controller types.
...
...
@@ -78,13 +84,16 @@ func NewController(k8sClient kubernetes.Interface, globalRoleBindingInformer iam
eventBroadcaster
.
StartRecordingToSink
(
&
typedcorev1
.
EventSinkImpl
{
Interface
:
k8sClient
.
CoreV1
()
.
Events
(
""
)})
recorder
:=
eventBroadcaster
.
NewRecorder
(
scheme
.
Scheme
,
corev1
.
EventSource
{
Component
:
controllerName
})
ctl
:=
&
Controller
{
k8sClient
:
k8sClient
,
informer
:
globalRoleBindingInformer
,
lister
:
globalRoleBindingInformer
.
Lister
(),
synced
:
globalRoleBindingInformer
.
Informer
()
.
HasSynced
,
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"ClusterRoleBinding"
),
recorder
:
recorder
,
multiClusterEnabled
:
multiClusterEnabled
,
k8sClient
:
k8sClient
,
ksClient
:
ksClient
,
globalRoleBindingInformer
:
globalRoleBindingInformer
,
globalRoleBindingLister
:
globalRoleBindingInformer
.
Lister
(),
globalRoleBindingSynced
:
globalRoleBindingInformer
.
Informer
()
.
HasSynced
,
fedGlobalRoleBindingCache
:
fedGlobalRoleBindingCache
,
fedGlobalRoleBindingCacheController
:
fedGlobalRoleBindingCacheController
,
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"GlobalRoleBinding"
),
recorder
:
recorder
,
multiClusterEnabled
:
multiClusterEnabled
,
}
klog
.
Info
(
"Setting up event handlers"
)
globalRoleBindingInformer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
...
...
@@ -101,14 +110,19 @@ 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"
)
klog
.
Info
(
"Starting
GlobalRoleBinding
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
{
synced
:=
make
([]
cache
.
InformerSynced
,
0
)
synced
=
append
(
synced
,
c
.
globalRoleBindingSynced
)
if
c
.
multiClusterEnabled
{
synced
=
append
(
synced
,
c
.
fedGlobalRoleBindingCacheController
.
HasSynced
)
}
if
ok
:=
cache
.
WaitForCacheSync
(
stopCh
,
synced
...
);
!
ok
{
return
fmt
.
Errorf
(
"failed to wait for caches to sync"
)
}
...
...
@@ -197,12 +211,12 @@ func (c *Controller) processNextWorkItem() bool {
// with the current status of the resource.
func
(
c
*
Controller
)
reconcile
(
key
string
)
error
{
globalRoleBinding
,
err
:=
c
.
l
ister
.
Get
(
key
)
globalRoleBinding
,
err
:=
c
.
globalRoleBindingL
ister
.
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
(
"
cluster
rolebinding '%s' in work queue no longer exists"
,
key
))
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"
global
rolebinding '%s' in work queue no longer exists"
,
key
))
return
nil
}
klog
.
Error
(
err
)
...
...
@@ -216,6 +230,13 @@ func (c *Controller) reconcile(key string) error {
}
}
if
c
.
multiClusterEnabled
{
if
err
=
c
.
multiClusterSync
(
globalRoleBinding
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
}
c
.
recorder
.
Event
(
globalRoleBinding
,
corev1
.
EventTypeNormal
,
successSynced
,
messageResourceSynced
)
return
nil
}
...
...
@@ -224,89 +245,181 @@ func (c *Controller) Start(stopCh <-chan struct{}) error {
return
c
.
Run
(
4
,
stopCh
)
}
func
(
c
*
Controller
)
relateToClusterAdmin
(
globalRoleBinding
*
iamv1alpha2
.
GlobalRoleBinding
)
error
{
func
(
c
*
Controller
)
multiClusterSync
(
globalRoleBinding
*
iamv1alpha2
.
GlobalRoleBinding
)
error
{
if
c
.
multiClusterEnabled
{
if
err
:=
c
.
ensureNotControlledByKubefed
(
globalRoleBinding
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
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
{},
},
},
}
obj
,
exist
,
err
:=
c
.
fedGlobalRoleBindingCache
.
GetByKey
(
globalRoleBinding
.
Name
)
if
!
exist
{
return
c
.
createFederatedGlobalRoleBinding
(
globalRoleBinding
)
}
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
err
:=
controllerutil
.
SetControllerReference
(
globalRoleBinding
,
federatedClusterRoleBinding
,
scheme
.
Scheme
)
var
federatedGlobalRoleBinding
iamv1alpha2
.
FederatedRoleBinding
if
err
!=
nil
{
return
err
}
err
=
runtime
.
DefaultUnstructuredConverter
.
FromUnstructured
(
obj
.
(
*
unstructured
.
Unstructured
)
.
Object
,
&
federatedGlobalRoleBinding
)
data
,
err
:=
json
.
Marshal
(
federatedClusterRoleBinding
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
if
err
!=
nil
{
return
err
}
if
!
reflect
.
DeepEqual
(
federatedGlobalRoleBinding
.
Spec
.
Template
.
Subjects
,
globalRoleBinding
.
Subjects
)
||
!
reflect
.
DeepEqual
(
federatedGlobalRoleBinding
.
Spec
.
Template
.
RoleRef
,
globalRoleBinding
.
RoleRef
)
||
!
reflect
.
DeepEqual
(
federatedGlobalRoleBinding
.
Spec
.
Template
.
Labels
,
globalRoleBinding
.
Labels
)
||
!
reflect
.
DeepEqual
(
federatedGlobalRoleBinding
.
Spec
.
Template
.
Annotations
,
globalRoleBinding
.
Annotations
)
{
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
federatedGlobalRoleBinding
.
Spec
.
Template
.
Subjects
=
globalRoleBinding
.
Subjects
federatedGlobalRoleBinding
.
Spec
.
Template
.
RoleRef
=
globalRoleBinding
.
RoleRef
federatedGlobalRoleBinding
.
Spec
.
Template
.
Annotations
=
globalRoleBinding
.
Annotations
federatedGlobalRoleBinding
.
Spec
.
Template
.
Labels
=
globalRoleBinding
.
Labels
err
=
cli
.
RESTClient
()
.
Post
()
.
AbsPath
(
federatedResourceAPIPath
)
.
Body
(
data
)
.
Do
()
.
Error
()
return
c
.
updateFederatedGlobalRoleBinding
(
&
federatedGlobalRoleBinding
)
}
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
return
nil
}
func
(
c
*
Controller
)
relateToClusterAdmin
(
globalRoleBinding
*
iamv1alpha2
.
GlobalRoleBinding
)
error
{
username
:=
findExpectUsername
(
globalRoleBinding
)
// unexpected
if
username
==
""
{
return
nil
}
clusterRoleBinding
:=
&
rbacv1
.
ClusterRoleBinding
{
TypeMeta
:
metav1
.
TypeMeta
{},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
fmt
.
Sprintf
(
"%s-%s"
,
username
,
iamv1alpha2
.
ClusterAdmin
),
},
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
findExpectUsername
(
globalRoleBinding
*
iamv1alpha2
.
GlobalRoleBinding
)
string
{
for
_
,
subject
:=
range
globalRoleBinding
.
Subjects
{
if
subject
.
Kind
==
iamv1alpha2
.
ResourceKindUser
{
return
subject
.
Name
}
}
else
{
}
return
""
}
clusterRoleBinding
:=
&
rbacv1
.
ClusterRoleBinding
{
TypeMeta
:
metav1
.
TypeMeta
{},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
fmt
.
Sprintf
(
"fed-%s"
,
globalRoleBinding
.
Name
),
func
(
c
*
Controller
)
createFederatedGlobalRoleBinding
(
globalRoleBinding
*
iamv1alpha2
.
GlobalRoleBinding
)
error
{
federatedGlobalRoleBinding
:=
&
iamv1alpha2
.
FederatedRoleBinding
{
TypeMeta
:
metav1
.
TypeMeta
{
Kind
:
iamv1alpha2
.
FedGlobalRoleBindingKind
,
APIVersion
:
iamv1alpha2
.
FedGlobalRoleBindingResource
.
Group
+
"/"
+
iamv1alpha2
.
FedGlobalRoleBindingResource
.
Version
,
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
globalRoleBinding
.
Name
,
},
Spec
:
iamv1alpha2
.
FederatedRoleBindingSpec
{
Template
:
iamv1alpha2
.
RoleBindingTemplate
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Labels
:
globalRoleBinding
.
Labels
,
Annotations
:
globalRoleBinding
.
Annotations
,
},
Subjects
:
globalRoleBinding
.
Subjects
,
RoleRef
:
globalRoleBinding
.
RoleRef
,
},
Subjects
:
ensureSubjectAPIVersionIsValid
(
globalRoleBinding
.
Subjects
),
RoleRef
:
rbacv1
.
RoleRef
{
APIGroup
:
"rbac.authorization.k8s.io"
,
Kind
:
iamv1alpha2
.
ResourceKindClusterRole
,
Name
:
iamv1alpha2
.
ClusterAdmin
,
Placement
:
iamv1alpha2
.
Placement
{
ClusterSelector
:
iamv1alpha2
.
ClusterSelector
{},
},
},
}
err
:=
controllerutil
.
SetControllerReference
(
globalRoleBinding
,
federatedGlobalRoleBinding
,
scheme
.
Scheme
)
if
err
!=
nil
{
return
err
}
data
,
err
:=
json
.
Marshal
(
federatedGlobalRoleBinding
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Post
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s"
,
iamv1alpha2
.
FedGlobalRoleBindingResource
.
Group
,
iamv1alpha2
.
FedGlobalRoleBindingResource
.
Version
,
iamv1alpha2
.
FedGlobalRoleBindingResource
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
}
return
nil
}
err
:=
controllerutil
.
SetControllerReference
(
globalRoleBinding
,
clusterRoleBinding
,
scheme
.
Scheme
)
func
(
c
*
Controller
)
updateFederatedGlobalRoleBinding
(
federatedGlobalRoleBinding
*
iamv1alpha2
.
FederatedRoleBinding
)
error
{
if
err
!=
nil
{
return
err
data
,
err
:=
json
.
Marshal
(
federatedGlobalRoleBinding
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Put
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s/%s"
,
iamv1alpha2
.
FedGlobalRoleBindingResource
.
Group
,
iamv1alpha2
.
FedGlobalRoleBindingResource
.
Version
,
iamv1alpha2
.
FedGlobalRoleBindingResource
.
Name
,
federatedGlobalRoleBinding
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
nil
}
return
err
}
_
,
err
=
c
.
k8sClient
.
RbacV1
()
.
ClusterRoleBindings
()
.
Create
(
clusterRoleBinding
)
return
nil
}
func
(
c
*
Controller
)
ensureNotControlledByKubefed
(
globalRoleBinding
*
iamv1alpha2
.
GlobalRoleBinding
)
error
{
if
globalRoleBinding
.
Labels
[
constants
.
KubefedManagedLabel
]
!=
"false"
{
if
globalRoleBinding
.
Labels
==
nil
{
globalRoleBinding
.
Labels
=
make
(
map
[
string
]
string
,
0
)
}
globalRoleBinding
=
globalRoleBinding
.
DeepCopy
()
globalRoleBinding
.
Labels
[
constants
.
KubefedManagedLabel
]
=
"false"
_
,
err
:=
c
.
ksClient
.
IamV1alpha2
()
.
GlobalRoleBindings
()
.
Update
(
globalRoleBinding
)
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
klog
.
Error
(
err
)
}
}
return
nil
}
...
...
pkg/controller/namespace/namespace_controller.go
浏览文件 @
4fcaa78b
...
...
@@ -17,17 +17,23 @@ limitations under the License.
package
namespace
import
(
"bytes"
"context"
"fmt"
appsv1
"k8s.io/api/apps/v1"
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"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
iamv1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
tenantv1alpha1
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"reflect"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
...
...
@@ -37,11 +43,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/source"
)
/**
* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller
* business logic. Delete these comments after modifying this file.*
*/
// Add creates a new Namespace Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func
Add
(
mgr
manager
.
Manager
)
error
{
...
...
@@ -138,7 +139,15 @@ func (r *ReconcileNamespace) Reconcile(request reconcile.Request) (reconcile.Res
return
reconcile
.
Result
{},
nil
}
if
err
=
r
.
checkAndBindWorkspace
(
instance
);
err
!=
nil
{
if
err
=
r
.
bindWorkspace
(
instance
);
err
!=
nil
{
return
reconcile
.
Result
{},
err
}
if
err
=
r
.
initRoles
(
instance
);
err
!=
nil
{
return
reconcile
.
Result
{},
err
}
if
err
=
r
.
initCreatorRoleBinding
(
instance
);
err
!=
nil
{
return
reconcile
.
Result
{},
err
}
...
...
@@ -157,7 +166,7 @@ func (r *ReconcileNamespace) isControlledByWorkspace(namespace *corev1.Namespace
return
true
,
nil
}
func
(
r
*
ReconcileNamespace
)
checkAndB
indWorkspace
(
namespace
*
corev1
.
Namespace
)
error
{
func
(
r
*
ReconcileNamespace
)
b
indWorkspace
(
namespace
*
corev1
.
Namespace
)
error
{
workspaceName
:=
namespace
.
Labels
[
constants
.
WorkspaceLabelKey
]
...
...
@@ -165,7 +174,7 @@ func (r *ReconcileNamespace) checkAndBindWorkspace(namespace *corev1.Namespace)
return
nil
}
workspace
:=
&
v1alpha1
.
Workspace
{}
workspace
:=
&
tenant
v1alpha1
.
Workspace
{}
err
:=
r
.
Get
(
context
.
TODO
(),
types
.
NamespacedName
{
Name
:
workspaceName
},
workspace
)
...
...
@@ -174,18 +183,20 @@ func (r *ReconcileNamespace) checkAndBindWorkspace(namespace *corev1.Namespace)
if
errors
.
IsNotFound
(
err
)
{
return
nil
}
klog
.
Error
f
(
"bind workspace namespace: %s, workspace: %s, error: %s"
,
namespace
.
Name
,
workspaceName
,
err
)
klog
.
Error
(
err
)
return
err
}
if
!
metav1
.
IsControlledBy
(
namespace
,
workspace
)
{
// federated namespace not controlled by workspace
if
namespace
.
Labels
[
constants
.
KubefedManagedLabel
]
!=
"true"
&&
!
metav1
.
IsControlledBy
(
namespace
,
workspace
)
{
namespace
.
OwnerReferences
=
removeWorkspaceOwnerReferences
(
namespace
.
OwnerReferences
)
if
err
:=
controllerutil
.
SetControllerReference
(
workspace
,
namespace
,
r
.
scheme
);
err
!=
nil
{
klog
.
Error
f
(
"bind workspace namespace: %s, workspace: %s, error: %s"
,
namespace
.
Name
,
workspaceName
,
err
)
klog
.
Error
(
err
)
return
err
}
err
=
r
.
Update
(
context
.
TODO
(),
namespace
)
if
err
!=
nil
{
klog
.
Error
f
(
"bind workspace namespace: %s, workspace: %s, error: %s"
,
namespace
.
Name
,
workspaceName
,
err
)
klog
.
Error
(
err
)
return
err
}
}
...
...
@@ -193,6 +204,16 @@ func (r *ReconcileNamespace) checkAndBindWorkspace(namespace *corev1.Namespace)
return
nil
}
func
removeWorkspaceOwnerReferences
(
ownerReferences
[]
metav1
.
OwnerReference
)
[]
metav1
.
OwnerReference
{
for
i
,
owner
:=
range
ownerReferences
{
if
owner
.
Kind
==
tenantv1alpha1
.
ResourceKindWorkspace
{
ownerReferences
=
append
(
ownerReferences
[
:
i
],
ownerReferences
[
i
+
1
:
]
...
)
i
--
}
}
return
ownerReferences
}
func
(
r
*
ReconcileNamespace
)
deleteRouter
(
namespace
string
)
error
{
routerName
:=
constants
.
IngressControllerPrefix
+
namespace
...
...
@@ -230,5 +251,79 @@ func (r *ReconcileNamespace) deleteRouter(namespace string) error {
}
return
nil
}
func
(
r
*
ReconcileNamespace
)
initRoles
(
namespace
*
corev1
.
Namespace
)
error
{
var
roleBases
iamv1alpha2
.
RoleBaseList
err
:=
r
.
List
(
context
.
Background
(),
&
roleBases
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
for
_
,
roleBase
:=
range
roleBases
.
Items
{
var
role
rbacv1
.
Role
if
err
=
yaml
.
NewYAMLOrJSONDecoder
(
bytes
.
NewBuffer
(
roleBase
.
Role
.
Raw
),
1024
)
.
Decode
(
&
role
);
err
==
nil
{
var
old
rbacv1
.
Role
err
:=
r
.
Client
.
Get
(
context
.
Background
(),
types
.
NamespacedName
{
Namespace
:
namespace
.
Name
,
Name
:
role
.
Name
},
&
old
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
role
.
Namespace
=
namespace
.
Name
err
=
r
.
Client
.
Create
(
context
.
Background
(),
&
role
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
continue
}
}
if
!
reflect
.
DeepEqual
(
role
.
Labels
,
old
.
Labels
)
||
!
reflect
.
DeepEqual
(
role
.
Annotations
,
old
.
Annotations
)
||
!
reflect
.
DeepEqual
(
role
.
Rules
,
old
.
Rules
)
{
old
.
Labels
=
role
.
Labels
old
.
Annotations
=
role
.
Annotations
old
.
Rules
=
role
.
Rules
return
r
.
Update
(
context
.
Background
(),
&
old
)
}
}
}
return
nil
}
func
(
r
*
ReconcileNamespace
)
initCreatorRoleBinding
(
namespace
*
corev1
.
Namespace
)
error
{
if
creator
:=
namespace
.
Annotations
[
constants
.
CreatorAnnotationKey
];
creator
!=
""
{
creatorRoleBinding
:=
&
rbacv1
.
RoleBinding
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
fmt
.
Sprintf
(
"%s-%s"
,
creator
,
iamv1alpha2
.
NamespaceAdmin
),
Namespace
:
namespace
.
Name
,
},
RoleRef
:
rbacv1
.
RoleRef
{
APIGroup
:
rbacv1
.
GroupName
,
Kind
:
iamv1alpha2
.
ResourceKindRole
,
Name
:
iamv1alpha2
.
NamespaceAdmin
,
},
Subjects
:
[]
rbacv1
.
Subject
{
{
Name
:
creator
,
Kind
:
iamv1alpha2
.
ResourceKindUser
,
APIGroup
:
rbacv1
.
GroupName
,
},
},
}
err
:=
r
.
Client
.
Create
(
context
.
Background
(),
creatorRoleBinding
)
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
klog
.
Error
(
err
)
return
err
}
}
return
nil
}
pkg/controller/user/user_controller.go
浏览文件 @
4fcaa78b
...
...
@@ -17,12 +17,17 @@ limitations under the License.
package
user
import
(
"encoding/json"
"fmt"
"golang.org/x/crypto/bcrypt"
corev1
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
corev1informers
"k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
typedcorev1
"k8s.io/client-go/kubernetes/typed/core/v1"
...
...
@@ -36,7 +41,10 @@ import (
kubespherescheme
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
userinformer
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/iam/v1alpha2"
userlister
"kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/models/kubeconfig"
"reflect"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"strconv"
"time"
)
...
...
@@ -50,12 +58,15 @@ const (
)
type
Controller
struct
{
k8sClient
kubernetes
.
Interface
ksClient
kubesphere
.
Interface
kubeconfig
kubeconfig
.
Interface
userInformer
userinformer
.
UserInformer
userLister
userlister
.
UserLister
userSynced
cache
.
InformerSynced
k8sClient
kubernetes
.
Interface
ksClient
kubesphere
.
Interface
kubeconfig
kubeconfig
.
Interface
userInformer
userinformer
.
UserInformer
userLister
userlister
.
UserLister
userSynced
cache
.
InformerSynced
cmSynced
cache
.
InformerSynced
fedUserCache
cache
.
Store
fedUserController
cache
.
Controller
// 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
...
...
@@ -64,11 +75,13 @@ type Controller struct {
workqueue
workqueue
.
RateLimitingInterface
// recorder is an event recorder for recording Event resources to the
// Kubernetes API.
recorder
record
.
EventRecorder
recorder
record
.
EventRecorder
multiClusterEnabled
bool
}
func
NewController
(
k8sClient
kubernetes
.
Interface
,
ksClient
kubesphere
.
Interface
,
config
*
rest
.
Config
,
userInformer
userinformer
.
UserInformer
)
*
Controller
{
config
*
rest
.
Config
,
userInformer
userinformer
.
UserInformer
,
fedUserCache
cache
.
Store
,
fedUserController
cache
.
Controller
,
configMapInformer
corev1informers
.
ConfigMapInformer
,
multiClusterEnabled
bool
)
*
Controller
{
// Create event broadcaster
// Add sample-controller types to the default Kubernetes Scheme so Events can be
// logged for sample-controller types.
...
...
@@ -81,17 +94,21 @@ func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface
recorder
:=
eventBroadcaster
.
NewRecorder
(
scheme
.
Scheme
,
corev1
.
EventSource
{
Component
:
controllerName
})
var
kubeconfigOperator
kubeconfig
.
Interface
if
config
!=
nil
{
kubeconfigOperator
=
kubeconfig
.
NewOperator
(
k8sClient
,
config
,
""
)
kubeconfigOperator
=
kubeconfig
.
NewOperator
(
k8sClient
,
config
MapInformer
,
config
)
}
ctl
:=
&
Controller
{
k8sClient
:
k8sClient
,
ksClient
:
ksClient
,
kubeconfig
:
kubeconfigOperator
,
userInformer
:
userInformer
,
userLister
:
userInformer
.
Lister
(),
userSynced
:
userInformer
.
Informer
()
.
HasSynced
,
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"Users"
),
recorder
:
recorder
,
k8sClient
:
k8sClient
,
ksClient
:
ksClient
,
kubeconfig
:
kubeconfigOperator
,
userInformer
:
userInformer
,
userLister
:
userInformer
.
Lister
(),
userSynced
:
userInformer
.
Informer
()
.
HasSynced
,
cmSynced
:
configMapInformer
.
Informer
()
.
HasSynced
,
fedUserCache
:
fedUserCache
,
fedUserController
:
fedUserController
,
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"Users"
),
recorder
:
recorder
,
multiClusterEnabled
:
multiClusterEnabled
,
}
klog
.
Info
(
"Setting up event handlers"
)
userInformer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
...
...
@@ -108,14 +125,19 @@ 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
.
userSynced
);
!
ok
{
synced
:=
make
([]
cache
.
InformerSynced
,
0
)
synced
=
append
(
synced
,
c
.
userSynced
,
c
.
cmSynced
)
if
c
.
multiClusterEnabled
{
synced
=
append
(
synced
,
c
.
fedUserController
.
HasSynced
)
}
if
ok
:=
cache
.
WaitForCacheSync
(
stopCh
,
synced
...
);
!
ok
{
return
fmt
.
Errorf
(
"failed to wait for caches to sync"
)
}
...
...
@@ -217,16 +239,22 @@ func (c *Controller) reconcile(key string) error {
return
err
}
user
,
err
=
c
.
encryptPassword
(
user
.
DeepCopy
())
if
err
!=
nil
{
if
user
,
err
=
c
.
ensurePasswordIsEncrypted
(
user
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
if
c
.
kubeconfig
!=
nil
{
err
=
c
.
kubeconfig
.
CreateKubeConfig
(
user
)
if
err
!=
nil
{
// ensure user kubeconfig configmap is created
if
err
=
c
.
kubeconfig
.
CreateKubeConfig
(
user
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
}
// synchronization through kubefed-controller when multi cluster is enabled
if
c
.
multiClusterEnabled
{
if
err
=
c
.
multiClusterSync
(
user
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
...
...
@@ -240,9 +268,8 @@ func (c *Controller) Start(stopCh <-chan struct{}) error {
return
c
.
Run
(
4
,
stopCh
)
}
func
(
c
*
Controller
)
en
cryptPasswor
d
(
user
*
iamv1alpha2
.
User
)
(
*
iamv1alpha2
.
User
,
error
)
{
func
(
c
*
Controller
)
en
surePasswordIsEncrypte
d
(
user
*
iamv1alpha2
.
User
)
(
*
iamv1alpha2
.
User
,
error
)
{
encrypted
,
err
:=
strconv
.
ParseBool
(
user
.
Annotations
[
iamv1alpha2
.
PasswordEncryptedAnnotation
])
// password is not encrypted
if
err
!=
nil
||
!
encrypted
{
password
,
err
:=
encrypt
(
user
.
Spec
.
EncryptedPassword
)
...
...
@@ -250,19 +277,146 @@ func (c *Controller) encryptPassword(user *iamv1alpha2.User) (*iamv1alpha2.User,
klog
.
Error
(
err
)
return
nil
,
err
}
user
=
user
.
DeepCopy
()
user
.
Spec
.
EncryptedPassword
=
password
if
user
.
Annotations
==
nil
{
user
.
Annotations
=
make
(
map
[
string
]
string
,
0
)
}
user
.
Annotations
[
iamv1alpha2
.
PasswordEncryptedAnnotation
]
=
"true"
user
.
Status
.
State
=
iamv1alpha2
.
UserActive
return
c
.
ksClient
.
IamV1alpha2
()
.
Users
()
.
Update
(
user
)
}
return
user
,
nil
}
func
(
c
*
Controller
)
ensureNotControlledByKubefed
(
user
*
iamv1alpha2
.
User
)
error
{
if
user
.
Labels
[
constants
.
KubefedManagedLabel
]
!=
"false"
{
if
user
.
Labels
==
nil
{
user
.
Labels
=
make
(
map
[
string
]
string
,
0
)
}
user
=
user
.
DeepCopy
()
user
.
Labels
[
constants
.
KubefedManagedLabel
]
=
"false"
_
,
err
:=
c
.
ksClient
.
IamV1alpha2
()
.
Users
()
.
Update
(
user
)
if
err
!=
nil
{
klog
.
Error
(
err
)
}
}
return
nil
}
updated
,
err
:=
c
.
ksClient
.
IamV1alpha2
()
.
Users
()
.
Update
(
user
)
func
(
c
*
Controller
)
multiClusterSync
(
user
*
iamv1alpha2
.
User
)
error
{
return
updated
,
err
if
err
:=
c
.
ensureNotControlledByKubefed
(
user
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
return
user
,
nil
obj
,
exist
,
err
:=
c
.
fedUserCache
.
GetByKey
(
user
.
Name
)
if
!
exist
{
return
c
.
createFederatedUser
(
user
)
}
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
var
federatedUser
iamv1alpha2
.
FederatedUser
if
err
=
runtime
.
DefaultUnstructuredConverter
.
FromUnstructured
(
obj
.
(
*
unstructured
.
Unstructured
)
.
Object
,
&
federatedUser
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
if
!
reflect
.
DeepEqual
(
federatedUser
.
Spec
.
Template
.
Spec
,
user
.
Spec
)
||
!
reflect
.
DeepEqual
(
federatedUser
.
Spec
.
Template
.
Status
,
user
.
Status
)
||
!
reflect
.
DeepEqual
(
federatedUser
.
Labels
,
user
.
Labels
)
||
!
reflect
.
DeepEqual
(
federatedUser
.
Annotations
,
user
.
Annotations
)
{
federatedUser
.
Labels
=
user
.
Labels
federatedUser
.
Spec
.
Template
.
Spec
=
user
.
Spec
federatedUser
.
Spec
.
Template
.
Status
=
user
.
Status
federatedUser
.
Spec
.
Template
.
Labels
=
user
.
Labels
federatedUser
.
Spec
.
Template
.
Annotations
=
user
.
Annotations
return
c
.
updateFederatedUser
(
&
federatedUser
)
}
return
nil
}
func
(
c
*
Controller
)
createFederatedUser
(
user
*
iamv1alpha2
.
User
)
error
{
federatedUser
:=
&
iamv1alpha2
.
FederatedUser
{
TypeMeta
:
metav1
.
TypeMeta
{
Kind
:
iamv1alpha2
.
FedUserKind
,
APIVersion
:
iamv1alpha2
.
FedUserResource
.
Group
+
"/"
+
iamv1alpha2
.
FedUserResource
.
Version
,
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
user
.
Name
,
},
Spec
:
iamv1alpha2
.
FederatedUserSpec
{
Template
:
iamv1alpha2
.
UserTemplate
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Labels
:
user
.
Labels
,
Annotations
:
user
.
Annotations
,
},
Spec
:
user
.
Spec
,
Status
:
user
.
Status
,
},
Placement
:
iamv1alpha2
.
Placement
{
ClusterSelector
:
iamv1alpha2
.
ClusterSelector
{},
},
},
}
// must bind user lifecycle
err
:=
controllerutil
.
SetControllerReference
(
user
,
federatedUser
,
scheme
.
Scheme
)
if
err
!=
nil
{
return
err
}
data
,
err
:=
json
.
Marshal
(
federatedUser
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Post
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s"
,
iamv1alpha2
.
FedUserResource
.
Group
,
iamv1alpha2
.
FedUserResource
.
Version
,
iamv1alpha2
.
FedUserResource
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
(
c
*
Controller
)
updateFederatedUser
(
fedUser
*
iamv1alpha2
.
FederatedUser
)
error
{
data
,
err
:=
json
.
Marshal
(
fedUser
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Put
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s/%s"
,
iamv1alpha2
.
FedUserResource
.
Group
,
iamv1alpha2
.
FedUserResource
.
Version
,
iamv1alpha2
.
FedUserResource
.
Name
,
fedUser
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
encrypt
(
password
string
)
(
string
,
error
)
{
...
...
pkg/controller/user/user_controller_test.go
浏览文件 @
4fcaa78b
...
...
@@ -92,7 +92,7 @@ func (f *fixture) newController() (*Controller, ksinformers.SharedInformerFactor
}
}
c
:=
NewController
(
f
.
k8sclient
,
f
.
ksclient
,
nil
,
ksinformers
.
Iam
()
.
V1alpha2
()
.
Users
())
c
:=
NewController
(
f
.
k8sclient
,
f
.
ksclient
,
nil
,
ksinformers
.
Iam
()
.
V1alpha2
()
.
Users
()
,
nil
,
nil
,
k8sinformers
.
Core
()
.
V1
()
.
ConfigMaps
(),
false
)
c
.
userSynced
=
alwaysReady
c
.
recorder
=
&
record
.
FakeRecorder
{}
...
...
pkg/controller/workspace/workspace_controller.go
浏览文件 @
4fcaa78b
...
...
@@ -17,12 +17,19 @@ limitations under the License.
package
workspace
import
(
"bytes"
"context"
"fmt"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/tools/record"
"k8s.io/klog"
iamv1alpha2
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
tenantv1alpha1
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"reflect"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
...
...
@@ -117,5 +124,48 @@ func (r *ReconcileWorkspace) Reconcile(request reconcile.Request) (reconcile.Res
return
reconcile
.
Result
{},
nil
}
if
err
=
r
.
initRoles
(
instance
);
err
!=
nil
{
klog
.
Error
(
err
)
return
reconcile
.
Result
{},
err
}
return
reconcile
.
Result
{},
nil
}
func
(
r
*
ReconcileWorkspace
)
initRoles
(
workspace
*
tenantv1alpha1
.
Workspace
)
error
{
var
roleBases
iamv1alpha2
.
RoleBaseList
err
:=
r
.
List
(
context
.
Background
(),
&
roleBases
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
for
_
,
roleBase
:=
range
roleBases
.
Items
{
var
role
iamv1alpha2
.
WorkspaceRole
if
err
=
yaml
.
NewYAMLOrJSONDecoder
(
bytes
.
NewBuffer
(
roleBase
.
Role
.
Raw
),
1024
)
.
Decode
(
&
role
);
err
==
nil
{
var
old
iamv1alpha2
.
WorkspaceRole
err
:=
r
.
Client
.
Get
(
context
.
Background
(),
types
.
NamespacedName
{
Name
:
fmt
.
Sprintf
(
"%s-%s"
,
workspace
.
Name
,
role
.
Name
)},
&
old
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
role
.
Name
=
fmt
.
Sprintf
(
"%s-%s"
,
workspace
.
Name
,
role
.
Name
)
role
.
Labels
[
tenantv1alpha1
.
WorkspaceLabel
]
=
workspace
.
Name
return
r
.
Client
.
Create
(
context
.
Background
(),
&
role
)
}
}
if
!
reflect
.
DeepEqual
(
role
.
Labels
,
old
.
Labels
)
||
!
reflect
.
DeepEqual
(
role
.
Annotations
,
old
.
Annotations
)
||
!
reflect
.
DeepEqual
(
role
.
Rules
,
old
.
Rules
)
{
old
.
Labels
=
role
.
Labels
old
.
Annotations
=
role
.
Annotations
old
.
Rules
=
role
.
Rules
return
r
.
Update
(
context
.
Background
(),
&
old
)
}
}
}
return
nil
}
pkg/controller/workspacerole/workspacerole.go
0 → 100644
浏览文件 @
4fcaa78b
/*
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
workspacerole
import
(
"encoding/json"
"fmt"
corev1
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"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"
kubesphere
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
iamv1alpha2informers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/iam/v1alpha2"
iamv1alpha2listers
"kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/constants"
"reflect"
"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
=
"WorkspaceRole synced successfully"
controllerName
=
"workspacerole-controller"
)
type
Controller
struct
{
k8sClient
kubernetes
.
Interface
ksClient
kubesphere
.
Interface
workspaceRoleInformer
iamv1alpha2informers
.
WorkspaceRoleInformer
workspaceRoleLister
iamv1alpha2listers
.
WorkspaceRoleLister
workspaceRoleSynced
cache
.
InformerSynced
fedWorkspaceRoleCache
cache
.
Store
fedWorkspaceRoleCacheController
cache
.
Controller
// 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
}
func
NewController
(
k8sClient
kubernetes
.
Interface
,
ksClient
kubesphere
.
Interface
,
workspaceRoleInformer
iamv1alpha2informers
.
WorkspaceRoleInformer
,
fedWorkspaceRoleCache
cache
.
Store
,
fedWorkspaceRoleCacheController
cache
.
Controller
)
*
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
})
ctl
:=
&
Controller
{
k8sClient
:
k8sClient
,
ksClient
:
ksClient
,
workspaceRoleInformer
:
workspaceRoleInformer
,
workspaceRoleLister
:
workspaceRoleInformer
.
Lister
(),
workspaceRoleSynced
:
workspaceRoleInformer
.
Informer
()
.
HasSynced
,
fedWorkspaceRoleCache
:
fedWorkspaceRoleCache
,
fedWorkspaceRoleCacheController
:
fedWorkspaceRoleCacheController
,
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"WorkspaceRole"
),
recorder
:
recorder
,
}
klog
.
Info
(
"Setting up event handlers"
)
workspaceRoleInformer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
AddFunc
:
ctl
.
enqueueClusterRole
,
UpdateFunc
:
func
(
old
,
new
interface
{})
{
ctl
.
enqueueClusterRole
(
new
)
},
DeleteFunc
:
ctl
.
enqueueClusterRole
,
})
return
ctl
}
func
(
c
*
Controller
)
Run
(
threadiness
int
,
stopCh
<-
chan
struct
{})
error
{
defer
utilruntime
.
HandleCrash
()
defer
c
.
workqueue
.
ShutDown
()
// Start the informer factories to begin populating the informer caches
klog
.
Info
(
"Starting GlobalRole 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
.
workspaceRoleSynced
,
c
.
fedWorkspaceRoleCacheController
.
HasSynced
);
!
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
)
enqueueClusterRole
(
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
{
workspaceRole
,
err
:=
c
.
workspaceRoleLister
.
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
(
"workspacerole '%s' in work queue no longer exists"
,
key
))
return
nil
}
klog
.
Error
(
err
)
return
err
}
if
err
=
c
.
multiClusterSync
(
workspaceRole
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
c
.
recorder
.
Event
(
workspaceRole
,
corev1
.
EventTypeNormal
,
successSynced
,
messageResourceSynced
)
return
nil
}
func
(
c
*
Controller
)
Start
(
stopCh
<-
chan
struct
{})
error
{
return
c
.
Run
(
4
,
stopCh
)
}
func
(
c
*
Controller
)
multiClusterSync
(
workspaceRole
*
iamv1alpha2
.
WorkspaceRole
)
error
{
if
err
:=
c
.
ensureNotControlledByKubefed
(
workspaceRole
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
obj
,
exist
,
err
:=
c
.
fedWorkspaceRoleCache
.
GetByKey
(
workspaceRole
.
Name
)
if
!
exist
{
return
c
.
createFederatedWorkspaceRole
(
workspaceRole
)
}
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
var
federatedWorkspaceRole
iamv1alpha2
.
FederatedRole
if
err
=
runtime
.
DefaultUnstructuredConverter
.
FromUnstructured
(
obj
.
(
*
unstructured
.
Unstructured
)
.
Object
,
&
federatedWorkspaceRole
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
if
!
reflect
.
DeepEqual
(
federatedWorkspaceRole
.
Spec
.
Template
.
Rules
,
workspaceRole
.
Rules
)
||
!
reflect
.
DeepEqual
(
federatedWorkspaceRole
.
Spec
.
Template
.
Labels
,
workspaceRole
.
Labels
)
||
!
reflect
.
DeepEqual
(
federatedWorkspaceRole
.
Spec
.
Template
.
Annotations
,
workspaceRole
.
Annotations
)
{
federatedWorkspaceRole
.
Spec
.
Template
.
Rules
=
workspaceRole
.
Rules
federatedWorkspaceRole
.
Spec
.
Template
.
Annotations
=
workspaceRole
.
Annotations
federatedWorkspaceRole
.
Spec
.
Template
.
Labels
=
workspaceRole
.
Labels
return
c
.
updateFederatedGlobalRole
(
&
federatedWorkspaceRole
)
}
return
nil
}
func
(
c
*
Controller
)
createFederatedWorkspaceRole
(
workspaceRole
*
iamv1alpha2
.
WorkspaceRole
)
error
{
federatedWorkspaceRole
:=
&
iamv1alpha2
.
FederatedRole
{
TypeMeta
:
metav1
.
TypeMeta
{
Kind
:
iamv1alpha2
.
FedWorkspaceRoleKind
,
APIVersion
:
iamv1alpha2
.
FedWorkspaceRoleResource
.
Group
+
"/"
+
iamv1alpha2
.
FedWorkspaceRoleResource
.
Version
,
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
workspaceRole
.
Name
,
},
Spec
:
iamv1alpha2
.
FederatedRoleSpec
{
Template
:
iamv1alpha2
.
RoleTemplate
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Labels
:
workspaceRole
.
Labels
,
Annotations
:
workspaceRole
.
Annotations
,
},
Rules
:
workspaceRole
.
Rules
,
},
Placement
:
iamv1alpha2
.
Placement
{
ClusterSelector
:
iamv1alpha2
.
ClusterSelector
{},
},
},
}
err
:=
controllerutil
.
SetControllerReference
(
workspaceRole
,
federatedWorkspaceRole
,
scheme
.
Scheme
)
if
err
!=
nil
{
return
err
}
data
,
err
:=
json
.
Marshal
(
federatedWorkspaceRole
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Post
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s"
,
iamv1alpha2
.
FedWorkspaceRoleResource
.
Group
,
iamv1alpha2
.
FedWorkspaceRoleResource
.
Version
,
iamv1alpha2
.
FedWorkspaceRoleResource
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
(
c
*
Controller
)
updateFederatedGlobalRole
(
federatedWorkspaceRole
*
iamv1alpha2
.
FederatedRole
)
error
{
data
,
err
:=
json
.
Marshal
(
federatedWorkspaceRole
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Put
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s/%s"
,
iamv1alpha2
.
FedWorkspaceRoleResource
.
Group
,
iamv1alpha2
.
FedWorkspaceRoleResource
.
Version
,
iamv1alpha2
.
FedWorkspaceRoleResource
.
Name
,
federatedWorkspaceRole
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
(
c
*
Controller
)
ensureNotControlledByKubefed
(
workspaceRole
*
iamv1alpha2
.
WorkspaceRole
)
error
{
if
workspaceRole
.
Labels
[
constants
.
KubefedManagedLabel
]
!=
"false"
{
if
workspaceRole
.
Labels
==
nil
{
workspaceRole
.
Labels
=
make
(
map
[
string
]
string
,
0
)
}
workspaceRole
=
workspaceRole
.
DeepCopy
()
workspaceRole
.
Labels
[
constants
.
KubefedManagedLabel
]
=
"false"
_
,
err
:=
c
.
ksClient
.
IamV1alpha2
()
.
WorkspaceRoles
()
.
Update
(
workspaceRole
)
if
err
!=
nil
{
klog
.
Error
(
err
)
}
}
return
nil
}
pkg/controller/workspacerolebinding/workspacerolebinding_controller.go
0 → 100644
浏览文件 @
4fcaa78b
/*
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
workspacerolebinding
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"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"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"
kubesphere
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
iamv1alpha2informers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/iam/v1alpha2"
iamv1alpha2listers
"kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/constants"
"reflect"
"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
=
"WorkspaceRoleBinding synced successfully"
controllerName
=
"workspacerolebinding-controller"
)
type
Controller
struct
{
k8sClient
kubernetes
.
Interface
ksClient
kubesphere
.
Interface
workspaceRoleBindingInformer
iamv1alpha2informers
.
WorkspaceRoleBindingInformer
workspaceRoleBindingLister
iamv1alpha2listers
.
WorkspaceRoleBindingLister
workspaceRoleBindingSynced
cache
.
InformerSynced
fedWorkspaceRoleBindingCache
cache
.
Store
fedWorkspaceRoleBindingCacheController
cache
.
Controller
// 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
}
func
NewController
(
k8sClient
kubernetes
.
Interface
,
ksClient
kubesphere
.
Interface
,
workspaceRoleBindingInformer
iamv1alpha2informers
.
WorkspaceRoleBindingInformer
,
fedWorkspaceRoleBindingCache
cache
.
Store
,
fedWorkspaceRoleBindingCacheController
cache
.
Controller
)
*
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
})
ctl
:=
&
Controller
{
k8sClient
:
k8sClient
,
ksClient
:
ksClient
,
workspaceRoleBindingInformer
:
workspaceRoleBindingInformer
,
workspaceRoleBindingLister
:
workspaceRoleBindingInformer
.
Lister
(),
workspaceRoleBindingSynced
:
workspaceRoleBindingInformer
.
Informer
()
.
HasSynced
,
fedWorkspaceRoleBindingCache
:
fedWorkspaceRoleBindingCache
,
fedWorkspaceRoleBindingCacheController
:
fedWorkspaceRoleBindingCacheController
,
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"WorkspaceRoleBinding"
),
recorder
:
recorder
,
}
klog
.
Info
(
"Setting up event handlers"
)
workspaceRoleBindingInformer
.
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
()
// Start the informer factories to begin populating the informer caches
klog
.
Info
(
"Starting WorkspaceRoleBinding 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
.
workspaceRoleBindingSynced
,
c
.
fedWorkspaceRoleBindingCacheController
.
HasSynced
);
!
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
{
workspaceRoleBinding
,
err
:=
c
.
workspaceRoleBindingLister
.
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
(
"workspacerolebinding '%s' in work queue no longer exists"
,
key
))
return
nil
}
klog
.
Error
(
err
)
return
err
}
if
err
=
c
.
multiClusterSync
(
workspaceRoleBinding
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
c
.
recorder
.
Event
(
workspaceRoleBinding
,
corev1
.
EventTypeNormal
,
successSynced
,
messageResourceSynced
)
return
nil
}
func
(
c
*
Controller
)
Start
(
stopCh
<-
chan
struct
{})
error
{
return
c
.
Run
(
4
,
stopCh
)
}
func
(
c
*
Controller
)
multiClusterSync
(
workspaceRoleBinding
*
iamv1alpha2
.
WorkspaceRoleBinding
)
error
{
if
err
:=
c
.
ensureNotControlledByKubefed
(
workspaceRoleBinding
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
obj
,
exist
,
err
:=
c
.
fedWorkspaceRoleBindingCache
.
GetByKey
(
workspaceRoleBinding
.
Name
)
if
!
exist
{
return
c
.
createFederatedWorkspaceRoleBinding
(
workspaceRoleBinding
)
}
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
var
federatedWorkspaceRoleBinding
iamv1alpha2
.
FederatedRoleBinding
err
=
runtime
.
DefaultUnstructuredConverter
.
FromUnstructured
(
obj
.
(
*
unstructured
.
Unstructured
)
.
Object
,
&
federatedWorkspaceRoleBinding
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
if
!
reflect
.
DeepEqual
(
federatedWorkspaceRoleBinding
.
Spec
.
Template
.
Subjects
,
workspaceRoleBinding
.
Subjects
)
||
!
reflect
.
DeepEqual
(
federatedWorkspaceRoleBinding
.
Spec
.
Template
.
RoleRef
,
workspaceRoleBinding
.
RoleRef
)
||
!
reflect
.
DeepEqual
(
federatedWorkspaceRoleBinding
.
Spec
.
Template
.
Labels
,
workspaceRoleBinding
.
Labels
)
||
!
reflect
.
DeepEqual
(
federatedWorkspaceRoleBinding
.
Spec
.
Template
.
Annotations
,
workspaceRoleBinding
.
Annotations
)
{
federatedWorkspaceRoleBinding
.
Spec
.
Template
.
Subjects
=
workspaceRoleBinding
.
Subjects
federatedWorkspaceRoleBinding
.
Spec
.
Template
.
RoleRef
=
workspaceRoleBinding
.
RoleRef
federatedWorkspaceRoleBinding
.
Spec
.
Template
.
Annotations
=
workspaceRoleBinding
.
Annotations
federatedWorkspaceRoleBinding
.
Spec
.
Template
.
Labels
=
workspaceRoleBinding
.
Labels
return
c
.
updateFederatedWorkspaceRoleBinding
(
&
federatedWorkspaceRoleBinding
)
}
return
nil
}
func
(
c
*
Controller
)
relateToClusterAdmin
(
workspaceRoleBinding
*
iamv1alpha2
.
WorkspaceRoleBinding
)
error
{
username
:=
findExpectUsername
(
workspaceRoleBinding
)
// unexpected
if
username
==
""
{
return
nil
}
clusterRoleBinding
:=
&
rbacv1
.
ClusterRoleBinding
{
TypeMeta
:
metav1
.
TypeMeta
{},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
fmt
.
Sprintf
(
"%s-%s"
,
username
,
iamv1alpha2
.
ClusterAdmin
),
},
Subjects
:
ensureSubjectAPIVersionIsValid
(
workspaceRoleBinding
.
Subjects
),
RoleRef
:
rbacv1
.
RoleRef
{
APIGroup
:
"rbac.authorization.k8s.io"
,
Kind
:
iamv1alpha2
.
ResourceKindClusterRole
,
Name
:
iamv1alpha2
.
ClusterAdmin
,
},
}
err
:=
controllerutil
.
SetControllerReference
(
workspaceRoleBinding
,
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
}
// binding only one user is expected
func
findExpectUsername
(
workspaceRoleBinding
*
iamv1alpha2
.
WorkspaceRoleBinding
)
string
{
for
_
,
subject
:=
range
workspaceRoleBinding
.
Subjects
{
if
subject
.
Kind
==
iamv1alpha2
.
ResourceKindUser
{
return
subject
.
Name
}
}
return
""
}
func
(
c
*
Controller
)
createFederatedWorkspaceRoleBinding
(
workspaceRoleBinding
*
iamv1alpha2
.
WorkspaceRoleBinding
)
error
{
federatedWorkspaceRoleBinding
:=
&
iamv1alpha2
.
FederatedRoleBinding
{
TypeMeta
:
metav1
.
TypeMeta
{
Kind
:
iamv1alpha2
.
FedWorkspaceRoleBindingKind
,
APIVersion
:
iamv1alpha2
.
FedWorkspaceRoleBindingResource
.
Group
+
"/"
+
iamv1alpha2
.
FedWorkspaceRoleBindingResource
.
Version
,
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
workspaceRoleBinding
.
Name
,
},
Spec
:
iamv1alpha2
.
FederatedRoleBindingSpec
{
Template
:
iamv1alpha2
.
RoleBindingTemplate
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Labels
:
workspaceRoleBinding
.
Labels
,
Annotations
:
workspaceRoleBinding
.
Annotations
,
},
Subjects
:
workspaceRoleBinding
.
Subjects
,
RoleRef
:
workspaceRoleBinding
.
RoleRef
,
},
Placement
:
iamv1alpha2
.
Placement
{
ClusterSelector
:
iamv1alpha2
.
ClusterSelector
{},
},
},
}
err
:=
controllerutil
.
SetControllerReference
(
workspaceRoleBinding
,
federatedWorkspaceRoleBinding
,
scheme
.
Scheme
)
if
err
!=
nil
{
return
err
}
data
,
err
:=
json
.
Marshal
(
federatedWorkspaceRoleBinding
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Post
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s"
,
iamv1alpha2
.
FedWorkspaceRoleBindingResource
.
Group
,
iamv1alpha2
.
FedWorkspaceRoleBindingResource
.
Version
,
iamv1alpha2
.
FedWorkspaceRoleBindingResource
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
(
c
*
Controller
)
updateFederatedWorkspaceRoleBinding
(
federatedWorkspaceRoleBinding
*
iamv1alpha2
.
FederatedRoleBinding
)
error
{
data
,
err
:=
json
.
Marshal
(
federatedWorkspaceRoleBinding
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Put
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s/%s"
,
iamv1alpha2
.
FedWorkspaceRoleBindingResource
.
Group
,
iamv1alpha2
.
FedWorkspaceRoleBindingResource
.
Version
,
iamv1alpha2
.
FedWorkspaceRoleBindingResource
.
Name
,
federatedWorkspaceRoleBinding
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
(
c
*
Controller
)
ensureNotControlledByKubefed
(
workspaceRoleBinding
*
iamv1alpha2
.
WorkspaceRoleBinding
)
error
{
if
workspaceRoleBinding
.
Labels
[
constants
.
KubefedManagedLabel
]
!=
"false"
{
if
workspaceRoleBinding
.
Labels
==
nil
{
workspaceRoleBinding
.
Labels
=
make
(
map
[
string
]
string
,
0
)
}
workspaceRoleBinding
=
workspaceRoleBinding
.
DeepCopy
()
workspaceRoleBinding
.
Labels
[
constants
.
KubefedManagedLabel
]
=
"false"
_
,
err
:=
c
.
ksClient
.
IamV1alpha2
()
.
WorkspaceRoleBindings
()
.
Update
(
workspaceRoleBinding
)
if
err
!=
nil
{
klog
.
Error
(
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/controller/workspacetemplate/workspacetemplate_controller.go
0 → 100644
浏览文件 @
4fcaa78b
/*
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
workspacetemplate
import
(
"bytes"
"encoding/json"
"fmt"
corev1
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/util/yaml"
"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"
tenantv1alpha1
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
tenantv1alpha2
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha2"
kubesphere
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
iamv1alpha2informers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/iam/v1alpha2"
tenantv1alpha1informers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant/v1alpha1"
tenantv1alpha2informers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant/v1alpha2"
iamv1alpha2listers
"kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
tenantv1alpha1listers
"kubesphere.io/kubesphere/pkg/client/listers/tenant/v1alpha1"
tenantv1alpha2listers
"kubesphere.io/kubesphere/pkg/client/listers/tenant/v1alpha2"
"reflect"
"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
=
"WorkspaceTemplate synced successfully"
controllerName
=
"workspacetemplate-controller"
)
type
Controller
struct
{
k8sClient
kubernetes
.
Interface
ksClient
kubesphere
.
Interface
workspaceTemplateInformer
tenantv1alpha2informers
.
WorkspaceTemplateInformer
workspaceTemplateLister
tenantv1alpha2listers
.
WorkspaceTemplateLister
workspaceTemplateSynced
cache
.
InformerSynced
workspaceRoleInformer
iamv1alpha2informers
.
WorkspaceRoleInformer
workspaceRoleLister
iamv1alpha2listers
.
WorkspaceRoleLister
workspaceRoleSynced
cache
.
InformerSynced
roleBaseInformer
iamv1alpha2informers
.
RoleBaseInformer
roleBaseLister
iamv1alpha2listers
.
RoleBaseLister
roleBaseSynced
cache
.
InformerSynced
workspaceInformer
tenantv1alpha1informers
.
WorkspaceInformer
workspaceLister
tenantv1alpha1listers
.
WorkspaceLister
workspaceSynced
cache
.
InformerSynced
fedWorkspaceCache
cache
.
Store
fedWorkspaceCacheController
cache
.
Controller
multiClusterEnabled
bool
// 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
}
func
NewController
(
k8sClient
kubernetes
.
Interface
,
ksClient
kubesphere
.
Interface
,
workspaceTemplateInformer
tenantv1alpha2informers
.
WorkspaceTemplateInformer
,
workspaceInformer
tenantv1alpha1informers
.
WorkspaceInformer
,
roleBaseInformer
iamv1alpha2informers
.
RoleBaseInformer
,
workspaceRoleInformer
iamv1alpha2informers
.
WorkspaceRoleInformer
,
fedWorkspaceCache
cache
.
Store
,
fedWorkspaceCacheController
cache
.
Controller
,
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
})
ctl
:=
&
Controller
{
k8sClient
:
k8sClient
,
ksClient
:
ksClient
,
workspaceTemplateInformer
:
workspaceTemplateInformer
,
workspaceTemplateLister
:
workspaceTemplateInformer
.
Lister
(),
workspaceTemplateSynced
:
workspaceTemplateInformer
.
Informer
()
.
HasSynced
,
workspaceInformer
:
workspaceInformer
,
workspaceLister
:
workspaceInformer
.
Lister
(),
workspaceSynced
:
workspaceInformer
.
Informer
()
.
HasSynced
,
workspaceRoleInformer
:
workspaceRoleInformer
,
workspaceRoleLister
:
workspaceRoleInformer
.
Lister
(),
workspaceRoleSynced
:
workspaceRoleInformer
.
Informer
()
.
HasSynced
,
roleBaseInformer
:
roleBaseInformer
,
roleBaseLister
:
roleBaseInformer
.
Lister
(),
roleBaseSynced
:
roleBaseInformer
.
Informer
()
.
HasSynced
,
fedWorkspaceCache
:
fedWorkspaceCache
,
fedWorkspaceCacheController
:
fedWorkspaceCacheController
,
multiClusterEnabled
:
multiClusterEnabled
,
workqueue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"WorkspaceTemplate"
),
recorder
:
recorder
,
}
klog
.
Info
(
"Setting up event handlers"
)
workspaceTemplateInformer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
AddFunc
:
ctl
.
enqueueClusterRole
,
UpdateFunc
:
func
(
old
,
new
interface
{})
{
ctl
.
enqueueClusterRole
(
new
)
},
DeleteFunc
:
ctl
.
enqueueClusterRole
,
})
return
ctl
}
func
(
c
*
Controller
)
Run
(
threadiness
int
,
stopCh
<-
chan
struct
{})
error
{
defer
utilruntime
.
HandleCrash
()
defer
c
.
workqueue
.
ShutDown
()
// Start the informer factories to begin populating the informer caches
klog
.
Info
(
"Starting GlobalRole controller"
)
// Wait for the caches to be synced before starting workers
klog
.
Info
(
"Waiting for informer caches to sync"
)
synced
:=
make
([]
cache
.
InformerSynced
,
0
)
synced
=
append
(
synced
,
c
.
workspaceTemplateSynced
,
c
.
workspaceSynced
,
c
.
workspaceRoleSynced
,
c
.
roleBaseSynced
)
if
c
.
multiClusterEnabled
{
synced
=
append
(
synced
,
c
.
fedWorkspaceCacheController
.
HasSynced
)
}
if
ok
:=
cache
.
WaitForCacheSync
(
stopCh
,
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
)
enqueueClusterRole
(
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
{
workspaceTemplate
,
err
:=
c
.
workspaceTemplateLister
.
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
(
"workspace template '%s' in work queue no longer exists"
,
key
))
return
nil
}
klog
.
Error
(
err
)
return
err
}
if
err
=
c
.
initRoles
(
workspaceTemplate
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
if
c
.
multiClusterEnabled
{
if
err
=
c
.
multiClusterSync
(
workspaceTemplate
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
}
else
{
if
err
=
c
.
sync
(
workspaceTemplate
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
}
c
.
recorder
.
Event
(
workspaceTemplate
,
corev1
.
EventTypeNormal
,
successSynced
,
messageResourceSynced
)
return
nil
}
func
(
c
*
Controller
)
Start
(
stopCh
<-
chan
struct
{})
error
{
return
c
.
Run
(
4
,
stopCh
)
}
func
(
c
*
Controller
)
multiClusterSync
(
workspaceTemplate
*
tenantv1alpha2
.
WorkspaceTemplate
)
error
{
obj
,
exist
,
err
:=
c
.
fedWorkspaceCache
.
GetByKey
(
workspaceTemplate
.
Name
)
if
!
exist
{
return
c
.
createFederatedWorkspace
(
workspaceTemplate
)
}
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
var
fedWorkspace
tenantv1alpha2
.
FederatedWorkspace
if
err
=
runtime
.
DefaultUnstructuredConverter
.
FromUnstructured
(
obj
.
(
*
unstructured
.
Unstructured
)
.
Object
,
&
fedWorkspace
);
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
if
!
reflect
.
DeepEqual
(
fedWorkspace
.
Spec
.
Template
.
Spec
,
workspaceTemplate
.
Spec
.
WorkspaceSpec
)
||
!
reflect
.
DeepEqual
(
fedWorkspace
.
Labels
,
workspaceTemplate
.
Labels
)
||
!
reflect
.
DeepEqual
(
fedWorkspace
.
Annotations
,
workspaceTemplate
.
Annotations
)
||
!
reflect
.
DeepEqual
(
fedWorkspace
.
Spec
.
Overrides
,
workspaceTemplate
.
Spec
.
Overrides
)
{
fedWorkspace
.
Spec
.
Template
.
Spec
=
workspaceTemplate
.
Spec
.
WorkspaceSpec
fedWorkspace
.
Annotations
=
workspaceTemplate
.
Annotations
fedWorkspace
.
Labels
=
workspaceTemplate
.
Labels
fedWorkspace
.
Spec
.
Overrides
=
workspaceTemplate
.
Spec
.
Overrides
return
c
.
updateFederatedWorkspace
(
&
fedWorkspace
)
}
return
nil
}
func
(
c
*
Controller
)
createFederatedWorkspace
(
workspaceTemplate
*
tenantv1alpha2
.
WorkspaceTemplate
)
error
{
clusters
:=
make
([]
tenantv1alpha2
.
Cluster
,
0
)
for
_
,
cluster
:=
range
workspaceTemplate
.
Spec
.
Clusters
{
clusters
=
append
(
clusters
,
tenantv1alpha2
.
Cluster
{
Name
:
cluster
})
}
federatedWorkspace
:=
&
tenantv1alpha2
.
FederatedWorkspace
{
TypeMeta
:
metav1
.
TypeMeta
{
Kind
:
tenantv1alpha2
.
FedWorkspaceKind
,
APIVersion
:
tenantv1alpha2
.
FedWorkspaceResource
.
Group
+
"/"
+
tenantv1alpha2
.
FedWorkspaceResource
.
Version
,
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
workspaceTemplate
.
Name
,
},
Spec
:
tenantv1alpha2
.
FederatedWorkspaceSpec
{
Template
:
tenantv1alpha2
.
Template
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Labels
:
workspaceTemplate
.
Labels
,
Annotations
:
workspaceTemplate
.
Annotations
,
},
Spec
:
workspaceTemplate
.
Spec
.
WorkspaceSpec
,
},
Placement
:
tenantv1alpha2
.
Placement
{
Clusters
:
clusters
,
},
Overrides
:
workspaceTemplate
.
Spec
.
Overrides
,
},
}
err
:=
controllerutil
.
SetControllerReference
(
workspaceTemplate
,
federatedWorkspace
,
scheme
.
Scheme
)
if
err
!=
nil
{
return
err
}
data
,
err
:=
json
.
Marshal
(
federatedWorkspace
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Post
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s"
,
tenantv1alpha2
.
FedWorkspaceResource
.
Group
,
tenantv1alpha2
.
FedWorkspaceResource
.
Version
,
tenantv1alpha2
.
FedWorkspaceResource
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
(
c
*
Controller
)
updateFederatedWorkspace
(
fedWorkspace
*
tenantv1alpha2
.
FederatedWorkspace
)
error
{
data
,
err
:=
json
.
Marshal
(
fedWorkspace
)
if
err
!=
nil
{
return
err
}
cli
:=
c
.
k8sClient
.
(
*
kubernetes
.
Clientset
)
err
=
cli
.
RESTClient
()
.
Put
()
.
AbsPath
(
fmt
.
Sprintf
(
"/apis/%s/%s/%s/%s"
,
tenantv1alpha2
.
FedWorkspaceResource
.
Group
,
tenantv1alpha2
.
FedWorkspaceResource
.
Version
,
tenantv1alpha2
.
FedWorkspaceResource
.
Name
,
fedWorkspace
.
Name
))
.
Body
(
data
)
.
Do
()
.
Error
()
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
nil
}
return
err
}
return
nil
}
func
(
c
*
Controller
)
sync
(
workspaceTemplate
*
tenantv1alpha2
.
WorkspaceTemplate
)
error
{
workspace
,
err
:=
c
.
workspaceLister
.
Get
(
workspaceTemplate
.
Name
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
c
.
createWorkspace
(
workspaceTemplate
)
}
klog
.
Error
(
err
)
return
err
}
if
!
reflect
.
DeepEqual
(
workspace
.
Spec
,
workspaceTemplate
.
Spec
.
WorkspaceSpec
)
||
!
reflect
.
DeepEqual
(
workspace
.
Labels
,
workspaceTemplate
.
Labels
)
||
!
reflect
.
DeepEqual
(
workspace
.
Annotations
,
workspaceTemplate
.
Annotations
)
{
workspace
=
workspace
.
DeepCopy
()
workspace
.
Spec
=
workspaceTemplate
.
Spec
.
WorkspaceSpec
workspace
.
Annotations
=
workspaceTemplate
.
Annotations
workspace
.
Labels
=
workspaceTemplate
.
Labels
return
c
.
updateWorkspace
(
workspace
)
}
return
nil
}
func
(
c
*
Controller
)
createWorkspace
(
workspaceTemplate
*
tenantv1alpha2
.
WorkspaceTemplate
)
error
{
workspace
:=
&
tenantv1alpha1
.
Workspace
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
workspaceTemplate
.
Name
,
Labels
:
workspaceTemplate
.
Labels
,
Annotations
:
workspaceTemplate
.
Annotations
,
},
Spec
:
workspaceTemplate
.
Spec
.
WorkspaceSpec
,
}
err
:=
controllerutil
.
SetControllerReference
(
workspaceTemplate
,
workspace
,
scheme
.
Scheme
)
if
err
!=
nil
{
return
err
}
_
,
err
=
c
.
ksClient
.
TenantV1alpha1
()
.
Workspaces
()
.
Create
(
workspace
)
if
err
!=
nil
{
if
errors
.
IsAlreadyExists
(
err
)
{
return
nil
}
klog
.
Error
(
err
)
return
err
}
return
nil
}
func
(
c
*
Controller
)
updateWorkspace
(
workspace
*
tenantv1alpha1
.
Workspace
)
error
{
_
,
err
:=
c
.
ksClient
.
TenantV1alpha1
()
.
Workspaces
()
.
Update
(
workspace
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
return
nil
}
func
(
r
*
Controller
)
initRoles
(
workspace
*
tenantv1alpha2
.
WorkspaceTemplate
)
error
{
roleBases
,
err
:=
r
.
roleBaseLister
.
List
(
labels
.
Everything
())
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
for
_
,
roleBase
:=
range
roleBases
{
var
role
iamv1alpha2
.
WorkspaceRole
if
err
=
yaml
.
NewYAMLOrJSONDecoder
(
bytes
.
NewBuffer
(
roleBase
.
Role
.
Raw
),
1024
)
.
Decode
(
&
role
);
err
==
nil
{
old
,
err
:=
r
.
workspaceRoleLister
.
Get
(
fmt
.
Sprintf
(
"%s-%s"
,
workspace
.
Name
,
role
.
Name
))
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
role
.
Name
=
fmt
.
Sprintf
(
"%s-%s"
,
workspace
.
Name
,
role
.
Name
)
if
role
.
Labels
==
nil
{
role
.
Labels
=
make
(
map
[
string
]
string
,
0
)
}
role
.
Labels
[
tenantv1alpha1
.
WorkspaceLabel
]
=
workspace
.
Name
_
,
err
=
r
.
ksClient
.
IamV1alpha2
()
.
WorkspaceRoles
()
.
Create
(
&
role
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
continue
}
}
if
!
reflect
.
DeepEqual
(
role
.
Annotations
,
old
.
Annotations
)
||
!
reflect
.
DeepEqual
(
role
.
Rules
,
old
.
Rules
)
{
updated
:=
old
.
DeepCopy
()
updated
.
Annotations
=
role
.
Annotations
updated
.
Rules
=
role
.
Rules
_
,
err
=
r
.
ksClient
.
IamV1alpha2
()
.
WorkspaceRoles
()
.
Update
(
updated
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
err
}
}
}
}
return
nil
}
pkg/kapis/resources/v1alpha2/handler.go
浏览文件 @
4fcaa78b
...
...
@@ -48,7 +48,7 @@ func newResourceHandler(k8sClient kubernetes.Interface, factory informers.Inform
routerOperator
:
routers
.
NewRouterOperator
(
k8sClient
,
factory
.
KubernetesSharedInformerFactory
()),
gitVerifier
:
git
.
NewGitVerifier
(
factory
.
KubernetesSharedInformerFactory
()),
registryGetter
:
registries
.
NewRegistryGetter
(
factory
.
KubernetesSharedInformerFactory
()),
kubeconfigOperator
:
kubeconfig
.
New
Operator
(
k8sClient
,
nil
,
masterURL
),
kubeconfigOperator
:
kubeconfig
.
New
ReadOnlyOperator
(
factory
.
KubernetesSharedInformerFactory
()
.
Core
()
.
V1
()
.
ConfigMaps
()
,
masterURL
),
kubectlOperator
:
kubectl
.
NewOperator
(
nil
,
factory
.
KubernetesSharedInformerFactory
()
.
Apps
()
.
V1
()
.
Deployments
(),
factory
.
KubernetesSharedInformerFactory
()
.
Core
()
.
V1
()
.
Pods
(),
factory
.
KubeSphereSharedInformerFactory
()
.
Iam
()
.
V1alpha2
()
.
Users
()),
...
...
pkg/kapis/tenant/v1alpha2/handler.go
浏览文件 @
4fcaa78b
...
...
@@ -457,3 +457,26 @@ func (h *tenantHandler) PatchWorkspace(request *restful.Request, response *restf
response
.
WriteEntity
(
patched
)
}
func
(
h
*
tenantHandler
)
ListClusters
(
r
*
restful
.
Request
,
response
*
restful
.
Response
)
{
user
,
ok
:=
request
.
UserFrom
(
r
.
Request
.
Context
())
if
!
ok
{
response
.
WriteEntity
([]
interface
{}{})
return
}
result
,
err
:=
h
.
tenant
.
ListClusters
(
user
)
if
err
!=
nil
{
klog
.
Error
(
err
)
if
errors
.
IsNotFound
(
err
)
{
api
.
HandleNotFound
(
response
,
r
,
err
)
return
}
api
.
HandleInternalError
(
response
,
r
,
err
)
return
}
response
.
WriteEntity
(
result
)
}
pkg/kapis/tenant/v1alpha2/register.go
浏览文件 @
4fcaa78b
...
...
@@ -51,6 +51,11 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
ws
:=
runtime
.
NewWebService
(
GroupVersion
)
handler
:=
newTenantHandler
(
factory
,
k8sclient
,
ksclient
,
evtsClient
,
loggingClient
,
auditingclient
)
ws
.
Route
(
ws
.
GET
(
"/clusters"
)
.
To
(
handler
.
ListClusters
)
.
Doc
(
"List clusters available to users"
)
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
api
.
ListResult
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
TenantResourcesTag
}))
ws
.
Route
(
ws
.
POST
(
"/workspaces"
)
.
To
(
handler
.
CreateWorkspace
)
.
Reads
(
tenantv1alpha2
.
WorkspaceTemplate
{})
.
...
...
@@ -82,12 +87,12 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
TenantResourcesTag
}))
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}"
)
.
To
(
handler
.
DescribeWorkspace
)
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
models
.
PageableRespons
e
{})
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
tenantv1alpha2
.
WorkspaceTemplat
e
{})
.
Doc
(
"Describe workspace."
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
TenantResourcesTag
}))
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}/clusters"
)
.
To
(
handler
.
ListWorkspaceClusters
)
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
models
.
PageableResponse
{})
.
Returns
(
http
.
StatusOK
,
api
.
StatusOK
,
api
.
ListResult
{})
.
Doc
(
"List clusters authorized to the specified workspace."
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
[]
string
{
constants
.
TenantResourcesTag
}))
...
...
pkg/models/iam/am/am.go
浏览文件 @
4fcaa78b
...
...
@@ -333,9 +333,9 @@ func (am *amOperator) GetGlobalRole(globalRole string) (*iamv1alpha2.GlobalRole,
return
obj
.
(
*
iamv1alpha2
.
GlobalRole
),
nil
}
func
(
am
*
amOperator
)
CreateGlobalRoleBinding
(
username
string
,
globalR
ole
string
)
error
{
func
(
am
*
amOperator
)
CreateGlobalRoleBinding
(
username
string
,
r
ole
string
)
error
{
_
,
err
:=
am
.
GetGlobalRole
(
globalR
ole
)
_
,
err
:=
am
.
GetGlobalRole
(
r
ole
)
if
err
!=
nil
{
klog
.
Error
(
err
)
...
...
@@ -350,7 +350,7 @@ func (am *amOperator) CreateGlobalRoleBinding(username string, globalRole string
}
for
_
,
roleBinding
:=
range
roleBindings
{
if
globalR
ole
==
roleBinding
.
RoleRef
.
Name
{
if
r
ole
==
roleBinding
.
RoleRef
.
Name
{
return
nil
}
err
:=
am
.
ksclient
.
IamV1alpha2
()
.
GlobalRoleBindings
()
.
Delete
(
roleBinding
.
Name
,
metav1
.
NewDeleteOptions
(
0
))
...
...
@@ -365,7 +365,7 @@ func (am *amOperator) CreateGlobalRoleBinding(username string, globalRole string
globalRoleBinding
:=
iamv1alpha2
.
GlobalRoleBinding
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
fmt
.
Sprintf
(
"%s-%s"
,
username
,
globalR
ole
),
Name
:
fmt
.
Sprintf
(
"%s-%s"
,
username
,
r
ole
),
Labels
:
map
[
string
]
string
{
iamv1alpha2
.
UserReferenceLabel
:
username
},
},
Subjects
:
[]
rbacv1
.
Subject
{
...
...
@@ -378,7 +378,7 @@ func (am *amOperator) CreateGlobalRoleBinding(username string, globalRole string
RoleRef
:
rbacv1
.
RoleRef
{
APIGroup
:
iamv1alpha2
.
SchemeGroupVersion
.
Group
,
Kind
:
iamv1alpha2
.
ResourceKindGlobalRole
,
Name
:
globalR
ole
,
Name
:
r
ole
,
},
}
...
...
@@ -456,7 +456,7 @@ func (am *amOperator) CreateWorkspaceRoleBinding(username string, workspace stri
roleBinding
:=
iamv1alpha2
.
WorkspaceRoleBinding
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
fmt
.
Sprintf
(
"%s-%s"
,
role
,
usernam
e
),
Name
:
fmt
.
Sprintf
(
"%s-%s"
,
username
,
rol
e
),
Labels
:
map
[
string
]
string
{
iamv1alpha2
.
UserReferenceLabel
:
username
,
tenantv1alpha1
.
WorkspaceLabel
:
workspace
},
},
...
...
pkg/models/iam/im/im.go
浏览文件 @
4fcaa78b
...
...
@@ -131,10 +131,7 @@ func (im *defaultIMOperator) ListUsers(query *query.Query) (result *api.ListResu
for
_
,
item
:=
range
result
.
Items
{
user
:=
item
.
(
*
iamv1alpha2
.
User
)
out
:=
user
.
DeepCopy
()
// ensure encrypted password will not be output
out
.
Spec
.
EncryptedPassword
=
""
items
=
append
(
items
,
out
)
items
=
append
(
items
,
ensurePasswordNotOutput
(
user
))
}
result
.
Items
=
items
...
...
@@ -156,11 +153,8 @@ func (im *defaultIMOperator) DescribeUser(username string) (*iamv1alpha2.User, e
}
user
:=
obj
.
(
*
iamv1alpha2
.
User
)
out
:=
user
.
DeepCopy
()
// ensure encrypted password will not be output
out
.
Spec
.
EncryptedPassword
=
""
return
out
,
nil
return
ensurePasswordNotOutput
(
user
)
,
nil
}
func
(
im
*
defaultIMOperator
)
DeleteUser
(
username
string
)
error
{
...
...
@@ -175,3 +169,10 @@ func (im *defaultIMOperator) CreateUser(user *iamv1alpha2.User) (*iamv1alpha2.Us
}
return
user
,
nil
}
func
ensurePasswordNotOutput
(
user
*
iamv1alpha2
.
User
)
*
iamv1alpha2
.
User
{
out
:=
user
.
DeepCopy
()
// ensure encrypted password will not be output
out
.
Spec
.
EncryptedPassword
=
""
return
out
}
pkg/models/kubeconfig/kubeconfig.go
浏览文件 @
4fcaa78b
...
...
@@ -28,6 +28,7 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/authentication/user"
corev1informers
"k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
...
...
@@ -60,30 +61,38 @@ type Interface interface {
}
type
operator
struct
{
k8sclient
kubernetes
.
Interface
config
*
rest
.
Config
masterURL
string
k8sClient
kubernetes
.
Interface
configMapInformer
corev1informers
.
ConfigMapInformer
config
*
rest
.
Config
masterURL
string
}
func
NewOperator
(
k8sclient
kubernetes
.
Interface
,
config
*
rest
.
Config
,
masterURL
string
)
Interface
{
return
&
operator
{
k8sclient
:
k8sclient
,
config
:
config
,
masterURL
:
masterURL
}
func
NewOperator
(
k8sClient
kubernetes
.
Interface
,
configMapInformer
corev1informers
.
ConfigMapInformer
,
config
*
rest
.
Config
)
Interface
{
return
&
operator
{
k8sClient
:
k8sClient
,
configMapInformer
:
configMapInformer
,
config
:
config
}
}
func
NewReadOnlyOperator
(
configMapInformer
corev1informers
.
ConfigMapInformer
,
masterURL
string
)
Interface
{
return
&
operator
{
configMapInformer
:
configMapInformer
,
masterURL
:
masterURL
}
}
func
(
o
*
operator
)
CreateKubeConfig
(
user
*
iamv1alpha2
.
User
)
error
{
configName
:=
fmt
.
Sprintf
(
kubeconfigNameFormat
,
user
.
Name
)
_
,
err
:=
o
.
k8sclient
.
CoreV1
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Get
(
configName
,
metav1
.
GetOptions
{}
)
_
,
err
:=
o
.
configMapInformer
.
Lister
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Get
(
configName
)
// already exist
if
err
==
nil
{
return
nil
}
// internal error
if
!
errors
.
IsNotFound
(
err
)
{
klog
.
Error
(
err
)
return
err
}
// create if not exist
var
ca
[]
byte
if
len
(
o
.
config
.
CAData
)
>
0
{
ca
=
o
.
config
.
CAData
...
...
@@ -142,7 +151,7 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error {
return
err
}
_
,
err
=
o
.
k8s
c
lient
.
CoreV1
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Create
(
cm
)
_
,
err
=
o
.
k8s
C
lient
.
CoreV1
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Create
(
cm
)
if
err
!=
nil
{
klog
.
Errorln
(
err
)
...
...
@@ -154,7 +163,7 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error {
func
(
o
*
operator
)
GetKubeConfig
(
username
string
)
(
string
,
error
)
{
configName
:=
fmt
.
Sprintf
(
kubeconfigNameFormat
,
username
)
configMap
,
err
:=
o
.
k8sclient
.
CoreV1
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Get
(
configName
,
metav1
.
GetOptions
{}
)
configMap
,
err
:=
o
.
configMapInformer
.
Lister
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Get
(
configName
)
if
err
!=
nil
{
klog
.
Errorln
(
err
)
return
""
,
err
...
...
@@ -171,6 +180,7 @@ func (o *operator) GetKubeConfig(username string) (string, error) {
masterURL
:=
o
.
masterURL
// server host override
if
cluster
:=
kubeconfig
.
Clusters
[
defaultClusterName
];
cluster
!=
nil
{
cluster
.
Server
=
masterURL
}
...
...
@@ -244,7 +254,7 @@ func (o *operator) createCSR(username string) ([]byte, error) {
}
// create csr
k8sCSR
,
err
=
o
.
k8s
c
lient
.
CertificatesV1beta1
()
.
CertificateSigningRequests
()
.
Create
(
k8sCSR
)
k8sCSR
,
err
=
o
.
k8s
C
lient
.
CertificatesV1beta1
()
.
CertificateSigningRequests
()
.
Create
(
k8sCSR
)
if
err
!=
nil
{
klog
.
Errorln
(
err
)
...
...
@@ -256,14 +266,14 @@ func (o *operator) createCSR(username string) ([]byte, error) {
func
(
o
*
operator
)
UpdateKubeconfig
(
username
string
,
certificate
[]
byte
)
error
{
configName
:=
fmt
.
Sprintf
(
kubeconfigNameFormat
,
username
)
configMap
,
err
:=
o
.
k8s
c
lient
.
CoreV1
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Get
(
configName
,
metav1
.
GetOptions
{})
configMap
,
err
:=
o
.
k8s
C
lient
.
CoreV1
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Get
(
configName
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
klog
.
Errorln
(
err
)
return
err
}
configMap
=
appendCert
(
configMap
,
certificate
)
_
,
err
=
o
.
k8s
c
lient
.
CoreV1
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Update
(
configMap
)
_
,
err
=
o
.
k8s
C
lient
.
CoreV1
()
.
ConfigMaps
(
constants
.
KubeSphereControlNamespace
)
.
Update
(
configMap
)
if
err
!=
nil
{
klog
.
Errorln
(
err
)
return
err
...
...
pkg/models/tenant/tenant.go
浏览文件 @
4fcaa78b
...
...
@@ -73,6 +73,7 @@ type Interface interface {
UpdateNamespace
(
workspace
string
,
namespace
*
corev1
.
Namespace
)
(
*
corev1
.
Namespace
,
error
)
PatchNamespace
(
workspace
string
,
namespace
*
corev1
.
Namespace
)
(
*
corev1
.
Namespace
,
error
)
PatchWorkspace
(
workspace
*
tenantv1alpha2
.
WorkspaceTemplate
)
(
*
tenantv1alpha2
.
WorkspaceTemplate
,
error
)
ListClusters
(
info
user
.
Info
)
(
*
api
.
ListResult
,
error
)
}
type
tenantOperator
struct
{
...
...
@@ -355,6 +356,90 @@ func (t *tenantOperator) ListWorkspaceClusters(workspaceName string) (*api.ListR
}
return
&
api
.
ListResult
{
Items
:
clusters
,
TotalItems
:
len
(
clusters
)},
nil
}
func
(
t
*
tenantOperator
)
ListClusters
(
user
user
.
Info
)
(
*
api
.
ListResult
,
error
)
{
listClustersInGlobalScope
:=
authorizer
.
AttributesRecord
{
User
:
user
,
Verb
:
"list"
,
Resource
:
"clusters"
,
ResourceScope
:
request
.
GlobalScope
,
ResourceRequest
:
true
,
}
allowedListClustersInGlobalScope
,
_
,
err
:=
t
.
authorizer
.
Authorize
(
listClustersInGlobalScope
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
nil
,
err
}
listWorkspacesInGlobalScope
:=
authorizer
.
AttributesRecord
{
User
:
user
,
Verb
:
"list"
,
Resource
:
"workspaces"
,
ResourceScope
:
request
.
GlobalScope
,
ResourceRequest
:
true
,
}
allowedListWorkspacesInGlobalScope
,
_
,
err
:=
t
.
authorizer
.
Authorize
(
listWorkspacesInGlobalScope
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
nil
,
err
}
if
allowedListClustersInGlobalScope
==
authorizer
.
DecisionAllow
||
allowedListWorkspacesInGlobalScope
==
authorizer
.
DecisionAllow
{
result
,
err
:=
t
.
resourceGetter
.
List
(
clusterv1alpha1
.
ResourcesPluralCluster
,
""
,
query
.
New
())
if
err
!=
nil
{
klog
.
Error
(
err
)
return
nil
,
err
}
return
result
,
nil
}
workspaceRoleBindings
,
err
:=
t
.
am
.
ListWorkspaceRoleBindings
(
user
.
GetName
(),
""
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
nil
,
err
}
clusters
:=
map
[
string
]
*
clusterv1alpha1
.
Cluster
{}
for
_
,
roleBinding
:=
range
workspaceRoleBindings
{
workspaceName
:=
roleBinding
.
Labels
[
tenantv1alpha1
.
WorkspaceLabel
]
workspace
,
err
:=
t
.
DescribeWorkspace
(
workspaceName
)
if
err
!=
nil
{
klog
.
Error
(
err
)
return
nil
,
err
}
for
_
,
clusterName
:=
range
workspace
.
Spec
.
Clusters
{
// skip if cluster exist
if
clusters
[
clusterName
]
!=
nil
{
continue
}
obj
,
err
:=
t
.
resourceGetter
.
Get
(
clusterv1alpha1
.
ResourcesPluralCluster
,
""
,
clusterName
)
if
err
!=
nil
{
klog
.
Error
(
err
)
if
errors
.
IsNotFound
(
err
)
{
continue
}
return
nil
,
err
}
cluster
:=
obj
.
(
*
clusterv1alpha1
.
Cluster
)
clusters
[
clusterName
]
=
cluster
}
}
items
:=
make
([]
interface
{},
0
)
for
_
,
cluster
:=
range
clusters
{
items
=
append
(
items
,
cluster
)
}
return
&
api
.
ListResult
{
Items
:
items
,
TotalItems
:
len
(
items
)},
nil
}
func
(
t
*
tenantOperator
)
DeleteWorkspace
(
workspace
string
)
error
{
return
t
.
ksclient
.
TenantV1alpha2
()
.
WorkspaceTemplates
()
.
Delete
(
workspace
,
metav1
.
NewDeleteOptions
(
0
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录