Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
水淹萌龙
kubesphere
提交
5c4efd53
K
kubesphere
项目概览
水淹萌龙
/
kubesphere
与 Fork 源项目一致
Fork自
KubeSphere / kubesphere
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kubesphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
5c4efd53
编写于
4月 10, 2019
作者:
H
hongming
提交者:
zryfish
4月 11, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor tenant api
Signed-off-by:
N
hongming
<
talonwan@yunify.com
>
上级
71633730
变更
29
隐藏空白更改
内联
并排
Showing
29 changed file
with
576 addition
and
583 deletion
+576
-583
pkg/apis/iam/v1alpha2/register.go
pkg/apis/iam/v1alpha2/register.go
+2
-1
pkg/apis/resources/v1alpha2/register.go
pkg/apis/resources/v1alpha2/register.go
+17
-2
pkg/apis/tenant/v1alpha2/register.go
pkg/apis/tenant/v1alpha2/register.go
+5
-1
pkg/apis/terminal/v1alpha2/register.go
pkg/apis/terminal/v1alpha2/register.go
+1
-1
pkg/apiserver/iam/groups.go
pkg/apiserver/iam/groups.go
+1
-1
pkg/apiserver/iam/im.go
pkg/apiserver/iam/im.go
+0
-11
pkg/apiserver/iam/workspaces.go
pkg/apiserver/iam/workspaces.go
+3
-9
pkg/apiserver/resources/application.go
pkg/apiserver/resources/application.go
+42
-2
pkg/apiserver/resources/resources.go
pkg/apiserver/resources/resources.go
+1
-8
pkg/apiserver/routers/routers.go
pkg/apiserver/routers/routers.go
+6
-1
pkg/apiserver/tenant/tenant.go
pkg/apiserver/tenant/tenant.go
+37
-11
pkg/constants/constants.go
pkg/constants/constants.go
+0
-2
pkg/controller/workspace/workspace_controller.go
pkg/controller/workspace/workspace_controller.go
+4
-4
pkg/models/iam/am.go
pkg/models/iam/am.go
+9
-62
pkg/models/iam/im.go
pkg/models/iam/im.go
+117
-31
pkg/models/iam/policy/policy.go
pkg/models/iam/policy/policy.go
+14
-2
pkg/models/resources/clusterroles.go
pkg/models/resources/clusterroles.go
+14
-0
pkg/models/resources/resources.go
pkg/models/resources/resources.go
+6
-15
pkg/models/routers/routers.go
pkg/models/routers/routers.go
+2
-1
pkg/models/tenant/devops.go
pkg/models/tenant/devops.go
+18
-47
pkg/models/tenant/namespaces.go
pkg/models/tenant/namespaces.go
+9
-0
pkg/models/tenant/tenant.go
pkg/models/tenant/tenant.go
+41
-19
pkg/models/tenant/workspaces.go
pkg/models/tenant/workspaces.go
+17
-0
pkg/models/types.go
pkg/models/types.go
+1
-1
pkg/models/workspaces/workspaces.go
pkg/models/workspaces/workspaces.go
+14
-336
pkg/params/params.go
pkg/params/params.go
+0
-12
pkg/simple/client/kubesphere/devops.go
pkg/simple/client/kubesphere/devops.go
+186
-0
pkg/simple/client/kubesphere/kubesphereclient.go
pkg/simple/client/kubesphere/kubesphereclient.go
+7
-0
pkg/simple/client/openpitrix/applications.go
pkg/simple/client/openpitrix/applications.go
+2
-3
未找到文件。
pkg/apis/iam/v1alpha2/register.go
浏览文件 @
5c4efd53
...
@@ -192,9 +192,10 @@ func addWebService(c *restful.Container) error {
...
@@ -192,9 +192,10 @@ func addWebService(c *restful.Container) error {
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Doc
(
"Add user to workspace"
)
.
Doc
(
"Add user to workspace"
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
ws
.
Route
(
ws
.
POST
(
"/workspaces/{workspace}/members
"
)
.
ws
.
Route
(
ws
.
DELETE
(
"/workspaces/{workspace}/members/{username}
"
)
.
To
(
iam
.
RemoveUser
)
.
To
(
iam
.
RemoveUser
)
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Param
(
ws
.
PathParameter
(
"name"
,
"username"
))
.
Doc
(
"Remove user from workspace"
)
.
Doc
(
"Remove user from workspace"
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}/members/{username}"
)
.
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}/members/{username}"
)
.
...
...
pkg/apis/resources/v1alpha2/register.go
浏览文件 @
5c4efd53
...
@@ -91,7 +91,7 @@ func addWebService(c *restful.Container) error {
...
@@ -91,7 +91,7 @@ func addWebService(c *restful.Container) error {
To
(
resources
.
ApplicationHandler
)
.
To
(
resources
.
ApplicationHandler
)
.
Writes
(
models
.
PageableResponse
{})
.
Writes
(
models
.
PageableResponse
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
)
.
Doc
(
"
Cluster level resource query
"
)
.
Doc
(
"
List applications in cluster
"
)
.
Param
(
webservice
.
QueryParameter
(
params
.
ConditionsParam
,
"query conditions"
)
.
Param
(
webservice
.
QueryParameter
(
params
.
ConditionsParam
,
"query conditions"
)
.
Required
(
false
)
.
Required
(
false
)
.
DataFormat
(
"key=value,key~value"
)
.
DataFormat
(
"key=value,key~value"
)
.
...
@@ -103,9 +103,24 @@ func addWebService(c *restful.Container) error {
...
@@ -103,9 +103,24 @@ func addWebService(c *restful.Container) error {
DataFormat
(
"limit=%d,page=%d"
)
.
DataFormat
(
"limit=%d,page=%d"
)
.
DefaultValue
(
"limit=10,page=1"
)))
DefaultValue
(
"limit=10,page=1"
)))
webservice
.
Route
(
webservice
.
GET
(
"/namespaces/{namespace}/applications"
)
.
To
(
resources
.
NamespacedApplicationHandler
)
.
Writes
(
models
.
PageableResponse
{})
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
)
.
Doc
(
"List applications"
)
.
Param
(
webservice
.
QueryParameter
(
params
.
ConditionsParam
,
"query conditions"
)
.
Required
(
false
)
.
DataFormat
(
"key=value,key~value"
)
.
DefaultValue
(
""
))
.
Param
(
webservice
.
PathParameter
(
"namespace"
,
"namespace"
))
.
Param
(
webservice
.
QueryParameter
(
params
.
PagingParam
,
"page"
)
.
Required
(
false
)
.
DataFormat
(
"limit=%d,page=%d"
)
.
DefaultValue
(
"limit=10,page=1"
)))
webservice
.
Route
(
webservice
.
GET
(
"/storageclasses/{storageclass}/persistentvolumeclaims"
)
.
webservice
.
Route
(
webservice
.
GET
(
"/storageclasses/{storageclass}/persistentvolumeclaims"
)
.
To
(
resources
.
GetPvcListBySc
)
.
To
(
resources
.
GetPvcListBySc
)
.
Doc
(
"
get user's kubectl pod
"
)
.
Doc
(
"
query persistent volume claims by storageclass
"
)
.
Param
(
webservice
.
PathParameter
(
"username"
,
"username"
))
.
Param
(
webservice
.
PathParameter
(
"username"
,
"username"
))
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
...
...
pkg/apis/tenant/v1alpha2/register.go
浏览文件 @
5c4efd53
...
@@ -42,6 +42,10 @@ func addWebService(c *restful.Container) error {
...
@@ -42,6 +42,10 @@ func addWebService(c *restful.Container) error {
To
(
tenant
.
ListWorkspaces
)
.
To
(
tenant
.
ListWorkspaces
)
.
Doc
(
"List workspace by user"
)
.
Doc
(
"List workspace by user"
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}"
)
.
To
(
tenant
.
DescribeWorkspace
)
.
Doc
(
"Get workspace detail"
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}/rules"
)
.
ws
.
Route
(
ws
.
GET
(
"/workspaces/{workspace}/rules"
)
.
To
(
tenant
.
ListWorkspaceRules
)
.
To
(
tenant
.
ListWorkspaceRules
)
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
...
@@ -96,7 +100,7 @@ func addWebService(c *restful.Container) error {
...
@@ -96,7 +100,7 @@ func addWebService(c *restful.Container) error {
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Doc
(
"Create devops project"
)
.
Doc
(
"Create devops project"
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
))
ws
.
Route
(
ws
.
DELETE
(
"/workspaces/{workspace}/devops"
)
.
ws
.
Route
(
ws
.
DELETE
(
"/workspaces/{workspace}/devops
/{id}
"
)
.
To
(
tenant
.
DeleteDevopsProject
)
.
To
(
tenant
.
DeleteDevopsProject
)
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Param
(
ws
.
PathParameter
(
"workspace"
,
"workspace name"
))
.
Doc
(
"Delete devops project"
)
.
Doc
(
"Delete devops project"
)
.
...
...
pkg/apis/terminal/v1alpha2/register.go
浏览文件 @
5c4efd53
...
@@ -41,7 +41,7 @@ func addWebService(c *restful.Container) error {
...
@@ -41,7 +41,7 @@ func addWebService(c *restful.Container) error {
tags
:=
[]
string
{
"Terminal"
}
tags
:=
[]
string
{
"Terminal"
}
webservice
.
Route
(
webservice
.
GET
(
"/namespace/{namespace}/pods/{pods}"
)
.
webservice
.
Route
(
webservice
.
GET
(
"/namespace
s
/{namespace}/pods/{pods}"
)
.
To
(
terminal
.
CreateTerminalSession
)
.
To
(
terminal
.
CreateTerminalSession
)
.
Doc
(
"create terminal session"
)
.
Doc
(
"create terminal session"
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
)
.
Metadata
(
restfulspec
.
KeyOpenAPITags
,
tags
)
.
...
...
pkg/apiserver/iam/groups.go
浏览文件 @
5c4efd53
...
@@ -142,7 +142,7 @@ func ListGroupUsers(req *restful.Request, resp *restful.Response) {
...
@@ -142,7 +142,7 @@ func ListGroupUsers(req *restful.Request, resp *restful.Response) {
for
i
:=
0
;
i
<
len
(
group
.
Members
);
i
++
{
for
i
:=
0
;
i
<
len
(
group
.
Members
);
i
++
{
name
:=
group
.
Members
[
i
]
name
:=
group
.
Members
[
i
]
user
,
err
:=
iam
.
DescribeUser
(
name
)
user
,
err
:=
iam
.
GetUserInfo
(
name
)
if
err
!=
nil
{
if
err
!=
nil
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
...
...
pkg/apiserver/iam/im.go
浏览文件 @
5c4efd53
...
@@ -234,22 +234,11 @@ func ListUsers(req *restful.Request, resp *restful.Response) {
...
@@ -234,22 +234,11 @@ func ListUsers(req *restful.Request, resp *restful.Response) {
conditions
,
err
:=
params
.
ParseConditions
(
req
.
QueryParameter
(
params
.
ConditionsParam
))
conditions
,
err
:=
params
.
ParseConditions
(
req
.
QueryParameter
(
params
.
ConditionsParam
))
orderBy
:=
req
.
QueryParameter
(
params
.
OrderByParam
)
orderBy
:=
req
.
QueryParameter
(
params
.
OrderByParam
)
reverse
:=
params
.
ParseReverse
(
req
)
reverse
:=
params
.
ParseReverse
(
req
)
names
:=
params
.
ParseArray
(
req
.
QueryParameter
(
params
.
NameParam
))
if
err
!=
nil
{
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusBadRequest
,
errors
.
Wrap
(
err
))
resp
.
WriteHeaderAndEntity
(
http
.
StatusBadRequest
,
errors
.
Wrap
(
err
))
return
return
}
}
if
len
(
names
)
>
0
{
users
,
err
:=
iam
.
ListUsersByName
(
names
)
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusBadRequest
,
errors
.
Wrap
(
err
))
return
}
resp
.
WriteAsJson
(
users
)
return
}
users
,
err
:=
iam
.
ListUsers
(
conditions
,
orderBy
,
reverse
,
limit
,
offset
)
users
,
err
:=
iam
.
ListUsers
(
conditions
,
orderBy
,
reverse
,
limit
,
offset
)
...
...
pkg/apiserver/iam/workspaces.go
浏览文件 @
5c4efd53
...
@@ -91,7 +91,7 @@ func DescribeWorkspaceUser(req *restful.Request, resp *restful.Response) {
...
@@ -91,7 +91,7 @@ func DescribeWorkspaceUser(req *restful.Request, resp *restful.Response) {
return
return
}
}
user
,
err
:=
iam
.
DescribeUser
(
username
)
user
,
err
:=
iam
.
GetUserInfo
(
username
)
if
err
!=
nil
{
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
...
@@ -132,15 +132,9 @@ func InviteUser(req *restful.Request, resp *restful.Response) {
...
@@ -132,15 +132,9 @@ func InviteUser(req *restful.Request, resp *restful.Response) {
func
RemoveUser
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
func
RemoveUser
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
workspace
:=
req
.
PathParameter
(
"workspace"
)
workspace
:=
req
.
PathParameter
(
"workspace"
)
var
user
models
.
User
username
:=
req
.
PathParameter
(
"username"
)
err
:=
req
.
ReadEntity
(
&
user
)
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusBadRequest
,
errors
.
Wrap
(
err
))
return
}
err
=
workspaces
.
InviteUser
(
workspace
,
&
user
)
err
:=
workspaces
.
RemoveUser
(
workspace
,
username
)
if
err
!=
nil
{
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
return
return
...
...
pkg/apiserver/resources/application.go
浏览文件 @
5c4efd53
...
@@ -19,10 +19,11 @@ package resources
...
@@ -19,10 +19,11 @@ package resources
import
(
import
(
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful"
"k8s.io/api/core/v1"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models/applications"
"kubesphere.io/kubesphere/pkg/models/applications"
"kubesphere.io/kubesphere/pkg/models/resources"
//"kubesphere.io/kubesphere/pkg/models/applications"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/params"
"net/http"
"net/http"
)
)
...
@@ -58,3 +59,42 @@ func ApplicationHandler(req *restful.Request, resp *restful.Response) {
...
@@ -58,3 +59,42 @@ func ApplicationHandler(req *restful.Request, resp *restful.Response) {
resp
.
WriteAsJson
(
result
)
resp
.
WriteAsJson
(
result
)
}
}
func
NamespacedApplicationHandler
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
limit
,
offset
:=
params
.
ParsePaging
(
req
.
QueryParameter
(
params
.
PagingParam
))
namespaceName
:=
req
.
PathParameter
(
"namespace"
)
conditions
,
err
:=
params
.
ParseConditions
(
req
.
QueryParameter
(
params
.
ConditionsParam
))
if
err
!=
nil
{
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusBadRequest
,
errors
.
Wrap
(
err
))
return
}
}
namespace
,
err
:=
resources
.
GetResource
(
""
,
resources
.
Namespaces
,
namespaceName
)
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
return
}
var
runtimeId
string
if
ns
,
ok
:=
namespace
.
(
*
v1
.
Namespace
);
ok
{
runtimeId
=
ns
.
Annotations
[
constants
.
OpenPitrixRuntimeAnnotationKey
]
}
if
runtimeId
==
""
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
New
(
"openpitrix runtime not init"
))
return
}
result
,
err
:=
applications
.
ListApplication
(
runtimeId
,
conditions
,
limit
,
offset
)
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
return
}
resp
.
WriteAsJson
(
result
)
}
pkg/apiserver/resources/resources.go
浏览文件 @
5c4efd53
...
@@ -19,7 +19,6 @@ package resources
...
@@ -19,7 +19,6 @@ package resources
import
(
import
(
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/models/resources"
"net/http"
"net/http"
...
@@ -34,7 +33,6 @@ func ListResources(req *restful.Request, resp *restful.Response) {
...
@@ -34,7 +33,6 @@ func ListResources(req *restful.Request, resp *restful.Response) {
orderBy
:=
req
.
QueryParameter
(
params
.
OrderByParam
)
orderBy
:=
req
.
QueryParameter
(
params
.
OrderByParam
)
limit
,
offset
:=
params
.
ParsePaging
(
req
.
QueryParameter
(
params
.
PagingParam
))
limit
,
offset
:=
params
.
ParsePaging
(
req
.
QueryParameter
(
params
.
PagingParam
))
reverse
:=
params
.
ParseReverse
(
req
)
reverse
:=
params
.
ParseReverse
(
req
)
names
:=
params
.
ParseArray
(
req
.
QueryParameter
(
params
.
NameParam
))
if
orderBy
==
""
{
if
orderBy
==
""
{
orderBy
=
resources
.
CreateTime
orderBy
=
resources
.
CreateTime
...
@@ -46,12 +44,7 @@ func ListResources(req *restful.Request, resp *restful.Response) {
...
@@ -46,12 +44,7 @@ func ListResources(req *restful.Request, resp *restful.Response) {
return
return
}
}
var
result
*
models
.
PageableResponse
result
,
err
:=
resources
.
ListResources
(
namespace
,
resourceName
,
conditions
,
orderBy
,
reverse
,
limit
,
offset
)
if
len
(
names
)
>
0
{
result
,
err
=
resources
.
ListResourcesByName
(
namespace
,
resourceName
,
names
)
}
else
{
result
,
err
=
resources
.
ListResources
(
namespace
,
resourceName
,
conditions
,
orderBy
,
reverse
,
limit
,
offset
)
}
if
err
!=
nil
{
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
...
...
pkg/apiserver/routers/routers.go
浏览文件 @
5c4efd53
...
@@ -21,6 +21,7 @@ package routers
...
@@ -21,6 +21,7 @@ package routers
import
(
import
(
"fmt"
"fmt"
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful"
k8serr
"k8s.io/apimachinery/pkg/api/errors"
"net/http"
"net/http"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/errors"
...
@@ -57,7 +58,11 @@ func GetRouter(request *restful.Request, response *restful.Response) {
...
@@ -57,7 +58,11 @@ func GetRouter(request *restful.Request, response *restful.Response) {
router
,
err
:=
routers
.
GetRouter
(
namespace
)
router
,
err
:=
routers
.
GetRouter
(
namespace
)
if
err
!=
nil
{
if
err
!=
nil
{
response
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
if
k8serr
.
IsNotFound
(
err
)
{
response
.
WriteHeaderAndEntity
(
http
.
StatusNotFound
,
errors
.
Wrap
(
err
))
}
else
{
response
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
}
return
return
}
}
...
...
pkg/apiserver/tenant/tenant.go
浏览文件 @
5c4efd53
...
@@ -19,6 +19,7 @@ package tenant
...
@@ -19,6 +19,7 @@ package tenant
import
(
import
(
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful"
"github.com/golang/glog"
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
k8serr
"k8s.io/apimachinery/pkg/api/errors"
k8serr
"k8s.io/apimachinery/pkg/api/errors"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
...
@@ -26,10 +27,11 @@ import (
...
@@ -26,10 +27,11 @@ import (
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/models/tenant"
"kubesphere.io/kubesphere/pkg/models/tenant"
"kubesphere.io/kubesphere/pkg/models/workspaces"
"kubesphere.io/kubesphere/pkg/models/workspaces"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/params"
"
log
"
"
kubesphere.io/kubesphere/pkg/simple/client/kubesphere
"
"net/http"
"net/http"
)
)
...
@@ -54,6 +56,11 @@ func ListWorkspaces(req *restful.Request, resp *restful.Response) {
...
@@ -54,6 +56,11 @@ func ListWorkspaces(req *restful.Request, resp *restful.Response) {
limit
,
offset
:=
params
.
ParsePaging
(
req
.
QueryParameter
(
params
.
PagingParam
))
limit
,
offset
:=
params
.
ParsePaging
(
req
.
QueryParameter
(
params
.
PagingParam
))
reverse
:=
params
.
ParseReverse
(
req
)
reverse
:=
params
.
ParseReverse
(
req
)
if
orderBy
==
""
{
orderBy
=
resources
.
CreateTime
reverse
=
true
}
if
err
!=
nil
{
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusBadRequest
,
errors
.
Wrap
(
err
))
resp
.
WriteHeaderAndEntity
(
http
.
StatusBadRequest
,
errors
.
Wrap
(
err
))
return
return
...
@@ -69,6 +76,20 @@ func ListWorkspaces(req *restful.Request, resp *restful.Response) {
...
@@ -69,6 +76,20 @@ func ListWorkspaces(req *restful.Request, resp *restful.Response) {
resp
.
WriteAsJson
(
result
)
resp
.
WriteAsJson
(
result
)
}
}
func
DescribeWorkspace
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
username
:=
req
.
HeaderParameter
(
constants
.
UserNameHeader
)
workspaceName
:=
req
.
PathParameter
(
"workspace"
)
result
,
err
:=
tenant
.
DescribeWorkspace
(
username
,
workspaceName
)
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
return
}
resp
.
WriteAsJson
(
result
)
}
func
ListNamespaces
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
func
ListNamespaces
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
workspace
:=
req
.
PathParameter
(
"workspace"
)
workspace
:=
req
.
PathParameter
(
"workspace"
)
username
:=
req
.
PathParameter
(
"username"
)
username
:=
req
.
PathParameter
(
"username"
)
...
@@ -88,7 +109,7 @@ func ListNamespaces(req *restful.Request, resp *restful.Response) {
...
@@ -88,7 +109,7 @@ func ListNamespaces(req *restful.Request, resp *restful.Response) {
return
return
}
}
conditions
.
Match
[
"kubesphere.io/workspace"
]
=
workspace
conditions
.
Match
[
constants
.
WorkspaceLabelKey
]
=
workspace
result
,
err
:=
tenant
.
ListNamespaces
(
username
,
conditions
,
orderBy
,
reverse
,
limit
,
offset
)
result
,
err
:=
tenant
.
ListNamespaces
(
username
,
conditions
,
orderBy
,
reverse
,
limit
,
offset
)
...
@@ -188,18 +209,24 @@ func ListDevopsProjects(req *restful.Request, resp *restful.Response) {
...
@@ -188,18 +209,24 @@ func ListDevopsProjects(req *restful.Request, resp *restful.Response) {
func
DeleteDevopsProject
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
func
DeleteDevopsProject
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
devops
:=
req
.
PathParameter
(
"id"
)
devops
:=
req
.
PathParameter
(
"id"
)
workspace
:=
req
.
PathParameter
(
"workspace"
)
workspaceName
:=
req
.
PathParameter
(
"workspace"
)
force
:=
req
.
QueryParameter
(
"force"
)
username
:=
req
.
HeaderParameter
(
constants
.
UserNameHeader
)
username
:=
req
.
HeaderParameter
(
constants
.
UserNameHeader
)
err
:=
workspaces
.
UnBindDevopsProject
(
workspace
,
devops
)
_
,
err
:=
tenant
.
GetWorkspace
(
workspaceName
)
if
err
!=
nil
&&
force
!=
"true"
{
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusBadRequest
,
errors
.
Wrap
(
err
))
return
}
err
=
kubesphere
.
Client
()
.
DeleteDevopsProject
(
username
,
devops
)
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
return
return
}
}
err
=
workspaces
.
DeleteDevopsProject
(
usern
ame
,
devops
)
err
=
workspaces
.
UnBindDevopsProject
(
workspaceN
ame
,
devops
)
if
err
!=
nil
{
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
...
@@ -211,7 +238,7 @@ func DeleteDevopsProject(req *restful.Request, resp *restful.Response) {
...
@@ -211,7 +238,7 @@ func DeleteDevopsProject(req *restful.Request, resp *restful.Response) {
func
CreateDevopsProject
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
func
CreateDevopsProject
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
workspace
:=
req
.
PathParameter
(
"workspace"
)
workspace
Name
:=
req
.
PathParameter
(
"workspace"
)
username
:=
req
.
HeaderParameter
(
constants
.
UserNameHeader
)
username
:=
req
.
HeaderParameter
(
constants
.
UserNameHeader
)
var
devops
models
.
DevopsProject
var
devops
models
.
DevopsProject
...
@@ -223,8 +250,8 @@ func CreateDevopsProject(req *restful.Request, resp *restful.Response) {
...
@@ -223,8 +250,8 @@ func CreateDevopsProject(req *restful.Request, resp *restful.Response) {
return
return
}
}
log
.
Println
(
"create workspace"
,
username
,
workspac
e
,
devops
)
glog
.
Infoln
(
"create workspace"
,
username
,
workspaceNam
e
,
devops
)
project
,
err
:=
workspaces
.
CreateDevopsProject
(
username
,
workspace
,
devops
)
project
,
err
:=
workspaces
.
CreateDevopsProject
(
username
,
workspace
Name
,
&
devops
)
if
err
!=
nil
{
if
err
!=
nil
{
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
resp
.
WriteHeaderAndEntity
(
http
.
StatusInternalServerError
,
errors
.
Wrap
(
err
))
...
@@ -232,7 +259,6 @@ func CreateDevopsProject(req *restful.Request, resp *restful.Response) {
...
@@ -232,7 +259,6 @@ func CreateDevopsProject(req *restful.Request, resp *restful.Response) {
}
}
resp
.
WriteAsJson
(
project
)
resp
.
WriteAsJson
(
project
)
}
}
func
ListNamespaceRules
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
func
ListNamespaceRules
(
req
*
restful
.
Request
,
resp
*
restful
.
Response
)
{
...
...
pkg/constants/constants.go
浏览文件 @
5c4efd53
...
@@ -47,7 +47,5 @@ const (
...
@@ -47,7 +47,5 @@ const (
var
(
var
(
WorkSpaceRoles
=
[]
string
{
WorkspaceAdmin
,
WorkspaceRegular
,
WorkspaceViewer
}
WorkSpaceRoles
=
[]
string
{
WorkspaceAdmin
,
WorkspaceRegular
,
WorkspaceViewer
}
SystemWorkspace
=
"system-workspace"
DevopsAPIServer
=
"ks-devops.kubesphere-devops-system.svc"
SystemNamespaces
=
[]
string
{
KubeSphereNamespace
,
OpenPitrixNamespace
,
KubeSystemNamespace
}
SystemNamespaces
=
[]
string
{
KubeSphereNamespace
,
OpenPitrixNamespace
,
KubeSystemNamespace
}
)
)
pkg/controller/workspace/workspace_controller.go
浏览文件 @
5c4efd53
...
@@ -153,9 +153,9 @@ func (r *ReconcileWorkspace) Reconcile(request reconcile.Request) (reconcile.Res
...
@@ -153,9 +153,9 @@ func (r *ReconcileWorkspace) Reconcile(request reconcile.Request) (reconcile.Res
return
reconcile
.
Result
{},
err
return
reconcile
.
Result
{},
err
}
}
if
err
=
r
.
createGroup
(
instance
);
err
!=
nil
{
//
if err = r.createGroup(instance); err != nil {
return
reconcile
.
Result
{},
err
//
return reconcile.Result{}, err
}
//
}
if
err
=
r
.
createWorkspaceRoleBindings
(
instance
);
err
!=
nil
{
if
err
=
r
.
createWorkspaceRoleBindings
(
instance
);
err
!=
nil
{
return
reconcile
.
Result
{},
err
return
reconcile
.
Result
{},
err
...
@@ -369,7 +369,7 @@ func (r *ReconcileWorkspace) createWorkspaceRoleBindings(instance *tenantv1alpha
...
@@ -369,7 +369,7 @@ func (r *ReconcileWorkspace) createWorkspaceRoleBindings(instance *tenantv1alpha
regularRoleBinding
:=
&
rbac
.
ClusterRoleBinding
{}
regularRoleBinding
:=
&
rbac
.
ClusterRoleBinding
{}
regularRoleBinding
.
Name
=
getWorkspaceRegularRoleBindingName
(
instance
.
Name
)
regularRoleBinding
.
Name
=
getWorkspaceRegularRoleBindingName
(
instance
.
Name
)
regularRoleBinding
.
Labels
=
map
[
string
]
string
{
constants
.
WorkspaceLabelKey
:
instance
.
Name
}
regularRoleBinding
.
Labels
=
map
[
string
]
string
{
constants
.
WorkspaceLabelKey
:
instance
.
Name
}
regularRoleBinding
.
RoleRef
=
rbac
.
RoleRef
{
APIGroup
:
"rbac.authorization.k8s.io"
,
Kind
:
"ClusterRole"
,
Name
:
getWorkspace
Viewe
rRoleName
(
instance
.
Name
)}
regularRoleBinding
.
RoleRef
=
rbac
.
RoleRef
{
APIGroup
:
"rbac.authorization.k8s.io"
,
Kind
:
"ClusterRole"
,
Name
:
getWorkspace
Regula
rRoleName
(
instance
.
Name
)}
regularRoleBinding
.
Subjects
=
[]
rbac
.
Subject
{}
regularRoleBinding
.
Subjects
=
[]
rbac
.
Subject
{}
if
err
=
controllerutil
.
SetControllerReference
(
instance
,
regularRoleBinding
,
r
.
scheme
);
err
!=
nil
{
if
err
=
controllerutil
.
SetControllerReference
(
instance
,
regularRoleBinding
,
r
.
scheme
);
err
!=
nil
{
...
...
pkg/models/iam/am.go
浏览文件 @
5c4efd53
...
@@ -18,20 +18,17 @@
...
@@ -18,20 +18,17 @@
package
iam
package
iam
import
(
import
(
"encoding/json"
"errors"
"fmt"
"fmt"
"github.com/golang/glog"
"github.com/golang/glog"
"io/ioutil"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"net/http"
"sort"
"sort"
"strings"
"strings"
...
@@ -47,7 +44,7 @@ import (
...
@@ -47,7 +44,7 @@ import (
const
ClusterRoleKind
=
"ClusterRole"
const
ClusterRoleKind
=
"ClusterRole"
func
GetUserDevopsSimpleRules
(
username
,
projectId
string
)
([]
models
.
SimpleRule
,
error
)
{
func
GetUserDevopsSimpleRules
(
username
,
projectId
string
)
([]
models
.
SimpleRule
,
error
)
{
role
,
err
:=
GetUserDevopsRole
(
projectId
,
username
)
role
,
err
:=
kubesphere
.
Client
()
.
GetUserDevopsRole
(
username
,
projectId
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -100,53 +97,6 @@ func GetDevopsRoleSimpleRules(role string) []models.SimpleRule {
...
@@ -100,53 +97,6 @@ func GetDevopsRoleSimpleRules(role string) []models.SimpleRule {
return
rules
return
rules
}
}
func
GetUserDevopsRole
(
projectId
string
,
username
string
)
(
string
,
error
)
{
//Hard fix
if
username
==
"admin"
{
return
"owner"
,
nil
}
req
,
err
:=
http
.
NewRequest
(
http
.
MethodGet
,
fmt
.
Sprintf
(
"http://%s/api/v1alpha/projects/%s/members"
,
constants
.
DevopsAPIServer
,
projectId
),
nil
)
if
err
!=
nil
{
return
""
,
err
}
req
.
Header
.
Set
(
constants
.
UserNameHeader
,
username
)
resp
,
err
:=
http
.
DefaultClient
.
Do
(
req
)
if
err
!=
nil
{
return
""
,
err
}
defer
resp
.
Body
.
Close
()
data
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
""
,
err
}
if
resp
.
StatusCode
>
200
{
return
""
,
errors
.
New
(
string
(
data
))
}
var
result
[]
map
[
string
]
string
err
=
json
.
Unmarshal
(
data
,
&
result
)
if
err
!=
nil
{
return
""
,
err
}
for
_
,
item
:=
range
result
{
if
item
[
"username"
]
==
username
{
return
item
[
"role"
],
nil
}
}
return
""
,
nil
}
// Get user roles in namespace
// Get user roles in namespace
func
GetUserRoles
(
namespace
,
username
string
)
([]
*
v1
.
Role
,
error
)
{
func
GetUserRoles
(
namespace
,
username
string
)
([]
*
v1
.
Role
,
error
)
{
clusterRoleLister
:=
informers
.
SharedInformerFactory
()
.
Rbac
()
.
V1
()
.
ClusterRoles
()
.
Lister
()
clusterRoleLister
:=
informers
.
SharedInformerFactory
()
.
Rbac
()
.
V1
()
.
ClusterRoles
()
.
Lister
()
...
@@ -267,13 +217,6 @@ func GetUserRules(namespace, username string) ([]v1.PolicyRule, error) {
...
@@ -267,13 +217,6 @@ func GetUserRules(namespace, username string) ([]v1.PolicyRule, error) {
return
rules
,
nil
return
rules
,
nil
}
}
func
isUserFacingClusterRole
(
role
*
v1
.
ClusterRole
)
bool
{
if
role
.
Labels
[
constants
.
CreatorLabelKey
]
!=
""
{
return
true
}
return
false
}
func
GetWorkspaceRoleBindings
(
workspace
string
)
([]
*
v1
.
ClusterRoleBinding
,
error
)
{
func
GetWorkspaceRoleBindings
(
workspace
string
)
([]
*
v1
.
ClusterRoleBinding
,
error
)
{
clusterRoleBindings
,
err
:=
informers
.
SharedInformerFactory
()
.
Rbac
()
.
V1
()
.
ClusterRoleBindings
()
.
Lister
()
.
List
(
labels
.
Everything
())
clusterRoleBindings
,
err
:=
informers
.
SharedInformerFactory
()
.
Rbac
()
.
V1
()
.
ClusterRoleBindings
()
.
Lister
()
.
List
(
labels
.
Everything
())
...
@@ -386,7 +329,7 @@ func ListClusterRoleUsers(clusterRoleName string, conditions *params.Conditions,
...
@@ -386,7 +329,7 @@ func ListClusterRoleUsers(clusterRoleName string, conditions *params.Conditions,
for
_
,
roleBinding
:=
range
roleBindings
{
for
_
,
roleBinding
:=
range
roleBindings
{
for
_
,
subject
:=
range
roleBinding
.
Subjects
{
for
_
,
subject
:=
range
roleBinding
.
Subjects
{
if
subject
.
Kind
==
v1
.
UserKind
&&
!
k8sutil
.
ContainsUser
(
users
,
subject
.
Name
)
{
if
subject
.
Kind
==
v1
.
UserKind
&&
!
k8sutil
.
ContainsUser
(
users
,
subject
.
Name
)
{
user
,
err
:=
DescribeUser
(
subject
.
Name
)
user
,
err
:=
GetUserInfo
(
subject
.
Name
)
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
continue
continue
}
}
...
@@ -436,7 +379,7 @@ func RoleUsers(namespace string, roleName string) ([]*models.User, error) {
...
@@ -436,7 +379,7 @@ func RoleUsers(namespace string, roleName string) ([]*models.User, error) {
for
_
,
roleBinding
:=
range
roleBindings
{
for
_
,
roleBinding
:=
range
roleBindings
{
for
_
,
subject
:=
range
roleBinding
.
Subjects
{
for
_
,
subject
:=
range
roleBinding
.
Subjects
{
if
subject
.
Kind
==
v1
.
UserKind
&&
!
k8sutil
.
ContainsUser
(
users
,
subject
.
Name
)
{
if
subject
.
Kind
==
v1
.
UserKind
&&
!
k8sutil
.
ContainsUser
(
users
,
subject
.
Name
)
{
user
,
err
:=
DescribeUser
(
subject
.
Name
)
user
,
err
:=
GetUserInfo
(
subject
.
Name
)
if
err
!=
nil
{
if
err
!=
nil
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
...
@@ -491,10 +434,14 @@ func NamespaceUsers(namespaceName string) ([]*models.User, error) {
...
@@ -491,10 +434,14 @@ func NamespaceUsers(namespaceName string) ([]*models.User, error) {
users
:=
make
([]
*
models
.
User
,
0
)
users
:=
make
([]
*
models
.
User
,
0
)
for
_
,
roleBinding
:=
range
roleBindings
{
for
_
,
roleBinding
:=
range
roleBindings
{
// controlled by ks-controller-manager
if
roleBinding
.
Name
==
"admin"
||
roleBinding
.
Name
==
"viewer"
{
continue
}
for
_
,
subject
:=
range
roleBinding
.
Subjects
{
for
_
,
subject
:=
range
roleBinding
.
Subjects
{
if
subject
.
Kind
==
v1
.
UserKind
&&
!
k8sutil
.
ContainsUser
(
users
,
subject
.
Name
)
{
if
subject
.
Kind
==
v1
.
UserKind
&&
!
k8sutil
.
ContainsUser
(
users
,
subject
.
Name
)
{
user
,
err
:=
DescribeUser
(
subject
.
Name
)
user
,
err
:=
GetUserInfo
(
subject
.
Name
)
if
err
!=
nil
{
if
err
!=
nil
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
...
...
pkg/models/iam/im.go
浏览文件 @
5c4efd53
...
@@ -26,6 +26,7 @@ import (
...
@@ -26,6 +26,7 @@ import (
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/redis"
"kubesphere.io/kubesphere/pkg/simple/client/redis"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"regexp"
"regexp"
"sort"
"sort"
"strconv"
"strconv"
...
@@ -232,7 +233,7 @@ func ListUsersByName(names []string) (*models.PageableResponse, error) {
...
@@ -232,7 +233,7 @@ func ListUsersByName(names []string) (*models.PageableResponse, error) {
for
_
,
name
:=
range
names
{
for
_
,
name
:=
range
names
{
if
!
k8sutil
.
ContainsUser
(
users
,
name
)
{
if
!
k8sutil
.
ContainsUser
(
users
,
name
)
{
user
,
err
:=
DescribeUser
(
name
)
user
,
err
:=
GetUserInfo
(
name
)
if
err
!=
nil
{
if
err
!=
nil
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
continue
continue
...
@@ -252,6 +253,30 @@ func ListUsersByName(names []string) (*models.PageableResponse, error) {
...
@@ -252,6 +253,30 @@ func ListUsersByName(names []string) (*models.PageableResponse, error) {
return
&
models
.
PageableResponse
{
Items
:
items
,
TotalCount
:
len
(
items
)},
nil
return
&
models
.
PageableResponse
{
Items
:
items
,
TotalCount
:
len
(
items
)},
nil
}
}
func
ListUserByEmail
(
email
[]
string
)
(
*
models
.
PageableResponse
,
error
)
{
users
:=
make
([]
*
models
.
User
,
0
)
for
_
,
mail
:=
range
email
{
user
,
err
:=
GetUserInfoByEmail
(
mail
)
if
err
!=
nil
{
if
ldap
.
IsErrorWithCode
(
err
,
ldap
.
LDAPResultNoSuchObject
)
{
continue
}
return
nil
,
err
}
if
!
k8sutil
.
ContainsUser
(
users
,
user
.
Username
)
{
users
=
append
(
users
,
user
)
}
}
items
:=
make
([]
interface
{},
0
)
for
_
,
u
:=
range
users
{
items
=
append
(
items
,
u
)
}
return
&
models
.
PageableResponse
{
Items
:
items
,
TotalCount
:
len
(
items
)},
nil
}
func
ListUsers
(
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
,
limit
,
offset
int
)
(
*
models
.
PageableResponse
,
error
)
{
func
ListUsers
(
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
,
limit
,
offset
int
)
(
*
models
.
PageableResponse
,
error
)
{
conn
,
err
:=
ldapclient
.
Client
()
conn
,
err
:=
ldapclient
.
Client
()
...
@@ -272,6 +297,22 @@ func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limi
...
@@ -272,6 +297,22 @@ func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limi
filter
=
fmt
.
Sprintf
(
"(&(objectClass=inetOrgPerson)(|(uid=*%s*)(mail=*%s*)(description=*%s*)))"
,
keyword
,
keyword
,
keyword
)
filter
=
fmt
.
Sprintf
(
"(&(objectClass=inetOrgPerson)(|(uid=*%s*)(mail=*%s*)(description=*%s*)))"
,
keyword
,
keyword
,
keyword
)
}
}
if
username
:=
conditions
.
Match
[
"username"
];
username
!=
""
{
uidFilter
:=
""
for
_
,
username
:=
range
strings
.
Split
(
username
,
"|"
)
{
uidFilter
+=
fmt
.
Sprintf
(
"(uid=%s)"
,
username
)
}
filter
=
fmt
.
Sprintf
(
"(&(objectClass=inetOrgPerson)(|%s))"
,
uidFilter
)
}
if
email
:=
conditions
.
Match
[
"email"
];
email
!=
""
{
emailFilter
:=
""
for
_
,
username
:=
range
strings
.
Split
(
email
,
"|"
)
{
emailFilter
+=
fmt
.
Sprintf
(
"(mail=%s)"
,
username
)
}
filter
=
fmt
.
Sprintf
(
"(&(objectClass=inetOrgPerson)(|%s))"
,
emailFilter
)
}
for
{
for
{
userSearchRequest
:=
ldap
.
NewSearchRequest
(
userSearchRequest
:=
ldap
.
NewSearchRequest
(
ldapclient
.
UserSearchBase
,
ldapclient
.
UserSearchBase
,
...
@@ -331,26 +372,13 @@ func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limi
...
@@ -331,26 +372,13 @@ func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limi
if
i
>=
offset
&&
len
(
items
)
<
limit
{
if
i
>=
offset
&&
len
(
items
)
<
limit
{
avatar
,
err
:=
getAvatar
(
user
.
Username
)
user
.
AvatarUrl
=
getAvatar
(
user
.
Username
)
if
err
!=
nil
{
user
.
LastLoginTime
=
getLastLoginTime
(
user
.
Username
)
return
nil
,
err
}
user
.
AvatarUrl
=
avatar
lastLoginTime
,
err
:=
getLastLoginTime
(
user
.
Username
)
if
err
!=
nil
{
return
nil
,
err
}
user
.
LastLoginTime
=
lastLoginTime
clusterRole
,
err
:=
GetUserClusterRole
(
user
.
Username
)
clusterRole
,
err
:=
GetUserClusterRole
(
user
.
Username
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
user
.
ClusterRole
=
clusterRole
.
Name
user
.
ClusterRole
=
clusterRole
.
Name
items
=
append
(
items
,
user
)
items
=
append
(
items
,
user
)
}
}
}
}
...
@@ -373,23 +401,47 @@ func DescribeUser(username string) (*models.User, error) {
...
@@ -373,23 +401,47 @@ func DescribeUser(username string) (*models.User, error) {
}
}
user
.
Groups
=
groups
user
.
Groups
=
groups
user
.
AvatarUrl
=
getAvatar
(
username
)
avatar
,
err
:=
getAvatar
(
username
)
return
user
,
nil
}
func
GetUserInfoByEmail
(
mail
string
)
(
*
models
.
User
,
error
)
{
conn
,
err
:=
ldapclient
.
Client
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
user
.
AvatarUrl
=
avatar
userSearchRequest
:=
ldap
.
NewSearchRequest
(
ldapclient
.
UserSearchBase
,
ldap
.
ScopeWholeSubtree
,
ldap
.
NeverDerefAliases
,
0
,
0
,
false
,
fmt
.
Sprintf
(
"(&(objectClass=inetOrgPerson)(mail=%s))"
,
mail
),
[]
string
{
"uid"
,
"description"
,
"preferredLanguage"
,
"createTimestamp"
},
nil
,
)
lastLoginTime
,
err
:=
getLastLoginTime
(
username
)
result
,
err
:=
conn
.
Search
(
userSearchRequest
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
user
.
LastLoginTime
=
lastLoginTime
if
len
(
result
.
Entries
)
!=
1
{
return
nil
,
ldap
.
NewError
(
ldap
.
LDAPResultNoSuchObject
,
fmt
.
Errorf
(
"user %s does not exist"
,
mail
))
}
username
:=
result
.
Entries
[
0
]
.
GetAttributeValue
(
"uid"
)
description
:=
result
.
Entries
[
0
]
.
GetAttributeValue
(
"description"
)
lang
:=
result
.
Entries
[
0
]
.
GetAttributeValue
(
"preferredLanguage"
)
createTimestamp
,
_
:=
time
.
Parse
(
"20060102150405Z"
,
result
.
Entries
[
0
]
.
GetAttributeValue
(
"createTimestamp"
))
user
:=
&
models
.
User
{
Username
:
username
,
Email
:
mail
,
Description
:
description
,
Lang
:
lang
,
CreateTime
:
createTimestamp
}
user
.
LastLoginTime
=
getLastLoginTime
(
username
)
clusterRole
,
err
:=
GetUserClusterRole
(
user
.
Username
)
if
err
!=
nil
{
return
nil
,
err
}
user
.
ClusterRole
=
clusterRole
.
Name
return
user
,
nil
return
user
,
nil
}
}
...
@@ -426,6 +478,8 @@ func GetUserInfo(username string) (*models.User, error) {
...
@@ -426,6 +478,8 @@ func GetUserInfo(username string) (*models.User, error) {
createTimestamp
,
_
:=
time
.
Parse
(
"20060102150405Z"
,
result
.
Entries
[
0
]
.
GetAttributeValue
(
"createTimestamp"
))
createTimestamp
,
_
:=
time
.
Parse
(
"20060102150405Z"
,
result
.
Entries
[
0
]
.
GetAttributeValue
(
"createTimestamp"
))
user
:=
&
models
.
User
{
Username
:
username
,
Email
:
email
,
Description
:
description
,
Lang
:
lang
,
CreateTime
:
createTimestamp
}
user
:=
&
models
.
User
{
Username
:
username
,
Email
:
email
,
Description
:
description
,
Lang
:
lang
,
CreateTime
:
createTimestamp
}
user
.
LastLoginTime
=
getLastLoginTime
(
username
)
return
user
,
nil
return
user
,
nil
}
}
...
@@ -462,17 +516,18 @@ func GetUserGroups(username string) ([]string, error) {
...
@@ -462,17 +516,18 @@ func GetUserGroups(username string) ([]string, error) {
return
groups
,
nil
return
groups
,
nil
}
}
func
getLastLoginTime
(
username
string
)
(
string
,
error
)
{
func
getLastLoginTime
(
username
string
)
string
{
lastLogin
,
err
:=
redis
.
Client
()
.
LRange
(
fmt
.
Sprintf
(
"kubesphere:users:%s:login-log"
,
username
),
-
1
,
-
1
)
.
Result
()
lastLogin
,
err
:=
redis
.
Client
()
.
LRange
(
fmt
.
Sprintf
(
"kubesphere:users:%s:login-log"
,
username
),
-
1
,
-
1
)
.
Result
()
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
}
}
if
len
(
lastLogin
)
>
0
{
if
len
(
lastLogin
)
>
0
{
return
strings
.
Split
(
lastLogin
[
0
],
","
)[
0
]
,
nil
return
strings
.
Split
(
lastLogin
[
0
],
","
)[
0
]
}
}
return
""
,
nil
return
""
}
}
func
setAvatar
(
username
,
avatar
string
)
error
{
func
setAvatar
(
username
,
avatar
string
)
error
{
...
@@ -480,20 +535,21 @@ func setAvatar(username, avatar string) error {
...
@@ -480,20 +535,21 @@ func setAvatar(username, avatar string) error {
return
err
return
err
}
}
func
getAvatar
(
username
string
)
(
string
,
error
)
{
func
getAvatar
(
username
string
)
string
{
avatar
,
err
:=
redis
.
Client
()
.
HMGet
(
"kubesphere:users:avatar"
,
username
)
.
Result
()
avatar
,
err
:=
redis
.
Client
()
.
HMGet
(
"kubesphere:users:avatar"
,
username
)
.
Result
()
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
}
}
if
len
(
avatar
)
>
0
{
if
len
(
avatar
)
>
0
{
if
url
,
ok
:=
avatar
[
0
]
.
(
string
);
ok
{
if
url
,
ok
:=
avatar
[
0
]
.
(
string
);
ok
{
return
url
,
nil
return
url
}
}
}
}
return
""
,
nil
return
""
}
}
func
DeleteUser
(
username
string
)
error
{
func
DeleteUser
(
username
string
)
error
{
...
@@ -811,7 +867,7 @@ func UpdateUser(user *models.User) (*models.User, error) {
...
@@ -811,7 +867,7 @@ func UpdateUser(user *models.User) (*models.User, error) {
return
nil
,
err
return
nil
,
err
}
}
return
DescribeUser
(
user
.
Username
)
return
GetUserInfo
(
user
.
Username
)
}
}
func
DeleteGroup
(
path
string
)
error
{
func
DeleteGroup
(
path
string
)
error
{
...
@@ -1105,13 +1161,15 @@ func ListWorkspaceUsers(workspace string, conditions *params.Conditions, orderBy
...
@@ -1105,13 +1161,15 @@ func ListWorkspaceUsers(workspace string, conditions *params.Conditions, orderBy
for
_
,
roleBinding
:=
range
workspaceRoleBindings
{
for
_
,
roleBinding
:=
range
workspaceRoleBindings
{
for
_
,
subject
:=
range
roleBinding
.
Subjects
{
for
_
,
subject
:=
range
roleBinding
.
Subjects
{
if
subject
.
Kind
==
v1
.
UserKind
&&
!
k8sutil
.
ContainsUser
(
users
,
subject
.
Name
)
{
if
subject
.
Kind
==
v1
.
UserKind
&&
!
k8sutil
.
ContainsUser
(
users
,
subject
.
Name
)
{
user
,
err
:=
DescribeUser
(
subject
.
Name
)
user
,
err
:=
GetUserInfo
(
subject
.
Name
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
prefix
:=
fmt
.
Sprintf
(
"workspace:%s:"
,
workspace
)
prefix
:=
fmt
.
Sprintf
(
"workspace:%s:"
,
workspace
)
user
.
WorkspaceRole
=
fmt
.
Sprintf
(
"workspace-%s"
,
strings
.
TrimPrefix
(
roleBinding
.
Name
,
prefix
))
user
.
WorkspaceRole
=
fmt
.
Sprintf
(
"workspace-%s"
,
strings
.
TrimPrefix
(
roleBinding
.
Name
,
prefix
))
users
=
append
(
users
,
user
)
if
matchConditions
(
conditions
,
user
)
{
users
=
append
(
users
,
user
)
}
}
}
}
}
}
}
...
@@ -1141,3 +1199,31 @@ func ListWorkspaceUsers(workspace string, conditions *params.Conditions, orderBy
...
@@ -1141,3 +1199,31 @@ func ListWorkspaceUsers(workspace string, conditions *params.Conditions, orderBy
return
&
models
.
PageableResponse
{
Items
:
result
,
TotalCount
:
len
(
users
)},
nil
return
&
models
.
PageableResponse
{
Items
:
result
,
TotalCount
:
len
(
users
)},
nil
}
}
func
matchConditions
(
conditions
*
params
.
Conditions
,
user
*
models
.
User
)
bool
{
for
k
,
v
:=
range
conditions
.
Match
{
switch
k
{
case
"keyword"
:
if
!
strings
.
Contains
(
user
.
Username
,
v
)
&&
!
strings
.
Contains
(
user
.
Email
,
v
)
&&
!
strings
.
Contains
(
user
.
Description
,
v
)
{
return
false
}
case
"name"
:
names
:=
strings
.
Split
(
v
,
"|"
)
if
!
sliceutil
.
HasString
(
names
,
user
.
Username
)
{
return
false
}
case
"email"
:
email
:=
strings
.
Split
(
v
,
"|"
)
if
!
sliceutil
.
HasString
(
email
,
user
.
Email
)
{
return
false
}
case
"role"
:
if
user
.
WorkspaceRole
!=
v
{
return
false
}
}
}
return
true
}
pkg/models/iam/policy/policy.go
浏览文件 @
5c4efd53
...
@@ -126,6 +126,18 @@ var (
...
@@ -126,6 +126,18 @@ var (
},
},
},
},
},
},
{
Name
:
"logging"
,
Actions
:
[]
models
.
Action
{
{
Name
:
"view"
,
Rules
:
[]
v1
.
PolicyRule
{{
Verbs
:
[]
string
{
"get"
,
"list"
},
APIGroups
:
[]
string
{
"logging.kubesphere.io"
},
Resources
:
[]
string
{
"*"
},
}},
},
},
},
{
{
Name
:
"accounts"
,
Name
:
"accounts"
,
Actions
:
[]
models
.
Action
{
Actions
:
[]
models
.
Action
{
...
@@ -683,8 +695,8 @@ var (
...
@@ -683,8 +695,8 @@ var (
Rules
:
[]
v1
.
PolicyRule
{
Rules
:
[]
v1
.
PolicyRule
{
{
{
Verbs
:
[]
string
{
"get"
},
Verbs
:
[]
string
{
"get"
},
APIGroups
:
[]
string
{
"
resources
.kubesphere.io"
},
APIGroups
:
[]
string
{
"
terminal
.kubesphere.io"
},
Resources
:
[]
string
{
"pod
/terminal
"
},
Resources
:
[]
string
{
"pod
s
"
},
},
},
},
},
},
},
...
...
pkg/models/resources/clusterroles.go
浏览文件 @
5c4efd53
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
package
resources
package
resources
import
(
import
(
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
...
@@ -55,6 +56,12 @@ func (*clusterRoleSearcher) match(match map[string]string, item *rbac.ClusterRol
...
@@ -55,6 +56,12 @@ func (*clusterRoleSearcher) match(match map[string]string, item *rbac.ClusterRol
if
!
strings
.
Contains
(
item
.
Name
,
v
)
&&
!
searchFuzzy
(
item
.
Labels
,
""
,
v
)
&&
!
searchFuzzy
(
item
.
Annotations
,
""
,
v
)
{
if
!
strings
.
Contains
(
item
.
Name
,
v
)
&&
!
searchFuzzy
(
item
.
Labels
,
""
,
v
)
&&
!
searchFuzzy
(
item
.
Annotations
,
""
,
v
)
{
return
false
return
false
}
}
case
"userfacing"
:
if
v
==
"true"
{
if
!
isUserFacingClusterRole
(
item
)
{
return
false
}
}
default
:
default
:
if
item
.
Labels
[
k
]
!=
v
{
if
item
.
Labels
[
k
]
!=
v
{
return
false
return
false
...
@@ -134,3 +141,10 @@ func (s *clusterRoleSearcher) search(namespace string, conditions *params.Condit
...
@@ -134,3 +141,10 @@ func (s *clusterRoleSearcher) search(namespace string, conditions *params.Condit
}
}
return
r
,
nil
return
r
,
nil
}
}
func
isUserFacingClusterRole
(
role
*
rbac
.
ClusterRole
)
bool
{
if
role
.
Labels
[
constants
.
CreatorLabelKey
]
!=
""
&&
role
.
Labels
[
constants
.
WorkspaceLabelKey
]
==
""
{
return
true
}
return
false
}
pkg/models/resources/resources.go
浏览文件 @
5c4efd53
...
@@ -103,24 +103,15 @@ type resourceSearchInterface interface {
...
@@ -103,24 +103,15 @@ type resourceSearchInterface interface {
search
(
namespace
string
,
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
)
([]
interface
{},
error
)
search
(
namespace
string
,
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
)
([]
interface
{},
error
)
}
}
func
ListResourcesByName
(
namespace
,
resource
string
,
names
[]
string
)
(
*
models
.
PageableResponse
,
error
)
{
func
GetResource
(
namespace
,
resource
,
name
string
)
(
interface
{},
error
)
{
items
:=
make
([]
interface
{},
0
)
if
searcher
,
ok
:=
resources
[
resource
];
ok
{
if
searcher
,
ok
:=
resources
[
resource
];
ok
{
for
_
,
name
:=
range
names
{
resource
,
err
:=
searcher
.
get
(
namespace
,
name
)
item
,
err
:=
searcher
.
get
(
namespace
,
name
)
if
err
!=
nil
{
return
nil
,
err
if
err
!=
nil
{
return
nil
,
err
}
items
=
append
(
items
,
item
)
}
}
return
resource
,
nil
}
else
{
return
nil
,
fmt
.
Errorf
(
"not found"
)
}
}
return
nil
,
fmt
.
Errorf
(
"resource %s not found"
,
resource
)
return
&
models
.
PageableResponse
{
TotalCount
:
len
(
items
),
Items
:
items
},
nil
}
}
func
ListResources
(
namespace
,
resource
string
,
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
,
limit
,
offset
int
)
(
*
models
.
PageableResponse
,
error
)
{
func
ListResources
(
namespace
,
resource
string
,
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
,
limit
,
offset
int
)
(
*
models
.
PageableResponse
,
error
)
{
...
...
pkg/models/routers/routers.go
浏览文件 @
5c4efd53
...
@@ -22,6 +22,7 @@ import (
...
@@ -22,6 +22,7 @@ import (
"fmt"
"fmt"
"github.com/golang/glog"
"github.com/golang/glog"
"io/ioutil"
"io/ioutil"
"k8s.io/apimachinery/pkg/api/errors"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"sort"
"sort"
...
@@ -127,7 +128,7 @@ func GetRouter(namespace string) (*corev1.Service, error) {
...
@@ -127,7 +128,7 @@ func GetRouter(namespace string) (*corev1.Service, error) {
}
}
}
}
return
nil
,
fmt
.
Errorf
(
"resources not found %s"
,
serviceName
)
return
nil
,
errors
.
NewNotFound
(
corev1
.
Resource
(
"service"
)
,
serviceName
)
}
}
// Load all resource yamls
// Load all resource yamls
...
...
pkg/models/tenant/devops.go
浏览文件 @
5c4efd53
...
@@ -18,15 +18,10 @@
...
@@ -18,15 +18,10 @@
package
tenant
package
tenant
import
(
import
(
"encoding/json"
"fmt"
"io/ioutil"
"kubesphere.io/kubesphere/pkg/constants"
kserr
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"net/http"
"sort"
"sort"
"strings"
"strings"
)
)
...
@@ -41,79 +36,55 @@ func ListDevopsProjects(workspace, username string, conditions *params.Condition
...
@@ -41,79 +36,55 @@ func ListDevopsProjects(workspace, username string, conditions *params.Condition
return
nil
,
err
return
nil
,
err
}
}
devOpsProjects
:=
make
([]
models
.
DevopsProject
,
0
)
projects
,
err
:=
kubesphere
.
Client
()
.
ListDevopsProjects
(
username
)
request
,
_
:=
http
.
NewRequest
(
http
.
MethodGet
,
fmt
.
Sprintf
(
"http://%s/api/v1alpha/projects"
,
constants
.
DevopsAPIServer
),
nil
)
request
.
Header
.
Add
(
constants
.
UserNameHeader
,
username
)
resp
,
err
:=
http
.
DefaultClient
.
Do
(
request
)
if
err
!=
nil
{
return
nil
,
err
}
defer
resp
.
Body
.
Close
()
data
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
nil
,
err
}
if
resp
.
StatusCode
>
200
{
return
nil
,
kserr
.
Parse
(
data
)
}
err
=
json
.
Unmarshal
(
data
,
&
devOpsProjects
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
if
keyword
:=
conditions
.
Match
[
"keyword"
];
keyword
!=
""
{
if
keyword
:=
conditions
.
Match
[
"keyword"
];
keyword
!=
""
{
for
i
:=
0
;
i
<
len
(
devOpsP
rojects
);
i
++
{
for
i
:=
0
;
i
<
len
(
p
rojects
);
i
++
{
if
!
strings
.
Contains
(
devOpsP
rojects
[
i
]
.
Name
,
keyword
)
{
if
!
strings
.
Contains
(
p
rojects
[
i
]
.
Name
,
keyword
)
{
devOpsProjects
=
append
(
devOpsProjects
[
:
i
],
devOpsP
rojects
[
i
+
1
:
]
...
)
projects
=
append
(
projects
[
:
i
],
p
rojects
[
i
+
1
:
]
...
)
i
--
i
--
}
}
}
}
}
}
sort
.
Slice
(
devOpsProjects
,
func
(
i
,
j
int
)
bool
{
sort
.
Slice
(
projects
,
func
(
i
,
j
int
)
bool
{
if
reverse
{
tmp
:=
i
i
=
j
j
=
tmp
}
switch
orderBy
{
switch
orderBy
{
case
"name"
:
case
"name"
:
if
reverse
{
return
projects
[
i
]
.
Name
>
projects
[
j
]
.
Name
return
devOpsProjects
[
i
]
.
Name
<
devOpsProjects
[
j
]
.
Name
}
else
{
return
devOpsProjects
[
i
]
.
Name
>
devOpsProjects
[
j
]
.
Name
}
default
:
default
:
if
reverse
{
return
projects
[
i
]
.
CreateTime
.
Before
(
*
projects
[
j
]
.
CreateTime
)
return
devOpsProjects
[
i
]
.
CreateTime
.
After
(
*
devOpsProjects
[
j
]
.
CreateTime
)
}
else
{
return
devOpsProjects
[
i
]
.
CreateTime
.
Before
(
*
devOpsProjects
[
j
]
.
CreateTime
)
}
}
}
})
})
for
i
:=
0
;
i
<
len
(
devOpsP
rojects
);
i
++
{
for
i
:=
0
;
i
<
len
(
p
rojects
);
i
++
{
inWorkspace
:=
false
inWorkspace
:=
false
for
_
,
binding
:=
range
workspaceDOPBindings
{
for
_
,
binding
:=
range
workspaceDOPBindings
{
if
binding
.
DevOpsProject
==
*
devOpsP
rojects
[
i
]
.
ProjectId
{
if
binding
.
DevOpsProject
==
p
rojects
[
i
]
.
ProjectId
{
inWorkspace
=
true
inWorkspace
=
true
}
}
}
}
if
!
inWorkspace
{
if
!
inWorkspace
{
devOpsProjects
=
append
(
devOpsProjects
[
:
i
],
devOpsP
rojects
[
i
+
1
:
]
...
)
projects
=
append
(
projects
[
:
i
],
p
rojects
[
i
+
1
:
]
...
)
i
--
i
--
}
}
}
}
// limit offset
// limit offset
result
:=
make
([]
interface
{},
0
)
result
:=
make
([]
interface
{},
0
)
for
i
,
v
:=
range
devOpsP
rojects
{
for
i
,
v
:=
range
p
rojects
{
if
len
(
result
)
<
limit
&&
i
>=
offset
{
if
len
(
result
)
<
limit
&&
i
>=
offset
{
result
=
append
(
result
,
v
)
result
=
append
(
result
,
v
)
}
}
}
}
return
&
models
.
PageableResponse
{
Items
:
result
,
TotalCount
:
len
(
devOpsP
rojects
)},
nil
return
&
models
.
PageableResponse
{
Items
:
result
,
TotalCount
:
len
(
p
rojects
)},
nil
}
}
pkg/models/tenant/namespaces.go
浏览文件 @
5c4efd53
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
rbacv1
"k8s.io/api/rbac/v1"
rbacv1
"k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/labels"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/params"
...
@@ -35,6 +36,14 @@ type namespaceSearcher struct {
...
@@ -35,6 +36,14 @@ type namespaceSearcher struct {
func
(
*
namespaceSearcher
)
match
(
match
map
[
string
]
string
,
item
*
v1
.
Namespace
)
bool
{
func
(
*
namespaceSearcher
)
match
(
match
map
[
string
]
string
,
item
*
v1
.
Namespace
)
bool
{
for
k
,
v
:=
range
match
{
for
k
,
v
:=
range
match
{
switch
k
{
switch
k
{
case
"name"
:
if
item
.
Name
!=
v
&&
item
.
Labels
[
constants
.
DisplayNameLabelKey
]
!=
v
{
return
false
}
case
"keyword"
:
if
!
strings
.
Contains
(
item
.
Name
,
v
)
&&
!
contains
(
item
.
Labels
,
""
,
v
)
&&
!
contains
(
item
.
Annotations
,
""
,
v
)
{
return
false
}
default
:
default
:
if
item
.
Labels
[
k
]
!=
v
{
if
item
.
Labels
[
k
]
!=
v
{
return
false
return
false
...
...
pkg/models/tenant/tenant.go
浏览文件 @
5c4efd53
...
@@ -19,7 +19,9 @@ package tenant
...
@@ -19,7 +19,9 @@ package tenant
import
(
import
(
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models"
ws
"kubesphere.io/kubesphere/pkg/models/workspaces"
ws
"kubesphere.io/kubesphere/pkg/models/workspaces"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/params"
...
@@ -45,6 +47,18 @@ func CreateNamespace(workspaceName string, namespace *v1.Namespace, username str
...
@@ -45,6 +47,18 @@ func CreateNamespace(workspaceName string, namespace *v1.Namespace, username str
return
k8s
.
Client
()
.
CoreV1
()
.
Namespaces
()
.
Create
(
namespace
)
return
k8s
.
Client
()
.
CoreV1
()
.
Namespaces
()
.
Create
(
namespace
)
}
}
func
DescribeWorkspace
(
username
,
workspaceName
string
)
(
*
v1alpha1
.
Workspace
,
error
)
{
workspace
,
err
:=
informers
.
KsSharedInformerFactory
()
.
Tenant
()
.
V1alpha1
()
.
Workspaces
()
.
Lister
()
.
Get
(
workspaceName
)
if
err
!=
nil
{
return
nil
,
err
}
workspace
=
appendAnnotations
(
username
,
workspace
)
return
workspace
,
nil
}
func
ListWorkspaces
(
username
string
,
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
,
limit
,
offset
int
)
(
*
models
.
PageableResponse
,
error
)
{
func
ListWorkspaces
(
username
string
,
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
,
limit
,
offset
int
)
(
*
models
.
PageableResponse
,
error
)
{
workspaces
,
err
:=
workspaces
.
search
(
username
,
conditions
,
orderBy
,
reverse
)
workspaces
,
err
:=
workspaces
.
search
(
username
,
conditions
,
orderBy
,
reverse
)
...
@@ -57,25 +71,7 @@ func ListWorkspaces(username string, conditions *params.Conditions, orderBy stri
...
@@ -57,25 +71,7 @@ func ListWorkspaces(username string, conditions *params.Conditions, orderBy stri
result
:=
make
([]
interface
{},
0
)
result
:=
make
([]
interface
{},
0
)
for
i
,
workspace
:=
range
workspaces
{
for
i
,
workspace
:=
range
workspaces
{
if
len
(
result
)
<
limit
&&
i
>=
offset
{
if
len
(
result
)
<
limit
&&
i
>=
offset
{
workspace
:=
workspace
.
DeepCopy
()
workspace
:=
appendAnnotations
(
username
,
workspace
)
ns
,
err
:=
ListNamespaces
(
username
,
&
params
.
Conditions
{
Match
:
map
[
string
]
string
{
"kubesphere.io/workspace"
:
workspace
.
Name
}},
""
,
false
,
1
,
0
)
if
err
!=
nil
{
return
nil
,
err
}
if
workspace
.
Annotations
==
nil
{
workspace
.
Annotations
=
make
(
map
[
string
]
string
)
}
workspace
.
Annotations
[
"kubesphere.io/namespace-count"
]
=
strconv
.
Itoa
(
ns
.
TotalCount
)
devops
,
err
:=
ListDevopsProjects
(
workspace
.
Name
,
username
,
&
params
.
Conditions
{},
""
,
false
,
1
,
0
)
if
err
!=
nil
{
return
nil
,
err
}
workspace
.
Annotations
[
"kubesphere.io/devops-count"
]
=
strconv
.
Itoa
(
devops
.
TotalCount
)
userCount
,
err
:=
ws
.
WorkspaceUserCount
(
workspace
.
Name
)
if
err
!=
nil
{
return
nil
,
err
}
workspace
.
Annotations
[
"kubesphere.io/member-count"
]
=
strconv
.
Itoa
(
userCount
)
result
=
append
(
result
,
workspace
)
result
=
append
(
result
,
workspace
)
}
}
}
}
...
@@ -83,6 +79,32 @@ func ListWorkspaces(username string, conditions *params.Conditions, orderBy stri
...
@@ -83,6 +79,32 @@ func ListWorkspaces(username string, conditions *params.Conditions, orderBy stri
return
&
models
.
PageableResponse
{
Items
:
result
,
TotalCount
:
len
(
workspaces
)},
nil
return
&
models
.
PageableResponse
{
Items
:
result
,
TotalCount
:
len
(
workspaces
)},
nil
}
}
func
appendAnnotations
(
username
string
,
workspace
*
v1alpha1
.
Workspace
)
*
v1alpha1
.
Workspace
{
workspace
=
workspace
.
DeepCopy
()
if
workspace
.
Annotations
==
nil
{
workspace
.
Annotations
=
make
(
map
[
string
]
string
)
}
ns
,
err
:=
ListNamespaces
(
username
,
&
params
.
Conditions
{
Match
:
map
[
string
]
string
{
constants
.
WorkspaceLabelKey
:
workspace
.
Name
}},
""
,
false
,
1
,
0
)
if
err
==
nil
{
workspace
.
Annotations
[
"kubesphere.io/namespace-count"
]
=
strconv
.
Itoa
(
ns
.
TotalCount
)
}
else
{
workspace
.
Annotations
[
"kubesphere.io/namespace-count"
]
=
"-1"
}
devops
,
err
:=
ListDevopsProjects
(
workspace
.
Name
,
username
,
&
params
.
Conditions
{},
""
,
false
,
1
,
0
)
if
err
==
nil
{
workspace
.
Annotations
[
"kubesphere.io/devops-count"
]
=
strconv
.
Itoa
(
devops
.
TotalCount
)
}
else
{
workspace
.
Annotations
[
"kubesphere.io/devops-count"
]
=
"-1"
}
userCount
,
err
:=
ws
.
WorkspaceUserCount
(
workspace
.
Name
)
if
err
==
nil
{
workspace
.
Annotations
[
"kubesphere.io/member-count"
]
=
strconv
.
Itoa
(
userCount
)
}
else
{
workspace
.
Annotations
[
"kubesphere.io/member-count"
]
=
"-1"
}
return
workspace
}
func
ListNamespaces
(
username
string
,
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
,
limit
,
offset
int
)
(
*
models
.
PageableResponse
,
error
)
{
func
ListNamespaces
(
username
string
,
conditions
*
params
.
Conditions
,
orderBy
string
,
reverse
bool
,
limit
,
offset
int
)
(
*
models
.
PageableResponse
,
error
)
{
namespaces
,
err
:=
namespaces
.
search
(
username
,
conditions
,
orderBy
,
reverse
)
namespaces
,
err
:=
namespaces
.
search
(
username
,
conditions
,
orderBy
,
reverse
)
...
...
pkg/models/tenant/workspaces.go
浏览文件 @
5c4efd53
...
@@ -40,6 +40,10 @@ func (*workspaceSearcher) match(match map[string]string, item *v1alpha1.Workspac
...
@@ -40,6 +40,10 @@ func (*workspaceSearcher) match(match map[string]string, item *v1alpha1.Workspac
if
item
.
Name
!=
v
&&
item
.
Labels
[
constants
.
DisplayNameLabelKey
]
!=
v
{
if
item
.
Name
!=
v
&&
item
.
Labels
[
constants
.
DisplayNameLabelKey
]
!=
v
{
return
false
return
false
}
}
case
"keyword"
:
if
!
strings
.
Contains
(
item
.
Name
,
v
)
&&
!
contains
(
item
.
Labels
,
""
,
v
)
&&
!
contains
(
item
.
Annotations
,
""
,
v
)
{
return
false
}
default
:
default
:
if
item
.
Labels
[
k
]
!=
v
{
if
item
.
Labels
[
k
]
!=
v
{
return
false
return
false
...
@@ -128,3 +132,16 @@ func (s *workspaceSearcher) search(username string, conditions *params.Condition
...
@@ -128,3 +132,16 @@ func (s *workspaceSearcher) search(username string, conditions *params.Condition
func
GetWorkspace
(
workspaceName
string
)
(
*
v1alpha1
.
Workspace
,
error
)
{
func
GetWorkspace
(
workspaceName
string
)
(
*
v1alpha1
.
Workspace
,
error
)
{
return
informers
.
KsSharedInformerFactory
()
.
Tenant
()
.
V1alpha1
()
.
Workspaces
()
.
Lister
()
.
Get
(
workspaceName
)
return
informers
.
KsSharedInformerFactory
()
.
Tenant
()
.
V1alpha1
()
.
Workspaces
()
.
Lister
()
.
Get
(
workspaceName
)
}
}
func
contains
(
m
map
[
string
]
string
,
key
,
value
string
)
bool
{
for
k
,
v
:=
range
m
{
if
key
==
""
{
if
strings
.
Contains
(
k
,
value
)
||
strings
.
Contains
(
v
,
value
)
{
return
true
}
}
else
if
k
==
key
&&
strings
.
Contains
(
v
,
value
)
{
return
true
}
}
return
false
}
pkg/models/types.go
浏览文件 @
5c4efd53
...
@@ -42,7 +42,7 @@ type WorkspaceDPBinding struct {
...
@@ -42,7 +42,7 @@ type WorkspaceDPBinding struct {
}
}
type
DevopsProject
struct
{
type
DevopsProject
struct
{
ProjectId
*
string
`json:"project_id,omitempty"`
ProjectId
string
`json:"project_id,omitempty"`
Name
string
`json:"name"`
Name
string
`json:"name"`
Description
string
`json:"description"`
Description
string
`json:"description"`
Creator
string
`json:"creator"`
Creator
string
`json:"creator"`
...
...
pkg/models/workspaces/workspaces.go
浏览文件 @
5c4efd53
...
@@ -18,41 +18,29 @@
...
@@ -18,41 +18,29 @@
package
workspaces
package
workspaces
import
(
import
(
"bytes"
"encoding/json"
"fmt"
"fmt"
"io/ioutil"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/
ldap
"
"kubesphere.io/kubesphere/pkg/simple/client/
kubesphere
"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"net/http"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam"
"strings"
"strings"
"github.com/jinzhu/gorm"
core
"k8s.io/api/core/v1"
core
"k8s.io/api/core/v1"
"errors"
"errors"
"github.com/golang/glog"
"k8s.io/api/rbac/v1"
"k8s.io/api/rbac/v1"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
meta_v1
"k8s.io/apimachinery/pkg/apis/meta/v1"
meta_v1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/labels"
"sort"
kserr
"kubesphere.io/kubesphere/pkg/errors"
)
)
func
UnBindDevopsProject
(
workspace
string
,
devops
string
)
error
{
func
UnBindDevopsProject
(
workspace
string
,
devops
string
)
error
{
...
@@ -60,191 +48,26 @@ func UnBindDevopsProject(workspace string, devops string) error {
...
@@ -60,191 +48,26 @@ func UnBindDevopsProject(workspace string, devops string) error {
return
db
.
Delete
(
&
models
.
WorkspaceDPBinding
{
Workspace
:
workspace
,
DevOpsProject
:
devops
})
.
Error
return
db
.
Delete
(
&
models
.
WorkspaceDPBinding
{
Workspace
:
workspace
,
DevOpsProject
:
devops
})
.
Error
}
}
func
DeleteDevopsProject
(
username
string
,
devops
string
)
error
{
func
CreateDevopsProject
(
username
string
,
workspace
string
,
devops
*
models
.
DevopsProject
)
(
*
models
.
DevopsProject
,
error
)
{
request
,
_
:=
http
.
NewRequest
(
http
.
MethodDelete
,
fmt
.
Sprintf
(
"http://%s/api/v1alpha/projects/%s"
,
constants
.
DevopsAPIServer
,
devops
),
nil
)
request
.
Header
.
Add
(
"X-Token-Username"
,
username
)
result
,
err
:=
http
.
DefaultClient
.
Do
(
request
)
if
err
!=
nil
{
return
err
}
defer
result
.
Body
.
Close
()
data
,
err
:=
ioutil
.
ReadAll
(
result
.
Body
)
if
err
!=
nil
{
return
err
}
if
result
.
StatusCode
>
200
{
return
kserr
.
Parse
(
data
)
}
return
nil
}
func
CreateDevopsProject
(
username
string
,
workspace
string
,
devops
models
.
DevopsProject
)
(
*
models
.
DevopsProject
,
error
)
{
data
,
err
:=
json
.
Marshal
(
devops
)
if
err
!=
nil
{
return
nil
,
err
}
request
,
_
:=
http
.
NewRequest
(
http
.
MethodPost
,
fmt
.
Sprintf
(
"http://%s/api/v1alpha/projects"
,
constants
.
DevopsAPIServer
),
bytes
.
NewReader
(
data
))
request
.
Header
.
Add
(
"X-Token-Username"
,
username
)
request
.
Header
.
Add
(
"Content-Type"
,
"application/json"
)
result
,
err
:=
http
.
DefaultClient
.
Do
(
request
)
if
err
!=
nil
{
return
nil
,
err
}
defer
result
.
Body
.
Close
()
data
,
err
=
ioutil
.
ReadAll
(
result
.
Body
)
if
err
!=
nil
{
return
nil
,
err
}
if
result
.
StatusCode
>
200
{
created
,
err
:=
kubesphere
.
Client
()
.
CreateDevopsProject
(
username
,
devops
)
return
nil
,
kserr
.
Parse
(
data
)
}
var
project
models
.
DevopsProject
err
=
json
.
Unmarshal
(
data
,
&
project
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
err
=
BindingDevopsProject
(
workspace
,
*
project
.
ProjectId
)
err
=
BindingDevopsProject
(
workspace
,
created
.
ProjectId
)
if
err
!=
nil
{
if
err
!=
nil
{
DeleteDevopsProject
(
username
,
*
project
.
ProjectId
)
return
nil
,
err
return
nil
,
err
}
}
go
createDefaultDevopsRoleBinding
(
workspace
,
project
)
return
created
,
nil
return
&
project
,
nil
}
func
createDefaultDevopsRoleBinding
(
workspace
string
,
project
models
.
DevopsProject
)
error
{
admins
:=
[]
string
{
""
}
for
_
,
admin
:=
range
admins
{
createDevopsRoleBinding
(
workspace
,
*
project
.
ProjectId
,
admin
,
constants
.
DevopsOwner
)
}
viewers
:=
[]
string
{
""
}
for
_
,
viewer
:=
range
viewers
{
createDevopsRoleBinding
(
workspace
,
*
project
.
ProjectId
,
viewer
,
constants
.
DevopsReporter
)
}
return
nil
}
func
createDevopsRoleBinding
(
workspace
string
,
projectId
string
,
user
string
,
role
string
)
{
projects
:=
make
([]
string
,
0
)
if
projectId
!=
""
{
projects
=
append
(
projects
,
projectId
)
}
else
{
p
,
err
:=
GetDevOpsProjects
(
workspace
)
if
err
!=
nil
{
glog
.
Warning
(
"create devops role binding failed"
,
workspace
,
projectId
,
user
,
role
)
return
}
projects
=
append
(
projects
,
p
...
)
}
for
_
,
project
:=
range
projects
{
data
:=
[]
byte
(
fmt
.
Sprintf
(
`{"username":"%s","role":"%s"}`
,
user
,
role
))
request
,
_
:=
http
.
NewRequest
(
http
.
MethodPost
,
fmt
.
Sprintf
(
"http://%s/api/v1alpha/projects/%s/members"
,
constants
.
DevopsAPIServer
,
project
),
bytes
.
NewReader
(
data
))
request
.
Header
.
Add
(
"Content-Type"
,
"application/json"
)
request
.
Header
.
Add
(
"X-Token-Username"
,
"admin"
)
resp
,
err
:=
http
.
DefaultClient
.
Do
(
request
)
if
err
!=
nil
||
resp
.
StatusCode
>
200
{
glog
.
Warning
(
fmt
.
Sprintf
(
"create devops role binding failed %s,%s,%s,%s"
,
workspace
,
project
,
user
,
role
))
}
if
resp
!=
nil
{
resp
.
Body
.
Close
()
}
}
}
func
ListNamespaceByUser
(
workspaceName
string
,
username
string
,
keyword
string
,
orderBy
string
,
reverse
bool
,
limit
int
,
offset
int
)
(
int
,
[]
*
core
.
Namespace
,
error
)
{
namespaces
,
err
:=
Namespaces
(
workspaceName
)
if
err
!=
nil
{
return
0
,
nil
,
err
}
if
keyword
!=
""
{
for
i
:=
0
;
i
<
len
(
namespaces
);
i
++
{
if
!
strings
.
Contains
(
namespaces
[
i
]
.
Name
,
keyword
)
{
namespaces
=
append
(
namespaces
[
:
i
],
namespaces
[
i
+
1
:
]
...
)
i
--
}
}
}
sort
.
Slice
(
namespaces
,
func
(
i
,
j
int
)
bool
{
switch
orderBy
{
case
"name"
:
if
reverse
{
return
namespaces
[
i
]
.
Name
<
namespaces
[
j
]
.
Name
}
else
{
return
namespaces
[
i
]
.
Name
>
namespaces
[
j
]
.
Name
}
default
:
if
reverse
{
return
namespaces
[
i
]
.
CreationTimestamp
.
Time
.
After
(
namespaces
[
j
]
.
CreationTimestamp
.
Time
)
}
else
{
return
namespaces
[
i
]
.
CreationTimestamp
.
Time
.
Before
(
namespaces
[
j
]
.
CreationTimestamp
.
Time
)
}
}
})
rules
,
err
:=
iam
.
GetUserClusterRules
(
username
)
if
err
!=
nil
{
return
0
,
nil
,
err
}
namespacesManager
:=
v1
.
PolicyRule
{
APIGroups
:
[]
string
{
"kubesphere.io"
},
ResourceNames
:
[]
string
{
workspaceName
},
Verbs
:
[]
string
{
"get"
},
Resources
:
[]
string
{
"workspaces/namespaces"
}}
if
!
iam
.
RulesMatchesRequired
(
rules
,
namespacesManager
)
{
for
i
:=
0
;
i
<
len
(
namespaces
);
i
++
{
roles
,
err
:=
iam
.
GetUserRoles
(
namespaces
[
i
]
.
Name
,
username
)
if
err
!=
nil
{
return
0
,
nil
,
err
}
rules
:=
make
([]
v1
.
PolicyRule
,
0
)
for
_
,
role
:=
range
roles
{
rules
=
append
(
rules
,
role
.
Rules
...
)
}
if
!
iam
.
RulesMatchesRequired
(
rules
,
v1
.
PolicyRule
{
APIGroups
:
[]
string
{
""
},
ResourceNames
:
[]
string
{
namespaces
[
i
]
.
Name
},
Verbs
:
[]
string
{
"get"
},
Resources
:
[]
string
{
"namespaces"
}})
{
namespaces
=
append
(
namespaces
[
:
i
],
namespaces
[
i
+
1
:
]
...
)
i
--
}
}
}
if
len
(
namespaces
)
<
offset
{
return
len
(
namespaces
),
namespaces
,
nil
}
else
if
len
(
namespaces
)
<
limit
+
offset
{
return
len
(
namespaces
),
namespaces
[
offset
:
],
nil
}
else
{
return
len
(
namespaces
),
namespaces
[
offset
:
limit
+
offset
],
nil
}
}
}
func
Namespaces
(
workspaceName
string
)
([]
*
core
.
Namespace
,
error
)
{
func
Namespaces
(
workspaceName
string
)
([]
*
core
.
Namespace
,
error
)
{
namespaceLister
:=
informers
.
SharedInformerFactory
()
.
Core
()
.
V1
()
.
Namespaces
()
.
Lister
()
namespaceLister
:=
informers
.
SharedInformerFactory
()
.
Core
()
.
V1
()
.
Namespaces
()
.
Lister
()
namespaces
,
err
:=
namespaceLister
.
List
(
labels
.
SelectorFromSet
(
labels
.
Set
{
"kubesphere.io/workspace"
:
workspaceName
}))
namespaces
,
err
:=
namespaceLister
.
List
(
labels
.
SelectorFromSet
(
labels
.
Set
{
constants
.
WorkspaceLabelKey
:
workspaceName
}))
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -281,161 +104,18 @@ func DeleteNamespace(workspace string, namespaceName string) error {
...
@@ -281,161 +104,18 @@ func DeleteNamespace(workspace string, namespaceName string) error {
}
}
}
}
func
Delete
(
workspace
*
models
.
Workspace
)
error
{
func
RemoveUser
(
workspaceName
string
,
username
string
)
error
{
workspaceRole
,
err
:=
iam
.
GetUserWorkspaceRole
(
workspaceName
,
username
)
err
:=
release
(
workspace
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
err
=
DeleteWorkspaceRoleBinding
(
workspaceName
,
username
,
workspaceRole
.
Labels
[
constants
.
DisplayNameLabelKey
])
err
=
iam
.
DeleteGroup
(
workspace
.
Name
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
return
nil
return
nil
}
}
// TODO
func
release
(
workspace
*
models
.
Workspace
)
error
{
for
_
,
namespace
:=
range
workspace
.
Namespaces
{
err
:=
DeleteNamespace
(
workspace
.
Name
,
namespace
)
if
err
!=
nil
&&
!
apierrors
.
IsNotFound
(
err
)
{
return
err
}
}
for
_
,
devops
:=
range
workspace
.
DevopsProjects
{
err
:=
DeleteDevopsProject
(
"admin"
,
devops
)
if
err
!=
nil
&&
!
strings
.
Contains
(
err
.
Error
(),
"not found"
)
{
return
err
}
}
err
:=
workspaceRoleRelease
(
workspace
.
Name
)
return
err
}
func
workspaceRoleRelease
(
workspace
string
)
error
{
k8sClient
:=
k8s
.
Client
()
deletePolicy
:=
meta_v1
.
DeletePropagationForeground
for
_
,
role
:=
range
constants
.
WorkSpaceRoles
{
err
:=
k8sClient
.
RbacV1
()
.
ClusterRoles
()
.
Delete
(
fmt
.
Sprintf
(
"system:%s:%s"
,
workspace
,
role
),
&
meta_v1
.
DeleteOptions
{
PropagationPolicy
:
&
deletePolicy
})
if
err
!=
nil
&&
!
apierrors
.
IsNotFound
(
err
)
{
return
err
}
}
for
_
,
role
:=
range
constants
.
WorkSpaceRoles
{
err
:=
k8sClient
.
RbacV1
()
.
ClusterRoleBindings
()
.
Delete
(
fmt
.
Sprintf
(
"system:%s:%s"
,
workspace
,
role
),
&
meta_v1
.
DeleteOptions
{
PropagationPolicy
:
&
deletePolicy
})
if
err
!=
nil
&&
!
apierrors
.
IsNotFound
(
err
)
{
return
err
}
}
return
nil
}
func
Edit
(
workspace
*
models
.
Workspace
)
(
*
models
.
Workspace
,
error
)
{
group
,
err
:=
iam
.
UpdateGroup
(
&
workspace
.
Group
)
if
err
!=
nil
{
return
nil
,
err
}
workspace
.
Group
=
*
group
return
workspace
,
nil
}
func
DescribeWorkspace
(
workspaceName
string
)
(
*
v1alpha1
.
Workspace
,
error
)
{
workspace
,
err
:=
informers
.
KsSharedInformerFactory
()
.
Tenant
()
.
V1alpha1
()
.
Workspaces
()
.
Lister
()
.
Get
(
workspaceName
)
if
err
!=
nil
{
return
nil
,
err
}
return
workspace
,
nil
}
func
fetch
(
names
[]
string
)
([]
*
models
.
Workspace
,
error
)
{
if
names
!=
nil
&&
len
(
names
)
==
0
{
return
make
([]
*
models
.
Workspace
,
0
),
nil
}
var
groups
[]
models
.
Group
var
err
error
if
names
==
nil
{
groups
,
err
=
iam
.
ChildList
(
""
)
if
err
!=
nil
{
return
nil
,
err
}
}
else
{
conn
,
err
:=
ldap
.
Client
()
if
err
!=
nil
{
return
nil
,
err
}
defer
conn
.
Close
()
for
_
,
name
:=
range
names
{
group
,
err
:=
iam
.
DescribeGroup
(
name
)
if
err
!=
nil
{
return
nil
,
err
}
groups
=
append
(
groups
,
*
group
)
}
}
db
:=
mysql
.
Client
()
workspaces
:=
make
([]
*
models
.
Workspace
,
0
)
for
_
,
group
:=
range
groups
{
workspace
,
err
:=
convertGroupToWorkspace
(
db
,
group
)
if
err
!=
nil
{
return
nil
,
err
}
workspaces
=
append
(
workspaces
,
workspace
)
}
return
workspaces
,
nil
}
func
convertGroupToWorkspace
(
db
*
gorm
.
DB
,
group
models
.
Group
)
(
*
models
.
Workspace
,
error
)
{
namespaces
,
err
:=
Namespaces
(
group
.
Name
)
if
err
!=
nil
{
return
nil
,
err
}
namespacesNames
:=
make
([]
string
,
0
)
for
_
,
namespace
:=
range
namespaces
{
namespacesNames
=
append
(
namespacesNames
,
namespace
.
Name
)
}
var
workspaceDOPBindings
[]
models
.
WorkspaceDPBinding
if
err
:=
db
.
Where
(
"workspace = ?"
,
group
.
Name
)
.
Find
(
&
workspaceDOPBindings
)
.
Error
;
err
!=
nil
{
return
nil
,
err
}
devOpsProjects
:=
make
([]
string
,
0
)
for
_
,
workspaceDOPBinding
:=
range
workspaceDOPBindings
{
devOpsProjects
=
append
(
devOpsProjects
,
workspaceDOPBinding
.
DevOpsProject
)
}
workspace
:=
models
.
Workspace
{
Group
:
group
}
workspace
.
Namespaces
=
namespacesNames
workspace
.
DevopsProjects
=
devOpsProjects
return
&
workspace
,
nil
}
func
InviteUser
(
workspaceName
string
,
user
*
models
.
User
)
error
{
func
InviteUser
(
workspaceName
string
,
user
*
models
.
User
)
error
{
workspaceRole
,
err
:=
iam
.
GetUserWorkspaceRole
(
workspaceName
,
user
.
Username
)
workspaceRole
,
err
:=
iam
.
GetUserWorkspaceRole
(
workspaceName
,
user
.
Username
)
...
@@ -463,7 +143,6 @@ func CreateWorkspaceRoleBinding(workspace, username string, role string) error {
...
@@ -463,7 +143,6 @@ func CreateWorkspaceRoleBinding(workspace, username string, role string) error {
}
}
roleBindingName
:=
fmt
.
Sprintf
(
"workspace:%s:%s"
,
workspace
,
strings
.
TrimPrefix
(
role
,
"workspace-"
))
roleBindingName
:=
fmt
.
Sprintf
(
"workspace:%s:%s"
,
workspace
,
strings
.
TrimPrefix
(
role
,
"workspace-"
))
workspaceRoleBinding
,
err
:=
informers
.
SharedInformerFactory
()
.
Rbac
()
.
V1
()
.
ClusterRoleBindings
()
.
Lister
()
.
Get
(
roleBindingName
)
workspaceRoleBinding
,
err
:=
informers
.
SharedInformerFactory
()
.
Rbac
()
.
V1
()
.
ClusterRoleBindings
()
.
Lister
()
.
Get
(
roleBindingName
)
workspaceRoleBinding
=
workspaceRoleBinding
.
DeepCopy
()
workspaceRoleBinding
=
workspaceRoleBinding
.
DeepCopy
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -487,11 +166,10 @@ func DeleteWorkspaceRoleBinding(workspace, username string, role string) error {
...
@@ -487,11 +166,10 @@ func DeleteWorkspaceRoleBinding(workspace, username string, role string) error {
roleBindingName
:=
fmt
.
Sprintf
(
"workspace:%s:%s"
,
workspace
,
strings
.
TrimPrefix
(
role
,
"workspace-"
))
roleBindingName
:=
fmt
.
Sprintf
(
"workspace:%s:%s"
,
workspace
,
strings
.
TrimPrefix
(
role
,
"workspace-"
))
workspaceRoleBinding
,
err
:=
informers
.
SharedInformerFactory
()
.
Rbac
()
.
V1
()
.
ClusterRoleBindings
()
.
Lister
()
.
Get
(
roleBindingName
)
workspaceRoleBinding
,
err
:=
informers
.
SharedInformerFactory
()
.
Rbac
()
.
V1
()
.
ClusterRoleBindings
()
.
Lister
()
.
Get
(
roleBindingName
)
workspaceRoleBinding
=
workspaceRoleBinding
.
DeepCopy
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
workspaceRoleBinding
=
workspaceRoleBinding
.
DeepCopy
()
for
i
,
v
:=
range
workspaceRoleBinding
.
Subjects
{
for
i
,
v
:=
range
workspaceRoleBinding
.
Subjects
{
if
v
.
Kind
==
v1
.
UserKind
&&
v
.
Name
==
username
{
if
v
.
Kind
==
v1
.
UserKind
&&
v
.
Name
==
username
{
...
...
pkg/params/params.go
浏览文件 @
5c4efd53
...
@@ -82,18 +82,6 @@ func ParseReverse(req *restful.Request) bool {
...
@@ -82,18 +82,6 @@ func ParseReverse(req *restful.Request) bool {
return
b
return
b
}
}
func
ParseArray
(
str
string
)
[]
string
{
arr
:=
make
([]
string
,
0
)
for
_
,
item
:=
range
strings
.
Split
(
str
,
","
)
{
if
item
=
strings
.
TrimSpace
(
item
);
item
!=
""
{
arr
=
append
(
arr
,
item
)
}
}
return
arr
}
type
Conditions
struct
{
type
Conditions
struct
{
Match
map
[
string
]
string
Match
map
[
string
]
string
Fuzzy
map
[
string
]
string
Fuzzy
map
[
string
]
string
...
...
pkg/simple/client/kubesphere/devops.go
0 → 100644
浏览文件 @
5c4efd53
/*
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
kubesphere
import
(
"bytes"
"encoding/json"
"fmt"
"github.com/golang/glog"
"io/ioutil"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/models"
"net/http"
)
func
(
c
client
)
DeleteDevopsProject
(
username
string
,
projectId
string
)
error
{
request
,
_
:=
http
.
NewRequest
(
http
.
MethodDelete
,
fmt
.
Sprintf
(
"%s/api/v1alpha/projects/%s"
,
devopsAPIServer
,
projectId
),
nil
)
if
username
==
""
{
username
=
constants
.
AdminUserName
}
request
.
Header
.
Add
(
"X-Token-Username"
,
username
)
resp
,
err
:=
c
.
client
.
Do
(
request
)
if
err
!=
nil
{
return
err
}
defer
resp
.
Body
.
Close
()
data
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
err
}
if
resp
.
StatusCode
>
http
.
StatusOK
{
return
Error
{
resp
.
StatusCode
,
string
(
data
)}
}
return
nil
}
func
(
c
client
)
GetUserDevopsRole
(
username
string
,
projectId
string
)
(
string
,
error
)
{
if
username
==
"admin"
{
return
"owner"
,
nil
}
req
,
err
:=
http
.
NewRequest
(
http
.
MethodGet
,
fmt
.
Sprintf
(
"%s/api/v1alpha/projects/%s/members"
,
devopsAPIServer
,
projectId
),
nil
)
if
err
!=
nil
{
return
""
,
err
}
req
.
Header
.
Set
(
constants
.
UserNameHeader
,
username
)
resp
,
err
:=
c
.
client
.
Do
(
req
)
if
err
!=
nil
{
return
""
,
err
}
defer
resp
.
Body
.
Close
()
data
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
""
,
err
}
if
resp
.
StatusCode
>
http
.
StatusOK
{
return
""
,
Error
{
resp
.
StatusCode
,
string
(
data
)}
}
var
result
[]
map
[
string
]
string
err
=
json
.
Unmarshal
(
data
,
&
result
)
if
err
!=
nil
{
return
""
,
err
}
for
_
,
item
:=
range
result
{
if
item
[
"username"
]
==
username
{
return
item
[
"role"
],
nil
}
}
return
""
,
nil
}
func
(
c
client
)
CreateDevopsProject
(
username
string
,
project
*
models
.
DevopsProject
)
(
*
models
.
DevopsProject
,
error
)
{
data
,
err
:=
json
.
Marshal
(
project
)
if
err
!=
nil
{
return
nil
,
err
}
request
,
_
:=
http
.
NewRequest
(
http
.
MethodPost
,
fmt
.
Sprintf
(
"%s/api/v1alpha/projects"
,
devopsAPIServer
),
bytes
.
NewReader
(
data
))
request
.
Header
.
Add
(
"X-Token-Username"
,
username
)
request
.
Header
.
Add
(
"Content-Type"
,
"application/json"
)
resp
,
err
:=
c
.
client
.
Do
(
request
)
if
err
!=
nil
{
return
nil
,
err
}
defer
resp
.
Body
.
Close
()
data
,
err
=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
nil
,
err
}
if
resp
.
StatusCode
>
http
.
StatusOK
{
return
nil
,
Error
{
resp
.
StatusCode
,
string
(
data
)}
}
var
created
models
.
DevopsProject
err
=
json
.
Unmarshal
(
data
,
&
created
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
created
,
nil
}
func
(
c
client
)
CreateDevopsRoleBinding
(
projectId
string
,
user
string
,
role
string
)
{
projects
:=
make
([]
string
,
0
)
projects
=
append
(
projects
,
projectId
)
for
_
,
project
:=
range
projects
{
data
:=
[]
byte
(
fmt
.
Sprintf
(
`{"username":"%s","role":"%s"}`
,
user
,
role
))
request
,
_
:=
http
.
NewRequest
(
http
.
MethodPost
,
fmt
.
Sprintf
(
"%s/api/v1alpha/projects/%s/members"
,
devopsAPIServer
,
project
),
bytes
.
NewReader
(
data
))
request
.
Header
.
Add
(
"Content-Type"
,
"application/json"
)
request
.
Header
.
Add
(
"X-Token-Username"
,
"admin"
)
resp
,
err
:=
c
.
client
.
Do
(
request
)
if
err
!=
nil
||
resp
.
StatusCode
>
200
{
glog
.
Warning
(
fmt
.
Sprintf
(
"create devops role binding failed %s,%s,%s"
,
project
,
user
,
role
))
}
if
resp
!=
nil
{
resp
.
Body
.
Close
()
}
}
}
func
(
c
client
)
ListDevopsProjects
(
username
string
)
([]
models
.
DevopsProject
,
error
)
{
projects
:=
make
([]
models
.
DevopsProject
,
0
)
request
,
_
:=
http
.
NewRequest
(
http
.
MethodGet
,
fmt
.
Sprintf
(
"%s/api/v1alpha/projects"
,
devopsAPIServer
),
nil
)
request
.
Header
.
Add
(
constants
.
UserNameHeader
,
username
)
resp
,
err
:=
c
.
client
.
Do
(
request
)
if
err
!=
nil
{
return
nil
,
err
}
defer
resp
.
Body
.
Close
()
data
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
nil
,
err
}
if
resp
.
StatusCode
>
http
.
StatusOK
{
return
nil
,
Error
{
resp
.
StatusCode
,
string
(
data
)}
}
err
=
json
.
Unmarshal
(
data
,
&
projects
)
if
err
!=
nil
{
return
nil
,
err
}
return
projects
,
nil
}
pkg/simple/client/kubesphere/kubesphereclient.go
浏览文件 @
5c4efd53
...
@@ -32,6 +32,7 @@ import (
...
@@ -32,6 +32,7 @@ import (
var
(
var
(
accountAPIServer
string
accountAPIServer
string
devopsAPIServer
string
once
sync
.
Once
once
sync
.
Once
c
client
c
client
)
)
...
@@ -41,6 +42,11 @@ type Interface interface {
...
@@ -41,6 +42,11 @@ type Interface interface {
UpdateGroup
(
group
*
models
.
Group
)
(
*
models
.
Group
,
error
)
UpdateGroup
(
group
*
models
.
Group
)
(
*
models
.
Group
,
error
)
DescribeGroup
(
name
string
)
(
*
models
.
Group
,
error
)
DescribeGroup
(
name
string
)
(
*
models
.
Group
,
error
)
DeleteGroup
(
name
string
)
error
DeleteGroup
(
name
string
)
error
DeleteDevopsProject
(
username
string
,
projectId
string
)
error
GetUserDevopsRole
(
username
string
,
projectId
string
)
(
string
,
error
)
CreateDevopsProject
(
username
string
,
project
*
models
.
DevopsProject
)
(
*
models
.
DevopsProject
,
error
)
CreateDevopsRoleBinding
(
projectId
string
,
user
string
,
role
string
)
ListDevopsProjects
(
username
string
)
([]
models
.
DevopsProject
,
error
)
}
}
type
client
struct
{
type
client
struct
{
...
@@ -49,6 +55,7 @@ type client struct {
...
@@ -49,6 +55,7 @@ type client struct {
func
init
()
{
func
init
()
{
flag
.
StringVar
(
&
accountAPIServer
,
"ks-account-api-server"
,
"http://ks-account.kubesphere-system.svc"
,
"kubesphere account api server"
)
flag
.
StringVar
(
&
accountAPIServer
,
"ks-account-api-server"
,
"http://ks-account.kubesphere-system.svc"
,
"kubesphere account api server"
)
flag
.
StringVar
(
&
devopsAPIServer
,
"ks-devops-api-server"
,
"http://ks-devops.kubesphere-devops-system.svc"
,
"kubesphere devops api server"
)
}
}
func
Client
()
Interface
{
func
Client
()
Interface
{
...
...
pkg/simple/client/openpitrix/applications.go
浏览文件 @
5c4efd53
...
@@ -273,11 +273,10 @@ func makeHttpRequest(method, url, data string) ([]byte, error) {
...
@@ -273,11 +273,10 @@ func makeHttpRequest(method, url, data string) ([]byte, error) {
return
nil
,
err
return
nil
,
err
}
}
httpClient
:=
&
http
.
Client
{}
resp
,
err
:=
http
.
DefaultClient
.
Do
(
req
)
resp
,
err
:=
httpClient
.
Do
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Request to %s failed, method: %s,
reason: %s "
,
url
,
method
,
err
)
err
:=
fmt
.
Errorf
(
"Request to %s failed, method: %s,
token: %s, reason: %s "
,
url
,
method
,
openpitrixProxyToken
,
err
)
glog
.
Error
(
err
)
glog
.
Error
(
err
)
return
nil
,
err
return
nil
,
err
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录