Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
水淹萌龙
kubesphere
提交
1f26e621
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看板
未验证
提交
1f26e621
编写于
3月 20, 2020
作者:
H
hongming
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update
Signed-off-by:
N
hongming
<
talonwan@yunify.com
>
上级
97693570
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
359 addition
and
183 deletion
+359
-183
Makefile
Makefile
+1
-5
build/ks-apigateway/Dockerfile
build/ks-apigateway/Dockerfile
+0
-20
build/ks-iam/Dockerfile
build/ks-iam/Dockerfile
+0
-18
cmd/ks-apiserver/app/server.go
cmd/ks-apiserver/app/server.go
+2
-0
pkg/apiserver/apiserver.go
pkg/apiserver/apiserver.go
+1
-1
pkg/apiserver/authorization/authorizer/interfaces.go
pkg/apiserver/authorization/authorizer/interfaces.go
+0
-8
pkg/apiserver/authorization/authorizerfactory/opa.go
pkg/apiserver/authorization/authorizerfactory/opa.go
+21
-28
pkg/apiserver/authorization/authorizerfactory/opa_test.go
pkg/apiserver/authorization/authorizerfactory/opa_test.go
+63
-50
pkg/apiserver/config/config_test.go
pkg/apiserver/config/config_test.go
+1
-1
pkg/apiserver/filters/authorization.go
pkg/apiserver/filters/authorization.go
+0
-1
pkg/apiserver/request/requestinfo.go
pkg/apiserver/request/requestinfo.go
+92
-12
pkg/apiserver/request/requestinfo_test.go
pkg/apiserver/request/requestinfo_test.go
+88
-4
pkg/kapis/tenant/v1alpha2/handler.go
pkg/kapis/tenant/v1alpha2/handler.go
+3
-3
pkg/models/iam/am/am.go
pkg/models/iam/am/am.go
+4
-22
pkg/models/iam/am/fake_operator.go
pkg/models/iam/am/fake_operator.go
+73
-0
pkg/models/tenant/namespaces.go
pkg/models/tenant/namespaces.go
+4
-4
pkg/models/tenant/tenant.go
pkg/models/tenant/tenant.go
+3
-3
pkg/models/tenant/workspaces.go
pkg/models/tenant/workspaces.go
+3
-3
未找到文件。
Makefile
浏览文件 @
1f26e621
...
@@ -39,16 +39,12 @@ define ALL_HELP_INFO
...
@@ -39,16 +39,12 @@ define ALL_HELP_INFO
# debugging tools like delve.
# debugging tools like delve.
endef
endef
.PHONY
:
all
.PHONY
:
all
all
:
test hypersphere ks-apiserver
ks-apigateway
controller-manager
all
:
test hypersphere ks-apiserver controller-manager
# Build ks-apiserver binary
# Build ks-apiserver binary
ks-apiserver
:
fmt vet
ks-apiserver
:
fmt vet
hack/gobuild.sh cmd/ks-apiserver
hack/gobuild.sh cmd/ks-apiserver
# Build ks-apigateway binary
ks-apigateway
:
fmt vet
hack/gobuild.sh cmd/ks-apigateway
# Build controller-manager binary
# Build controller-manager binary
controller-manager
:
fmt vet
controller-manager
:
fmt vet
hack/gobuild.sh cmd/controller-manager
hack/gobuild.sh cmd/controller-manager
...
...
build/ks-apigateway/Dockerfile
已删除
100644 → 0
浏览文件 @
97693570
# Copyright 2018 The KubeSphere Authors. All rights reserved.
# Use of this source code is governed by a Apache license
# that can be found in the LICENSE file.
# Copyright 2018 The KubeSphere Authors. All rights reserved.
# Use of this source code is governed by a Apache license
# that can be found in the LICENSE file.
FROM
golang:1.12 as ks-apigateway-builder
COPY
/ /go/src/kubesphere.io/kubesphere
WORKDIR
/go/src/kubesphere.io/kubesphere
RUN
CGO_ENABLED
=
0
GO111MODULE
=
on
GOOS
=
linux
GOARCH
=
amd64
GOFLAGS
=
-mod
=
vendor go build
-i
-ldflags
'-w -s'
-o
ks-apigateway cmd/ks-apigateway/apiserver.go
&&
\
go run tools/cmd/doc-gen/main.go
--output
=
install
/swagger-ui/api.json
FROM
alpine:3.9
RUN
apk add
--update
ca-certificates
&&
update-ca-certificates
COPY
--from=ks-apigateway-builder /go/src/kubesphere.io/kubesphere/ks-apigateway /usr/local/bin/
COPY
--from=ks-apigateway-builder /go/src/kubesphere.io/kubesphere/install/swagger-ui /var/static/swagger-ui
CMD
["sh"]
build/ks-iam/Dockerfile
已删除
100644 → 0
浏览文件 @
97693570
# Copyright 2018 The KubeSphere Authors. All rights reserved.
# Use of this source code is governed by a Apache license
# that can be found in the LICENSE file.
# Copyright 2018 The KubeSphere Authors. All rights reserved.
# Use of this source code is governed by a Apache license
# that can be found in the LICENSE file.
FROM
golang:1.12 as ks-iam-builder
COPY
/ /go/src/kubesphere.io/kubesphere
WORKDIR
/go/src/kubesphere.io/kubesphere
RUN
CGO_ENABLED
=
0
GO111MODULE
=
on
GOOS
=
linux
GOARCH
=
amd64
GOFLAGS
=
-mod
=
vendor go build
-i
-ldflags
'-w -s'
-o
ks-iam cmd/ks-iam/apiserver.go
FROM
alpine:3.9
RUN
apk add
--update
ca-certificates
&&
update-ca-certificates
COPY
--from=ks-iam-builder /go/src/kubesphere.io/kubesphere/ks-iam /usr/local/bin/
CMD
["sh"]
cmd/ks-apiserver/app/server.go
浏览文件 @
1f26e621
...
@@ -46,6 +46,8 @@ func NewAPIServerCommand() *cobra.Command {
...
@@ -46,6 +46,8 @@ func NewAPIServerCommand() *cobra.Command {
S3Options
:
conf
.
S3Options
,
S3Options
:
conf
.
S3Options
,
OpenPitrixOptions
:
conf
.
OpenPitrixOptions
,
OpenPitrixOptions
:
conf
.
OpenPitrixOptions
,
LoggingOptions
:
conf
.
LoggingOptions
,
LoggingOptions
:
conf
.
LoggingOptions
,
LdapOptions
:
conf
.
LdapOptions
,
CacheOptions
:
conf
.
RedisOptions
,
AuthenticateOptions
:
conf
.
AuthenticateOptions
,
AuthenticateOptions
:
conf
.
AuthenticateOptions
,
}
}
}
}
...
...
pkg/apiserver/apiserver.go
浏览文件 @
1f26e621
...
@@ -187,7 +187,7 @@ func (s *APIServer) buildHandlerChain() {
...
@@ -187,7 +187,7 @@ func (s *APIServer) buildHandlerChain() {
excludedPaths
:=
[]
string
{
"/oauth/authorize"
,
"/oauth/token"
}
excludedPaths
:=
[]
string
{
"/oauth/authorize"
,
"/oauth/token"
}
pathAuthorizer
,
_
:=
path
.
NewAuthorizer
(
excludedPaths
)
pathAuthorizer
,
_
:=
path
.
NewAuthorizer
(
excludedPaths
)
authorizer
:=
unionauthorizer
.
New
(
pathAuthorizer
,
authorizerfactory
.
NewOPAAuthorizer
(
am
.
New
AMOperator
(
s
.
KubernetesClient
.
Kubernetes
(),
s
.
InformerFactory
.
KubernetesSharedInformerFactory
())))
authorizer
:=
unionauthorizer
.
New
(
pathAuthorizer
,
authorizerfactory
.
NewOPAAuthorizer
(
am
.
New
FakeAMOperator
(
cache
.
NewSimpleCache
())))
handler
=
filters
.
WithAuthorization
(
handler
,
authorizer
)
handler
=
filters
.
WithAuthorization
(
handler
,
authorizer
)
handler
=
filters
.
WithMultipleClusterDispatcher
(
handler
,
dispatch
.
DefaultClusterDispatch
)
handler
=
filters
.
WithMultipleClusterDispatcher
(
handler
,
dispatch
.
DefaultClusterDispatch
)
handler
=
filters
.
WithKubeAPIServer
(
handler
,
s
.
KubernetesClient
.
Config
(),
&
errorResponder
{})
handler
=
filters
.
WithKubeAPIServer
(
handler
,
s
.
KubernetesClient
.
Config
(),
&
errorResponder
{})
...
...
pkg/apiserver/authorization/authorizer/interfaces.go
浏览文件 @
1f26e621
...
@@ -48,9 +48,6 @@ type Attributes interface {
...
@@ -48,9 +48,6 @@ type Attributes interface {
// The namespace of the object, if a request is for a REST object.
// The namespace of the object, if a request is for a REST object.
GetNamespace
()
string
GetNamespace
()
string
// The devops project of the object, if a request is for a REST object.
GetDevopsProject
()
string
// The kind of object, if a request is for a REST object.
// The kind of object, if a request is for a REST object.
GetResource
()
string
GetResource
()
string
...
@@ -106,7 +103,6 @@ type AttributesRecord struct {
...
@@ -106,7 +103,6 @@ type AttributesRecord struct {
Cluster
string
Cluster
string
Workspace
string
Workspace
string
Namespace
string
Namespace
string
DevopsProject
string
APIGroup
string
APIGroup
string
APIVersion
string
APIVersion
string
Resource
string
Resource
string
...
@@ -141,10 +137,6 @@ func (a AttributesRecord) GetNamespace() string {
...
@@ -141,10 +137,6 @@ func (a AttributesRecord) GetNamespace() string {
return
a
.
Namespace
return
a
.
Namespace
}
}
func
(
a
AttributesRecord
)
GetDevopsProject
()
string
{
return
a
.
DevopsProject
}
func
(
a
AttributesRecord
)
GetResource
()
string
{
func
(
a
AttributesRecord
)
GetResource
()
string
{
return
a
.
Resource
return
a
.
Resource
}
}
...
...
pkg/apiserver/authorization/authorizerfactory/opa.go
浏览文件 @
1f26e621
...
@@ -22,79 +22,68 @@ import (
...
@@ -22,79 +22,68 @@ import (
"context"
"context"
"github.com/open-policy-agent/opa/rego"
"github.com/open-policy-agent/opa/rego"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
am2
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/am"
)
)
type
opaAuthorizer
struct
{
type
opaAuthorizer
struct
{
am
am
2
.
AccessManagementInterface
am
am
.
AccessManagementInterface
}
}
func
(
o
*
opaAuthorizer
)
Authorize
(
a
authorizer
.
Attributes
)
(
authorized
authorizer
.
Decision
,
reason
string
,
err
error
)
{
func
(
o
*
opaAuthorizer
)
Authorize
(
a
ttr
authorizer
.
Attributes
)
(
authorized
authorizer
.
Decision
,
reason
string
,
err
error
)
{
platformRole
,
err
:=
o
.
am
.
GetPlatformRole
(
a
.
GetUser
()
.
GetName
())
platformRole
,
err
:=
o
.
am
.
GetPlatformRole
(
a
ttr
.
GetUser
()
.
GetName
())
if
err
!=
nil
{
if
err
!=
nil
{
return
authorizer
.
DecisionDeny
,
""
,
err
return
authorizer
.
DecisionDeny
,
""
,
err
}
}
// check platform role policy rules
// check platform role policy rules
if
a
,
r
,
e
:=
o
.
roleAuthorize
(
platformRole
,
a
);
a
==
authorizer
.
DecisionAllow
{
if
a
,
r
,
e
:=
makeDecision
(
platformRole
,
attr
);
a
==
authorizer
.
DecisionAllow
{
return
a
,
r
,
e
return
a
,
r
,
e
}
}
// it's not in cluster resource, permission denied
// it's not in cluster resource, permission denied
// TODO declare implicit cluster info in request Info
// TODO declare implicit cluster info in request Info
if
a
.
GetCluster
()
==
""
{
if
a
ttr
.
GetCluster
()
==
""
{
return
authorizer
.
DecisionDeny
,
"permission undefined"
,
nil
return
authorizer
.
DecisionDeny
,
"permission undefined"
,
nil
}
}
clusterRole
,
err
:=
o
.
am
.
GetClusterRole
(
a
.
GetCluster
(),
a
.
GetUser
()
.
GetName
())
clusterRole
,
err
:=
o
.
am
.
GetClusterRole
(
a
ttr
.
GetCluster
(),
attr
.
GetUser
()
.
GetName
())
if
err
!=
nil
{
if
err
!=
nil
{
return
authorizer
.
DecisionDeny
,
""
,
err
return
authorizer
.
DecisionDeny
,
""
,
err
}
}
// check cluster role policy rules
// check cluster role policy rules
if
a
,
r
,
e
:=
o
.
roleAuthorize
(
clusterRole
,
a
);
a
==
authorizer
.
DecisionAllow
{
if
a
,
r
,
e
:=
makeDecision
(
clusterRole
,
attr
);
a
==
authorizer
.
DecisionAllow
{
return
a
,
r
,
e
return
a
,
r
,
e
}
}
// it's not in cluster resource, permission denied
// it's not in cluster resource, permission denied
if
a
.
GetWorkspace
()
==
""
&&
a
.
GetNamespace
()
==
""
&&
a
.
GetDevopsProject
()
==
""
{
if
a
ttr
.
GetWorkspace
()
==
""
&&
attr
.
GetNamespace
()
==
""
{
return
authorizer
.
DecisionDeny
,
"permission undefined"
,
nil
return
authorizer
.
DecisionDeny
,
"permission undefined"
,
nil
}
}
workspaceRole
,
err
:=
o
.
am
.
GetWorkspaceRole
(
a
.
GetWorkspace
(),
a
.
GetUser
()
.
GetName
())
workspaceRole
,
err
:=
o
.
am
.
GetWorkspaceRole
(
a
ttr
.
GetWorkspace
(),
attr
.
GetUser
()
.
GetName
())
if
err
!=
nil
{
if
err
!=
nil
{
return
authorizer
.
DecisionDeny
,
""
,
err
return
authorizer
.
DecisionDeny
,
""
,
err
}
}
// check workspace role policy rules
// check workspace role policy rules
if
a
,
r
,
e
:=
o
.
roleAuthorize
(
workspaceRole
,
a
);
a
==
authorizer
.
DecisionAllow
{
if
a
,
r
,
e
:=
makeDecision
(
workspaceRole
,
attr
);
a
==
authorizer
.
DecisionAllow
{
return
a
,
r
,
e
return
a
,
r
,
e
}
}
// it's not in workspace resource, permission denied
// it's not in workspace resource, permission denied
if
a
.
GetNamespace
()
==
""
&&
a
.
GetDevopsProject
()
==
""
{
if
a
ttr
.
GetNamespace
()
==
""
{
return
authorizer
.
DecisionDeny
,
"permission undefined"
,
nil
return
authorizer
.
DecisionDeny
,
"permission undefined"
,
nil
}
}
if
a
.
GetNamespace
()
!=
""
{
if
a
ttr
.
GetNamespace
()
!=
""
{
namespaceRole
,
err
:=
o
.
am
.
GetNamespaceRole
(
a
.
GetNamespace
(),
a
.
GetUser
()
.
GetName
())
namespaceRole
,
err
:=
o
.
am
.
GetNamespaceRole
(
a
ttr
.
GetNamespace
(),
attr
.
GetUser
()
.
GetName
())
if
err
!=
nil
{
if
err
!=
nil
{
return
authorizer
.
DecisionDeny
,
""
,
err
return
authorizer
.
DecisionDeny
,
""
,
err
}
}
// check namespace role policy rules
// check namespace role policy rules
if
a
,
r
,
e
:=
o
.
roleAuthorize
(
namespaceRole
,
a
);
a
==
authorizer
.
DecisionAllow
{
if
a
,
r
,
e
:=
makeDecision
(
namespaceRole
,
attr
);
a
==
authorizer
.
DecisionAllow
{
return
a
,
r
,
e
}
}
if
a
.
GetDevopsProject
()
!=
""
{
devOpsRole
,
err
:=
o
.
am
.
GetDevOpsRole
(
a
.
GetNamespace
(),
a
.
GetUser
()
.
GetName
())
if
err
!=
nil
{
return
authorizer
.
DecisionDeny
,
""
,
err
}
// check devops role policy rules
if
a
,
r
,
e
:=
o
.
roleAuthorize
(
devOpsRole
,
a
);
a
==
authorizer
.
DecisionAllow
{
return
a
,
r
,
e
return
a
,
r
,
e
}
}
}
}
...
@@ -102,14 +91,18 @@ func (o *opaAuthorizer) Authorize(a authorizer.Attributes) (authorized authorize
...
@@ -102,14 +91,18 @@ func (o *opaAuthorizer) Authorize(a authorizer.Attributes) (authorized authorize
return
authorizer
.
DecisionDeny
,
""
,
nil
return
authorizer
.
DecisionDeny
,
""
,
nil
}
}
func
(
o
*
opaAuthorizer
)
roleAuthorize
(
role
am2
.
Role
,
a
authorizer
.
Attributes
)
(
authorized
authorizer
.
Decision
,
reason
string
,
err
error
)
{
// Make decision base on role
func
makeDecision
(
role
am
.
Role
,
a
authorizer
.
Attributes
)
(
authorized
authorizer
.
Decision
,
reason
string
,
err
error
)
{
// Call the rego.New function to create an object that can be prepared or evaluated
// After constructing a new rego.Rego object you can call PrepareForEval() to obtain an executable query
query
,
err
:=
rego
.
New
(
rego
.
Query
(
"data.authz.allow"
),
rego
.
Module
(
"authz.rego"
,
role
.
GetRego
()))
.
PrepareForEval
(
context
.
Background
())
query
,
err
:=
rego
.
New
(
rego
.
Query
(
"data.authz.allow"
),
rego
.
Module
(
"authz.rego"
,
role
.
GetRego
()))
.
PrepareForEval
(
context
.
Background
())
if
err
!=
nil
{
if
err
!=
nil
{
return
authorizer
.
DecisionDeny
,
""
,
err
return
authorizer
.
DecisionDeny
,
""
,
err
}
}
// The policy decision is contained in the results returned by the Eval() call. You can inspect the decision and handle it accordingly.
results
,
err
:=
query
.
Eval
(
context
.
Background
(),
rego
.
EvalInput
(
a
))
results
,
err
:=
query
.
Eval
(
context
.
Background
(),
rego
.
EvalInput
(
a
))
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -123,6 +116,6 @@ func (o *opaAuthorizer) roleAuthorize(role am2.Role, a authorizer.Attributes) (a
...
@@ -123,6 +116,6 @@ func (o *opaAuthorizer) roleAuthorize(role am2.Role, a authorizer.Attributes) (a
return
authorizer
.
DecisionDeny
,
"permission undefined"
,
nil
return
authorizer
.
DecisionDeny
,
"permission undefined"
,
nil
}
}
func
NewOPAAuthorizer
(
am
am
2
.
AccessManagementInterface
)
*
opaAuthorizer
{
func
NewOPAAuthorizer
(
am
am
.
AccessManagementInterface
)
*
opaAuthorizer
{
return
&
opaAuthorizer
{
am
:
am
}
return
&
opaAuthorizer
{
am
:
am
}
}
}
pkg/apiserver/authorization/authorizerfactory/opa_test.go
浏览文件 @
1f26e621
...
@@ -19,66 +19,79 @@
...
@@ -19,66 +19,79 @@
package
authorizerfactory
package
authorizerfactory
import
(
import
(
"context"
"github.com/open-policy-agent/opa/rego"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authentication/user"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
"testing"
"testing"
)
)
func
TestPlatformRole
(
t
*
testing
.
T
)
{
func
TestPlatformRole
(
t
*
testing
.
T
)
{
module
:=
`package platform.authz
opa
:=
NewOPAAuthorizer
(
am
.
NewFakeAMOperator
(
cache
.
NewSimpleCache
()))
default allow = false
allow {
tests
:=
[]
struct
{
input.User.name == "admin"
name
string
}
request
authorizer
.
AttributesRecord
expectedDecision
authorizer
.
Decision
allow {
}{
is_admin
{
}
name
:
"list nodes"
,
request
:
authorizer
.
AttributesRecord
{
is_admin {
User
:
&
user
.
DefaultInfo
{
input.User.Groups[_] == "admin"
Name
:
"admin"
,
}
UID
:
"0"
,
`
Groups
:
[]
string
{
"admin"
},
query
,
err
:=
rego
.
New
(
rego
.
Query
(
"data.authz.allow"
),
rego
.
Module
(
"authz.rego"
,
module
))
.
PrepareForEval
(
context
.
Background
())
Extra
:
nil
,
if
err
!=
nil
{
},
t
.
Fatal
(
err
)
Verb
:
"list"
,
}
Cluster
:
""
,
Workspace
:
""
,
input
:=
authorizer
.
AttributesRecord
{
Namespace
:
""
,
User
:
&
user
.
DefaultInfo
{
APIGroup
:
""
,
Name
:
"admin"
,
APIVersion
:
"v1"
,
UID
:
"0"
,
Resource
:
"nodes"
,
Groups
:
[]
string
{
"admin"
},
Subresource
:
""
,
Extra
:
nil
,
Name
:
""
,
KubernetesRequest
:
true
,
ResourceRequest
:
true
,
Path
:
"/api/v1/nodes"
,
},
expectedDecision
:
authorizer
.
DecisionAllow
,
},
{
name
:
"list nodes"
,
request
:
authorizer
.
AttributesRecord
{
User
:
&
user
.
DefaultInfo
{
Name
:
user
.
Anonymous
,
UID
:
"0"
,
Groups
:
[]
string
{
"admin"
},
Extra
:
nil
,
},
Verb
:
"list"
,
Cluster
:
""
,
Workspace
:
""
,
Namespace
:
""
,
APIGroup
:
""
,
APIVersion
:
"v1"
,
Resource
:
"nodes"
,
Subresource
:
""
,
Name
:
""
,
KubernetesRequest
:
true
,
ResourceRequest
:
true
,
Path
:
"/api/v1/nodes"
,
},
expectedDecision
:
authorizer
.
DecisionDeny
,
},
},
Verb
:
"list"
,
Cluster
:
""
,
Workspace
:
""
,
Namespace
:
""
,
DevopsProject
:
""
,
APIGroup
:
""
,
APIVersion
:
"v1"
,
Resource
:
"nodes"
,
Subresource
:
""
,
Name
:
""
,
KubernetesRequest
:
true
,
ResourceRequest
:
true
,
Path
:
"/api/v1/nodes"
,
}
results
,
err
:=
query
.
Eval
(
context
.
Background
(),
rego
.
EvalInput
(
input
))
if
err
!=
nil
{
t
.
Log
(
err
)
}
}
if
len
(
results
)
>
0
&&
results
[
0
]
.
Expressions
[
0
]
.
Value
==
true
{
for
_
,
test
:=
range
tests
{
t
.
Log
(
"allowed"
)
decision
,
_
,
err
:=
opa
.
Authorize
(
test
.
request
)
}
else
{
if
err
!=
nil
{
t
.
Log
(
"deny"
)
t
.
Error
(
err
)
}
if
decision
!=
test
.
expectedDecision
{
t
.
Errorf
(
"%s: expected decision %v, actual %+v"
,
test
.
name
,
test
.
expectedDecision
,
decision
)
}
}
}
}
}
pkg/apiserver/config/config_test.go
浏览文件 @
1f26e621
...
@@ -64,7 +64,7 @@ func newTestConfig() *Config {
...
@@ -64,7 +64,7 @@ func newTestConfig() *Config {
GroupSearchBase
:
"ou=Groups,dc=example,dc=org"
,
GroupSearchBase
:
"ou=Groups,dc=example,dc=org"
,
},
},
RedisOptions
:
&
cache
.
Options
{
RedisOptions
:
&
cache
.
Options
{
Host
:
"localhost
:6379
"
,
Host
:
"localhost"
,
Port
:
6379
,
Port
:
6379
,
Password
:
"P@88w0rd"
,
Password
:
"P@88w0rd"
,
DB
:
0
,
DB
:
0
,
...
...
pkg/apiserver/filters/authorization.go
浏览文件 @
1f26e621
...
@@ -68,7 +68,6 @@ func GetAuthorizerAttributes(ctx context.Context) (authorizer.Attributes, error)
...
@@ -68,7 +68,6 @@ func GetAuthorizerAttributes(ctx context.Context) (authorizer.Attributes, error)
attribs
.
Resource
=
requestInfo
.
Resource
attribs
.
Resource
=
requestInfo
.
Resource
attribs
.
Subresource
=
requestInfo
.
Subresource
attribs
.
Subresource
=
requestInfo
.
Subresource
attribs
.
Namespace
=
requestInfo
.
Namespace
attribs
.
Namespace
=
requestInfo
.
Namespace
attribs
.
DevopsProject
=
requestInfo
.
DevopsProject
attribs
.
Name
=
requestInfo
.
Name
attribs
.
Name
=
requestInfo
.
Name
return
&
attribs
,
nil
return
&
attribs
,
nil
...
...
pkg/apiserver/request/requestinfo.go
浏览文件 @
1f26e621
...
@@ -3,7 +3,11 @@ package request
...
@@ -3,7 +3,11 @@ package request
import
(
import
(
"context"
"context"
"fmt"
"fmt"
"k8s.io/apimachinery/pkg/api/validation/path"
metainternalversion
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog"
"net/http"
"net/http"
"strings"
"strings"
...
@@ -19,6 +23,13 @@ type RequestInfoResolver interface {
...
@@ -19,6 +23,13 @@ type RequestInfoResolver interface {
// master's Mux.
// master's Mux.
var
specialVerbs
=
sets
.
NewString
(
"proxy"
,
"watch"
)
var
specialVerbs
=
sets
.
NewString
(
"proxy"
,
"watch"
)
// specialVerbsNoSubresources contains root verbs which do not allow subresources
var
specialVerbsNoSubresources
=
sets
.
NewString
(
"proxy"
)
// namespaceSubresources contains subresources of namespace
// this list allows the parser to distinguish between a namespace subresource, and a namespaced resource
var
namespaceSubresources
=
sets
.
NewString
(
"status"
,
"finalize"
)
var
kubernetesAPIPrefixes
=
sets
.
NewString
(
"api"
,
"apis"
)
var
kubernetesAPIPrefixes
=
sets
.
NewString
(
"api"
,
"apis"
)
// RequestInfo holds information parsed from the http.Request,
// RequestInfo holds information parsed from the http.Request,
...
@@ -34,9 +45,6 @@ type RequestInfo struct {
...
@@ -34,9 +45,6 @@ type RequestInfo struct {
// Cluster of requested resource, this is empty in single-cluster environment
// Cluster of requested resource, this is empty in single-cluster environment
Cluster
string
Cluster
string
// Devops project of requested resource, this may be empty
DevopsProject
string
}
}
type
RequestInfoFactory
struct
{
type
RequestInfoFactory
struct
{
...
@@ -101,16 +109,9 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
...
@@ -101,16 +109,9 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
currentParts
=
currentParts
[
1
:
]
currentParts
=
currentParts
[
1
:
]
if
!
r
.
GrouplessAPIPrefixes
.
Has
(
requestInfo
.
APIPrefix
)
{
if
!
r
.
GrouplessAPIPrefixes
.
Has
(
requestInfo
.
APIPrefix
)
{
if
len
(
currentParts
)
<
2
{
// one part (APIPrefix) has already been consumed, so this is actually "do we have four parts?"
return
&
requestInfo
,
nil
}
if
currentParts
[
0
]
==
"clusters"
{
requestInfo
.
Cluster
=
currentParts
[
1
]
currentParts
=
currentParts
[
2
:
]
}
if
len
(
currentParts
)
<
3
{
if
len
(
currentParts
)
<
3
{
// return a non-resource request
return
&
requestInfo
,
nil
return
&
requestInfo
,
nil
}
}
...
@@ -122,6 +123,18 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
...
@@ -122,6 +123,18 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
requestInfo
.
APIVersion
=
currentParts
[
0
]
requestInfo
.
APIVersion
=
currentParts
[
0
]
currentParts
=
currentParts
[
1
:
]
currentParts
=
currentParts
[
1
:
]
if
currentParts
[
0
]
==
"clusters"
{
requestInfo
.
Cluster
=
currentParts
[
1
]
currentParts
=
currentParts
[
2
:
]
}
else
if
len
(
currentParts
)
>
0
{
requestInfo
.
Cluster
=
"host-cluster"
}
if
currentParts
[
0
]
==
"workspaces"
{
requestInfo
.
Workspace
=
currentParts
[
1
]
currentParts
=
currentParts
[
2
:
]
}
if
specialVerbs
.
Has
(
currentParts
[
0
])
{
if
specialVerbs
.
Has
(
currentParts
[
0
])
{
if
len
(
currentParts
)
<
2
{
if
len
(
currentParts
)
<
2
{
return
&
requestInfo
,
fmt
.
Errorf
(
"unable to determine kind and namespace from url: %v"
,
req
.
URL
)
return
&
requestInfo
,
fmt
.
Errorf
(
"unable to determine kind and namespace from url: %v"
,
req
.
URL
)
...
@@ -146,6 +159,73 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
...
@@ -146,6 +159,73 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
}
}
}
}
// URL forms: /namespaces/{namespace}/{kind}/*, where parts are adjusted to be relative to kind
if
currentParts
[
0
]
==
"namespaces"
{
if
len
(
currentParts
)
>
1
{
requestInfo
.
Namespace
=
currentParts
[
1
]
// if there is another step after the namespace name and it is not a known namespace subresource
// move currentParts to include it as a resource in its own right
if
len
(
currentParts
)
>
2
&&
!
namespaceSubresources
.
Has
(
currentParts
[
2
])
{
currentParts
=
currentParts
[
2
:
]
}
}
}
else
{
requestInfo
.
Namespace
=
metav1
.
NamespaceNone
}
// parsing successful, so we now know the proper value for .Parts
requestInfo
.
Parts
=
currentParts
// parts look like: resource/resourceName/subresource/other/stuff/we/don't/interpret
switch
{
case
len
(
requestInfo
.
Parts
)
>=
3
&&
!
specialVerbsNoSubresources
.
Has
(
requestInfo
.
Verb
)
:
requestInfo
.
Subresource
=
requestInfo
.
Parts
[
2
]
fallthrough
case
len
(
requestInfo
.
Parts
)
>=
2
:
requestInfo
.
Name
=
requestInfo
.
Parts
[
1
]
fallthrough
case
len
(
requestInfo
.
Parts
)
>=
1
:
requestInfo
.
Resource
=
requestInfo
.
Parts
[
0
]
}
// if there's no name on the request and we thought it was a get before, then the actual verb is a list or a watch
if
len
(
requestInfo
.
Name
)
==
0
&&
requestInfo
.
Verb
==
"get"
{
opts
:=
metainternalversion
.
ListOptions
{}
if
err
:=
metainternalversion
.
ParameterCodec
.
DecodeParameters
(
req
.
URL
.
Query
(),
metav1
.
SchemeGroupVersion
,
&
opts
);
err
!=
nil
{
// An error in parsing request will result in default to "list" and not setting "name" field.
klog
.
Errorf
(
"Couldn't parse request %#v: %v"
,
req
.
URL
.
Query
(),
err
)
// Reset opts to not rely on partial results from parsing.
// However, if watch is set, let's report it.
opts
=
metainternalversion
.
ListOptions
{}
if
values
:=
req
.
URL
.
Query
()[
"watch"
];
len
(
values
)
>
0
{
switch
strings
.
ToLower
(
values
[
0
])
{
case
"false"
,
"0"
:
default
:
opts
.
Watch
=
true
}
}
}
if
opts
.
Watch
{
requestInfo
.
Verb
=
"watch"
}
else
{
requestInfo
.
Verb
=
"list"
}
if
opts
.
FieldSelector
!=
nil
{
if
name
,
ok
:=
opts
.
FieldSelector
.
RequiresExactMatch
(
"metadata.name"
);
ok
{
if
len
(
path
.
IsValidPathSegmentName
(
name
))
==
0
{
requestInfo
.
Name
=
name
}
}
}
}
// if there's no name on the request and we thought it was a delete before, then the actual verb is deletecollection
if
len
(
requestInfo
.
Name
)
==
0
&&
requestInfo
.
Verb
==
"delete"
{
requestInfo
.
Verb
=
"deletecollection"
}
return
&
requestInfo
,
nil
return
&
requestInfo
,
nil
}
}
...
...
pkg/apiserver/request/requestinfo_test.go
浏览文件 @
1f26e621
...
@@ -43,6 +43,8 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) {
...
@@ -43,6 +43,8 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) {
expectedResource
string
expectedResource
string
expectedIsResourceRequest
bool
expectedIsResourceRequest
bool
expectedCluster
string
expectedCluster
string
expectedWorkspace
string
exceptedNamespace
string
}{
}{
{
{
name
:
"login"
,
name
:
"login"
,
...
@@ -54,15 +56,88 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) {
...
@@ -54,15 +56,88 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) {
expectedIsResourceRequest
:
false
,
expectedIsResourceRequest
:
false
,
expectedCluster
:
""
,
expectedCluster
:
""
,
},
},
{
name
:
"list cluster roles"
,
url
:
"/apis/rbac.authorization.k8s.io/v1/clusters/cluster1/clusterroles"
,
method
:
http
.
MethodGet
,
expectedErr
:
nil
,
expectedVerb
:
"list"
,
expectedResource
:
"clusterroles"
,
expectedIsResourceRequest
:
true
,
expectedCluster
:
"cluster1"
,
},
{
name
:
"list cluster nodes"
,
url
:
"/api/v1/clusters/cluster1/nodes"
,
method
:
http
.
MethodGet
,
expectedErr
:
nil
,
expectedVerb
:
"list"
,
expectedResource
:
"nodes"
,
expectedIsResourceRequest
:
true
,
expectedCluster
:
"cluster1"
,
},
{
name
:
"list cluster nodes"
,
url
:
"/api/v1/clusters/cluster1/nodes"
,
method
:
http
.
MethodGet
,
expectedErr
:
nil
,
expectedVerb
:
"list"
,
expectedResource
:
"nodes"
,
expectedIsResourceRequest
:
true
,
expectedCluster
:
"cluster1"
,
},
{
name
:
"list cluster nodes"
,
url
:
"/api/v1/nodes"
,
method
:
http
.
MethodGet
,
expectedErr
:
nil
,
expectedVerb
:
"list"
,
expectedResource
:
"nodes"
,
expectedIsResourceRequest
:
true
,
expectedCluster
:
"host-cluster"
,
},
{
name
:
"list roles"
,
url
:
"/apis/rbac.authorization.k8s.io/v1/clusters/cluster1/namespaces/namespace1/roles"
,
method
:
http
.
MethodGet
,
expectedErr
:
nil
,
expectedVerb
:
"list"
,
expectedResource
:
"roles"
,
expectedIsResourceRequest
:
true
,
exceptedNamespace
:
"namespace1"
,
expectedCluster
:
"cluster1"
,
},
{
name
:
"list roles"
,
url
:
"/apis/rbac.authorization.k8s.io/v1/namespaces/namespace1/roles"
,
method
:
http
.
MethodGet
,
expectedErr
:
nil
,
expectedVerb
:
"list"
,
expectedResource
:
"roles"
,
expectedIsResourceRequest
:
true
,
expectedCluster
:
"host-cluster"
,
},
{
{
name
:
"list namespaces"
,
name
:
"list namespaces"
,
url
:
"/kapis/resources.kubesphere.io/v1alpha
2
/namespaces"
,
url
:
"/kapis/resources.kubesphere.io/v1alpha
3/workspaces/workspace1
/namespaces"
,
method
:
http
.
MethodGet
,
method
:
http
.
MethodGet
,
expectedErr
:
nil
,
expectedErr
:
nil
,
expectedVerb
:
"list"
,
expectedVerb
:
"list"
,
expectedResource
:
"namespaces"
,
expectedResource
:
"namespaces"
,
expectedIsResourceRequest
:
true
,
expectedIsResourceRequest
:
true
,
expectedCluster
:
""
,
expectedWorkspace
:
"workspace1"
,
expectedCluster
:
"host-cluster"
,
},
{
name
:
"list namespaces"
,
url
:
"/kapis/resources.kubesphere.io/v1alpha3/clusters/cluster1/workspaces/workspace1/namespaces"
,
method
:
http
.
MethodGet
,
expectedErr
:
nil
,
expectedVerb
:
"list"
,
expectedResource
:
"namespaces"
,
expectedIsResourceRequest
:
true
,
expectedWorkspace
:
"workspace1"
,
expectedCluster
:
"cluster1"
,
},
},
}
}
...
@@ -80,15 +155,24 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) {
...
@@ -80,15 +155,24 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) {
t
.
Errorf
(
"%s: expected error %v, actual %v"
,
test
.
name
,
test
.
expectedErr
,
err
)
t
.
Errorf
(
"%s: expected error %v, actual %v"
,
test
.
name
,
test
.
expectedErr
,
err
)
}
}
}
else
{
}
else
{
if
test
.
expectedVerb
!=
requestInfo
.
Verb
{
if
test
.
expectedVerb
!=
""
&&
test
.
expectedVerb
!=
requestInfo
.
Verb
{
t
.
Errorf
(
"%s: expected verb %v, actual %+v"
,
test
.
name
,
test
.
expectedVerb
,
requestInfo
.
Verb
)
t
.
Errorf
(
"%s: expected verb %v, actual %+v"
,
test
.
name
,
test
.
expectedVerb
,
requestInfo
.
Verb
)
}
}
if
test
.
expectedResource
!=
requestInfo
.
Resource
{
if
test
.
expectedResource
!=
""
&&
test
.
expectedResource
!=
requestInfo
.
Resource
{
t
.
Errorf
(
"%s: expected resource %v, actual %+v"
,
test
.
name
,
test
.
expectedResource
,
requestInfo
.
Resource
)
t
.
Errorf
(
"%s: expected resource %v, actual %+v"
,
test
.
name
,
test
.
expectedResource
,
requestInfo
.
Resource
)
}
}
if
test
.
expectedIsResourceRequest
!=
requestInfo
.
IsResourceRequest
{
if
test
.
expectedIsResourceRequest
!=
requestInfo
.
IsResourceRequest
{
t
.
Errorf
(
"%s: expected is resource request %v, actual %+v"
,
test
.
name
,
test
.
expectedIsResourceRequest
,
requestInfo
.
IsResourceRequest
)
t
.
Errorf
(
"%s: expected is resource request %v, actual %+v"
,
test
.
name
,
test
.
expectedIsResourceRequest
,
requestInfo
.
IsResourceRequest
)
}
}
if
test
.
expectedCluster
!=
""
&&
test
.
expectedCluster
!=
requestInfo
.
Cluster
{
t
.
Errorf
(
"%s: expected cluster %v, actual %+v"
,
test
.
name
,
test
.
expectedCluster
,
requestInfo
.
Cluster
)
}
if
test
.
expectedWorkspace
!=
""
&&
test
.
expectedWorkspace
!=
requestInfo
.
Workspace
{
t
.
Errorf
(
"%s: expected workspace %v, actual %+v"
,
test
.
name
,
test
.
expectedWorkspace
,
requestInfo
.
Workspace
)
}
if
test
.
exceptedNamespace
!=
""
&&
test
.
exceptedNamespace
!=
requestInfo
.
Namespace
{
t
.
Errorf
(
"%s: expected namespace %v, actual %+v"
,
test
.
name
,
test
.
exceptedNamespace
,
requestInfo
.
Namespace
)
}
}
}
}
}
}
}
pkg/kapis/tenant/v1alpha2/handler.go
浏览文件 @
1f26e621
...
@@ -8,7 +8,7 @@ import (
...
@@ -8,7 +8,7 @@ import (
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/informers"
am2
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/monitoring"
"kubesphere.io/kubesphere/pkg/models/monitoring"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/models/tenant"
"kubesphere.io/kubesphere/pkg/models/tenant"
...
@@ -21,14 +21,14 @@ import (
...
@@ -21,14 +21,14 @@ import (
type
tenantHandler
struct
{
type
tenantHandler
struct
{
tenant
tenant
.
Interface
tenant
tenant
.
Interface
am
am
2
.
AccessManagementInterface
am
am
.
AccessManagementInterface
}
}
func
newTenantHandler
(
k8sClient
k8s
.
Client
,
factory
informers
.
InformerFactory
,
db
*
mysql
.
Database
)
*
tenantHandler
{
func
newTenantHandler
(
k8sClient
k8s
.
Client
,
factory
informers
.
InformerFactory
,
db
*
mysql
.
Database
)
*
tenantHandler
{
return
&
tenantHandler
{
return
&
tenantHandler
{
tenant
:
tenant
.
New
(
k8sClient
.
Kubernetes
(),
factory
.
KubernetesSharedInformerFactory
(),
factory
.
KubeSphereSharedInformerFactory
(),
db
),
tenant
:
tenant
.
New
(
k8sClient
.
Kubernetes
(),
factory
.
KubernetesSharedInformerFactory
(),
factory
.
KubeSphereSharedInformerFactory
(),
db
),
am
:
am
2
.
NewAMOperator
(
k8sClient
.
Kubernetes
(),
factory
.
KubernetesSharedInformerFactory
()),
am
:
am
.
NewAMOperator
(
k8sClient
.
Kubernetes
(),
factory
.
KubernetesSharedInformerFactory
()),
}
}
}
}
...
...
pkg/models/iam/am/am.go
浏览文件 @
1f26e621
...
@@ -18,7 +18,6 @@
...
@@ -18,7 +18,6 @@
package
am
package
am
import
(
import
(
rbacv1
"k8s.io/api/rbac/v1"
"k8s.io/client-go/informers"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
...
@@ -38,7 +37,6 @@ type AccessManagementInterface interface {
...
@@ -38,7 +37,6 @@ type AccessManagementInterface interface {
GetClusterRole
(
cluster
,
username
string
)
(
Role
,
error
)
GetClusterRole
(
cluster
,
username
string
)
(
Role
,
error
)
GetWorkspaceRole
(
workspace
,
username
string
)
(
Role
,
error
)
GetWorkspaceRole
(
workspace
,
username
string
)
(
Role
,
error
)
GetNamespaceRole
(
namespace
,
username
string
)
(
Role
,
error
)
GetNamespaceRole
(
namespace
,
username
string
)
(
Role
,
error
)
GetDevOpsRole
(
project
,
username
string
)
(
Role
,
error
)
}
}
type
Role
interface
{
type
Role
interface
{
...
@@ -52,26 +50,6 @@ type amOperator struct {
...
@@ -52,26 +50,6 @@ type amOperator struct {
kubeClient
kubernetes
.
Interface
kubeClient
kubernetes
.
Interface
}
}
func
(
am
*
amOperator
)
ListClusterRoleBindings
(
clusterRole
string
)
([]
*
rbacv1
.
ClusterRoleBinding
,
error
)
{
panic
(
"implement me"
)
}
func
(
am
*
amOperator
)
GetRoles
(
namespace
,
username
string
)
([]
*
rbacv1
.
Role
,
error
)
{
panic
(
"implement me"
)
}
func
(
am
*
amOperator
)
GetClusterPolicyRules
(
username
string
)
([]
rbacv1
.
PolicyRule
,
error
)
{
panic
(
"implement me"
)
}
func
(
am
*
amOperator
)
GetPolicyRules
(
namespace
,
username
string
)
([]
rbacv1
.
PolicyRule
,
error
)
{
panic
(
"implement me"
)
}
func
(
am
*
amOperator
)
GetWorkspaceRole
(
workspace
,
username
string
)
(
Role
,
error
)
{
panic
(
"implement me"
)
}
func
NewAMOperator
(
kubeClient
kubernetes
.
Interface
,
informers
informers
.
SharedInformerFactory
)
AccessManagementInterface
{
func
NewAMOperator
(
kubeClient
kubernetes
.
Interface
,
informers
informers
.
SharedInformerFactory
)
AccessManagementInterface
{
resourceGetter
:=
resource
.
ResourceGetter
{}
resourceGetter
:=
resource
.
ResourceGetter
{}
resourceGetter
.
Add
(
v1alpha2
.
Role
,
role
.
NewRoleSearcher
(
informers
))
resourceGetter
.
Add
(
v1alpha2
.
Role
,
role
.
NewRoleSearcher
(
informers
))
...
@@ -91,6 +69,10 @@ func (am *amOperator) GetClusterRole(cluster, username string) (Role, error) {
...
@@ -91,6 +69,10 @@ func (am *amOperator) GetClusterRole(cluster, username string) (Role, error) {
panic
(
"implement me"
)
panic
(
"implement me"
)
}
}
func
(
am
*
amOperator
)
GetWorkspaceRole
(
workspace
,
username
string
)
(
Role
,
error
)
{
panic
(
"implement me"
)
}
func
(
am
*
amOperator
)
GetNamespaceRole
(
namespace
,
username
string
)
(
Role
,
error
)
{
func
(
am
*
amOperator
)
GetNamespaceRole
(
namespace
,
username
string
)
(
Role
,
error
)
{
panic
(
"implement me"
)
panic
(
"implement me"
)
}
}
...
...
pkg/models/iam/am/fake_operator.go
0 → 100644
浏览文件 @
1f26e621
/*
*
* 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
am
import
(
"k8s.io/apiserver/pkg/authentication/user"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
)
type
fakeRole
struct
{
Name
string
Rego
string
}
type
fakeOperator
struct
{
cache
cache
.
Interface
}
func
newFakeRole
(
username
string
)
Role
{
if
username
==
user
.
Anonymous
{
return
&
fakeRole
{
Name
:
"anonymous"
,
Rego
:
"package authz
\n
default allow = false"
,
}
}
return
&
fakeRole
{
Name
:
"admin"
,
Rego
:
"package authz
\n
default allow = true"
,
}
}
func
(
f
fakeOperator
)
GetPlatformRole
(
username
string
)
(
Role
,
error
)
{
return
newFakeRole
(
username
),
nil
}
func
(
f
fakeOperator
)
GetClusterRole
(
cluster
,
username
string
)
(
Role
,
error
)
{
return
newFakeRole
(
username
),
nil
}
func
(
f
fakeOperator
)
GetWorkspaceRole
(
workspace
,
username
string
)
(
Role
,
error
)
{
return
newFakeRole
(
username
),
nil
}
func
(
f
fakeOperator
)
GetNamespaceRole
(
namespace
,
username
string
)
(
Role
,
error
)
{
return
newFakeRole
(
username
),
nil
}
func
(
f
fakeRole
)
GetName
()
string
{
return
f
.
Name
}
func
(
f
fakeRole
)
GetRego
()
string
{
return
f
.
Rego
}
func
NewFakeAMOperator
(
cache
cache
.
Interface
)
AccessManagementInterface
{
return
&
fakeOperator
{
cache
:
cache
}
}
pkg/models/tenant/namespaces.go
浏览文件 @
1f26e621
...
@@ -20,9 +20,9 @@ package tenant
...
@@ -20,9 +20,9 @@ package tenant
import
(
import
(
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
k8sinformers
"k8s.io/client-go/informers"
k8sinformers
"k8s.io/client-go/informers"
kubernetes
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/constants"
am2
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
...
@@ -37,7 +37,7 @@ type NamespaceInterface interface {
...
@@ -37,7 +37,7 @@ type NamespaceInterface interface {
type
namespaceSearcher
struct
{
type
namespaceSearcher
struct
{
k8s
kubernetes
.
Interface
k8s
kubernetes
.
Interface
informers
k8sinformers
.
SharedInformerFactory
informers
k8sinformers
.
SharedInformerFactory
am
am
2
.
AccessManagementInterface
am
am
.
AccessManagementInterface
}
}
func
(
s
*
namespaceSearcher
)
CreateNamespace
(
workspace
string
,
namespace
*
v1
.
Namespace
,
username
string
)
(
*
v1
.
Namespace
,
error
)
{
func
(
s
*
namespaceSearcher
)
CreateNamespace
(
workspace
string
,
namespace
*
v1
.
Namespace
,
username
string
)
(
*
v1
.
Namespace
,
error
)
{
...
@@ -53,7 +53,7 @@ func (s *namespaceSearcher) CreateNamespace(workspace string, namespace *v1.Name
...
@@ -53,7 +53,7 @@ func (s *namespaceSearcher) CreateNamespace(workspace string, namespace *v1.Name
return
s
.
k8s
.
CoreV1
()
.
Namespaces
()
.
Create
(
namespace
)
return
s
.
k8s
.
CoreV1
()
.
Namespaces
()
.
Create
(
namespace
)
}
}
func
newNamespaceOperator
(
k8s
kubernetes
.
Interface
,
informers
k8sinformers
.
SharedInformerFactory
,
am
am
2
.
AccessManagementInterface
)
NamespaceInterface
{
func
newNamespaceOperator
(
k8s
kubernetes
.
Interface
,
informers
k8sinformers
.
SharedInformerFactory
,
am
am
.
AccessManagementInterface
)
NamespaceInterface
{
return
&
namespaceSearcher
{
k8s
:
k8s
,
informers
:
informers
,
am
:
am
}
return
&
namespaceSearcher
{
k8s
:
k8s
,
informers
:
informers
,
am
:
am
}
}
}
...
...
pkg/models/tenant/tenant.go
浏览文件 @
1f26e621
...
@@ -24,7 +24,7 @@ import (
...
@@ -24,7 +24,7 @@ import (
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
ksinformers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
ksinformers
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models"
am2
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
)
)
...
@@ -43,7 +43,7 @@ type Interface interface {
...
@@ -43,7 +43,7 @@ type Interface interface {
type
tenantOperator
struct
{
type
tenantOperator
struct
{
workspaces
WorkspaceInterface
workspaces
WorkspaceInterface
namespaces
NamespaceInterface
namespaces
NamespaceInterface
am
am
2
.
AccessManagementInterface
am
am
.
AccessManagementInterface
devops
DevOpsProjectOperator
devops
DevOpsProjectOperator
}
}
...
@@ -68,7 +68,7 @@ func (t *tenantOperator) DeleteNamespace(workspace, namespace string) error {
...
@@ -68,7 +68,7 @@ func (t *tenantOperator) DeleteNamespace(workspace, namespace string) error {
}
}
func
New
(
client
kubernetes
.
Interface
,
informers
k8sinformers
.
SharedInformerFactory
,
ksinformers
ksinformers
.
SharedInformerFactory
,
db
*
mysql
.
Database
)
Interface
{
func
New
(
client
kubernetes
.
Interface
,
informers
k8sinformers
.
SharedInformerFactory
,
ksinformers
ksinformers
.
SharedInformerFactory
,
db
*
mysql
.
Database
)
Interface
{
amOperator
:=
am
2
.
NewAMOperator
(
client
,
informers
)
amOperator
:=
am
.
NewAMOperator
(
client
,
informers
)
return
&
tenantOperator
{
return
&
tenantOperator
{
workspaces
:
newWorkspaceOperator
(
client
,
informers
,
ksinformers
,
amOperator
,
db
),
workspaces
:
newWorkspaceOperator
(
client
,
informers
,
ksinformers
,
amOperator
,
db
),
namespaces
:
newNamespaceOperator
(
client
,
informers
,
amOperator
),
namespaces
:
newNamespaceOperator
(
client
,
informers
,
amOperator
),
...
...
pkg/models/tenant/workspaces.go
浏览文件 @
1f26e621
...
@@ -27,7 +27,7 @@ import (
...
@@ -27,7 +27,7 @@ import (
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/models/devops"
"kubesphere.io/kubesphere/pkg/models/devops"
am2
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
...
@@ -64,14 +64,14 @@ type workspaceOperator struct {
...
@@ -64,14 +64,14 @@ type workspaceOperator struct {
client
kubernetes
.
Interface
client
kubernetes
.
Interface
informers
informers
.
SharedInformerFactory
informers
informers
.
SharedInformerFactory
ksInformers
externalversions
.
SharedInformerFactory
ksInformers
externalversions
.
SharedInformerFactory
am
am
2
.
AccessManagementInterface
am
am
.
AccessManagementInterface
// TODO: use db interface instead of mysql client
// TODO: use db interface instead of mysql client
// we can refactor this after rewrite devops using crd
// we can refactor this after rewrite devops using crd
db
*
mysql
.
Database
db
*
mysql
.
Database
}
}
func
newWorkspaceOperator
(
client
kubernetes
.
Interface
,
informers
informers
.
SharedInformerFactory
,
ksinformers
externalversions
.
SharedInformerFactory
,
am
am
2
.
AccessManagementInterface
,
db
*
mysql
.
Database
)
WorkspaceInterface
{
func
newWorkspaceOperator
(
client
kubernetes
.
Interface
,
informers
informers
.
SharedInformerFactory
,
ksinformers
externalversions
.
SharedInformerFactory
,
am
am
.
AccessManagementInterface
,
db
*
mysql
.
Database
)
WorkspaceInterface
{
return
&
workspaceOperator
{
return
&
workspaceOperator
{
client
:
client
,
client
:
client
,
informers
:
informers
,
informers
:
informers
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录