Refactor iam module.
This commit is contained in:
@@ -28,9 +28,19 @@ import (
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/filter/route"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
)
|
||||
|
||||
type roleList struct {
|
||||
ClusterRoles []v1.ClusterRole `json:"clusterRoles" protobuf:"bytes,2,rep,name=clusterRoles"`
|
||||
Roles []v1.Role `json:"roles" protobuf:"bytes,2,rep,name=roles"`
|
||||
}
|
||||
|
||||
type userRuleList struct {
|
||||
ClusterRules []iam.Rule `json:"clusterRules"`
|
||||
Rules map[string][]iam.Rule `json:"rules"`
|
||||
}
|
||||
|
||||
func Register(ws *restful.WebService) {
|
||||
//roles
|
||||
ws.Route(ws.GET("/users/{username}/roles").To(userRolesHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
||||
@@ -53,14 +63,14 @@ func userRolesHandler(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
username := req.PathParameter("username")
|
||||
|
||||
roles, err := models.GetRoles(username)
|
||||
roles, err := iam.GetRoles(username)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
clusterRoles, err := models.GetClusterRoles(username)
|
||||
clusterRoles, err := iam.GetClusterRoles(username)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
@@ -79,7 +89,7 @@ func roleUsersHandler(req *restful.Request, resp *restful.Response) {
|
||||
name := req.PathParameter("name")
|
||||
namespace := req.PathParameter("namespace")
|
||||
|
||||
roleBindings, err := models.GetRoleBindings(namespace, name)
|
||||
roleBindings, err := iam.GetRoleBindings(namespace, name)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
@@ -105,7 +115,7 @@ func roleUsersHandler(req *restful.Request, resp *restful.Response) {
|
||||
func clusterRoleUsersHandler(req *restful.Request, resp *restful.Response) {
|
||||
name := req.PathParameter("name")
|
||||
|
||||
roleBindings, err := models.GetClusterRoleBindings(name)
|
||||
roleBindings, err := iam.GetClusterRoleBindings(name)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
@@ -138,14 +148,14 @@ func usersRulesHandler(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
userRuleList := userRuleList{}
|
||||
|
||||
clusterRules, err := getUserClusterRules(username)
|
||||
clusterRules, err := iam.GetUserClusterRules(username)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
rules, err := getUserRules(username)
|
||||
rules, err := iam.GetUserRules(username)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
@@ -168,14 +178,14 @@ func userRulesHandler(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
userRuleList := userRuleList{}
|
||||
|
||||
clusterRules, err := getUserClusterRules(username)
|
||||
clusterRules, err := iam.GetUserClusterRules(username)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
rules, err := getUserRules(username)
|
||||
rules, err := iam.GetUserRules(username)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
@@ -193,13 +203,13 @@ func clusterRoleRulesHandler(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
name := req.PathParameter("name")
|
||||
|
||||
var rules []rule
|
||||
var rules []iam.Rule
|
||||
|
||||
if name == "" {
|
||||
rules = clusterRoleRuleGroup
|
||||
rules = iam.ClusterRoleRuleGroup
|
||||
} else {
|
||||
var err error
|
||||
rules, err = getClusterRoleRules(name)
|
||||
rules, err = iam.GetClusterRoleRules(name)
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
return
|
||||
@@ -214,13 +224,13 @@ func roleRulesHandler(req *restful.Request, resp *restful.Response) {
|
||||
name := req.PathParameter("name")
|
||||
namespace := req.PathParameter("namespace")
|
||||
|
||||
var rules []rule
|
||||
var rules []iam.Rule
|
||||
|
||||
if namespace == "" && name == "" {
|
||||
rules = roleRuleGroup
|
||||
rules = iam.RoleRuleGroup
|
||||
} else {
|
||||
var err error
|
||||
rules, err = getRoleRules(namespace, name)
|
||||
rules, err = iam.GetRoleRules(namespace, name)
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
return
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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 iam
|
||||
|
||||
import (
|
||||
"k8s.io/api/rbac/v1"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/slice"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
)
|
||||
|
||||
func getUserRules(username string) (map[string][]rule, error) {
|
||||
|
||||
items := make(map[string][]rule, 0)
|
||||
roles, err := models.GetRoles(username)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
namespaces := make([]string, 0)
|
||||
|
||||
for i := 0; i < len(roles); i++ {
|
||||
if !slice.ContainsString(namespaces, roles[i].Namespace, nil) {
|
||||
namespaces = append(namespaces, roles[i].Namespace)
|
||||
}
|
||||
}
|
||||
|
||||
for _, namespace := range namespaces {
|
||||
rules := getMergeRules(namespace, roles)
|
||||
if len(rules) > 0 {
|
||||
items[namespace] = rules
|
||||
}
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func getMergeRules(namespace string, roles []v1.Role) []rule {
|
||||
rules := make([]rule, 0)
|
||||
|
||||
for i := 0; i < (len(roleRuleGroup)); i++ {
|
||||
rule := rule{Name: roleRuleGroup[i].Name}
|
||||
rule.Actions = make([]action, 0)
|
||||
for j := 0; j < (len(roleRuleGroup[i].Actions)); j++ {
|
||||
permit := false
|
||||
for _, role := range roles {
|
||||
if role.Namespace == namespace && actionValidate(role.Rules, roleRuleGroup[i].Actions[j]) {
|
||||
permit = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if permit {
|
||||
rule.Actions = append(rule.Actions, roleRuleGroup[i].Actions[j])
|
||||
}
|
||||
}
|
||||
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
return rules
|
||||
}
|
||||
|
||||
func getUserClusterRules(username string) ([]rule, error) {
|
||||
|
||||
rules := make([]rule, 0)
|
||||
|
||||
roles, err := models.GetClusterRoles(username)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 0; i < (len(clusterRoleRuleGroup)); i++ {
|
||||
rule := rule{Name: clusterRoleRuleGroup[i].Name}
|
||||
rule.Actions = make([]action, 0)
|
||||
for j := 0; j < (len(clusterRoleRuleGroup[i].Actions)); j++ {
|
||||
actionPermit := false
|
||||
for _, role := range roles {
|
||||
if actionValidate(role.Rules, clusterRoleRuleGroup[i].Actions[j]) {
|
||||
actionPermit = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if actionPermit {
|
||||
rule.Actions = append(rule.Actions, clusterRoleRuleGroup[i].Actions[j])
|
||||
}
|
||||
}
|
||||
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func getClusterRoleRules(name string) ([]rule, error) {
|
||||
|
||||
clusterRole, err := models.GetClusterRole(name)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rules := make([]rule, 0)
|
||||
|
||||
for i := 0; i < len(clusterRoleRuleGroup); i++ {
|
||||
rule := rule{Name: clusterRoleRuleGroup[i].Name}
|
||||
rule.Actions = make([]action, 0)
|
||||
for j := 0; j < (len(clusterRoleRuleGroup[i].Actions)); j++ {
|
||||
if actionValidate(clusterRole.Rules, clusterRoleRuleGroup[i].Actions[j]) {
|
||||
rule.Actions = append(rule.Actions, clusterRoleRuleGroup[i].Actions[j])
|
||||
}
|
||||
}
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func getRoleRules(namespace string, name string) ([]rule, error) {
|
||||
role, err := models.GetRole(namespace, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rules := make([]rule, 0)
|
||||
for i := 0; i < len(roleRuleGroup); i++ {
|
||||
rule := rule{Name: roleRuleGroup[i].Name}
|
||||
rule.Actions = make([]action, 0)
|
||||
for j := 0; j < len(roleRuleGroup[i].Actions); j++ {
|
||||
if actionValidate(role.Rules, roleRuleGroup[i].Actions[j]) {
|
||||
rule.Actions = append(rule.Actions, roleRuleGroup[i].Actions[j])
|
||||
}
|
||||
}
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func actionValidate(rules []v1.PolicyRule, action action) bool {
|
||||
for _, rule := range action.Rules {
|
||||
if !ruleValidate(rules, rule) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ruleValidate(rules []v1.PolicyRule, rule v1.PolicyRule) bool {
|
||||
|
||||
for _, apiGroup := range rule.APIGroups {
|
||||
if len(rule.NonResourceURLs) == 0 {
|
||||
for _, resource := range rule.Resources {
|
||||
|
||||
//if len(rule.ResourceNames) == 0 {
|
||||
|
||||
for _, verb := range rule.Verbs {
|
||||
if !verbValidate(rules, apiGroup, "", resource, "", verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
//} else {
|
||||
// for _, resourceName := range rule.ResourceNames {
|
||||
// for _, verb := range rule.Verbs {
|
||||
// if !verbValidate(rules, apiGroup, "", resource, resourceName, verb) {
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
} else {
|
||||
for _, nonResourceURL := range rule.NonResourceURLs {
|
||||
for _, verb := range rule.Verbs {
|
||||
if !verbValidate(rules, apiGroup, nonResourceURL, "", "", verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func verbValidate(rules []v1.PolicyRule, apiGroup string, nonResourceURL string, resource string, resourceName string, verb string) bool {
|
||||
for _, rule := range rules {
|
||||
if slice.ContainsString(rule.APIGroups, apiGroup, nil) || slice.ContainsString(rule.APIGroups, v1.APIGroupAll, nil) {
|
||||
if slice.ContainsString(rule.Verbs, verb, nil) || slice.ContainsString(rule.Verbs, v1.VerbAll, nil) {
|
||||
if nonResourceURL == "" {
|
||||
if slice.ContainsString(rule.Resources, resource, nil) || slice.ContainsString(rule.Resources, v1.ResourceAll, nil) {
|
||||
if resourceName == "" {
|
||||
return true
|
||||
} else if slice.ContainsString(rule.ResourceNames, resourceName, nil) || slice.ContainsString(rule.Resources, v1.ResourceAll, nil) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else if slice.ContainsString(rule.NonResourceURLs, nonResourceURL, nil) || slice.ContainsString(rule.NonResourceURLs, v1.NonResourceAll, nil) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -20,11 +20,11 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
)
|
||||
|
||||
func Register(ws *restful.WebService, subPath string) {
|
||||
@@ -74,7 +74,7 @@ func delUser(req *restful.Request, resp *restful.Response) {
|
||||
return
|
||||
}
|
||||
|
||||
err = models.DeleteRoleBindings(user)
|
||||
err = iam.DeleteRoleBindings(user)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
|
||||
@@ -66,11 +66,11 @@ func preCheck() error {
|
||||
return err
|
||||
}
|
||||
for _, ns := range nsList.Items {
|
||||
if ns.Name == constants.KubeSphereControlNameSpace {
|
||||
if ns.Name == constants.KubeSphereControlNamespace {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
namespace := v1.Namespace{ObjectMeta: meta_v1.ObjectMeta{Name: constants.KubeSphereControlNameSpace}}
|
||||
namespace := v1.Namespace{ObjectMeta: meta_v1.ObjectMeta{Name: constants.KubeSphereControlNamespace}}
|
||||
_, err = k8sClient.CoreV1().Namespaces().Create(&namespace)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -26,12 +26,16 @@ type PageableResponse struct {
|
||||
}
|
||||
|
||||
const (
|
||||
APIVERSION = "v1alpha1"
|
||||
KIND = "kubesphere"
|
||||
KubeSphereControlNameSpace = "kubesphere-controls-system"
|
||||
APIVersion = "v1alpha1"
|
||||
|
||||
DataHome = "/etc/kubesphere"
|
||||
IngressControllerFolder = DataHome + "/ingress-controller"
|
||||
IngressControllerNamespace = KubeSphereControlNameSpace
|
||||
IngressControllerPrefix = "kubesphere-router-"
|
||||
KubeSystemNamespace = "kube-system"
|
||||
OpenPitrixNamespace = "openpitrix-system"
|
||||
IstioNamespace = "istio-system"
|
||||
KubeSphereNamespace = "kubesphere-system"
|
||||
KubeSphereControlNamespace = "kubesphere-controls-system"
|
||||
IngressControllerNamespace = KubeSphereControlNamespace
|
||||
|
||||
DataHome = "/etc/kubesphere"
|
||||
IngressControllerFolder = DataHome + "/ingress-controller"
|
||||
IngressControllerPrefix = "kubesphere-router-"
|
||||
)
|
||||
|
||||
@@ -23,13 +23,9 @@ import (
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
)
|
||||
|
||||
const KUBESYSTEM = "kube-system"
|
||||
const OPENPITRIX = "openpitrix-system"
|
||||
const ISTIO = "istio-system"
|
||||
const KUBESPHERE = "kubesphere-system"
|
||||
|
||||
type ComponentsCount struct {
|
||||
KubernetesCount int `json:"kubernetesCount"`
|
||||
OpenpitrixCount int `json:"openpitrixCount"`
|
||||
@@ -63,10 +59,10 @@ func GetComponents() (map[string]interface{}, error) {
|
||||
LabelSelector: label,
|
||||
}
|
||||
|
||||
namespaces := []string{KUBESYSTEM, OPENPITRIX, ISTIO, KUBESPHERE}
|
||||
namespaces := []string{constants.KubeSystemNamespace, constants.OpenPitrixNamespace, constants.IstioNamespace, constants.KubeSphereNamespace}
|
||||
for _, ns := range namespaces {
|
||||
|
||||
if ns != KUBESYSTEM {
|
||||
if ns != constants.KubeSystemNamespace {
|
||||
option.LabelSelector = ""
|
||||
}
|
||||
servicelists, err := k8sClient.CoreV1().Services(ns).List(option)
|
||||
@@ -84,11 +80,11 @@ func GetComponents() (map[string]interface{}, error) {
|
||||
|
||||
switch ns {
|
||||
|
||||
case KUBESYSTEM:
|
||||
case constants.KubeSystemNamespace:
|
||||
count.KubernetesCount++
|
||||
case OPENPITRIX:
|
||||
case constants.OpenPitrixNamespace:
|
||||
count.OpenpitrixCount++
|
||||
case KUBESPHERE:
|
||||
case constants.KubeSphereNamespace:
|
||||
count.KubesphereCount++
|
||||
|
||||
default:
|
||||
|
||||
@@ -33,19 +33,23 @@ import (
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/util/slice"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/options"
|
||||
)
|
||||
|
||||
const (
|
||||
provider = "kubernetes"
|
||||
admin = "admin"
|
||||
editor = "editor"
|
||||
viewer = "viewer"
|
||||
kubectlNamespace = constants.KubeSphereControlNameSpace
|
||||
kubectlConfigKey = "config"
|
||||
openpitrix_runtime = "openpitrix_runtime"
|
||||
provider = "kubernetes"
|
||||
admin = "admin"
|
||||
editor = "editor"
|
||||
viewer = "viewer"
|
||||
kubectlNamespace = constants.KubeSphereControlNamespace
|
||||
kubectlConfigKey = "config"
|
||||
openPitrixRuntimeAnnotateKey = "openpitrix_runtime"
|
||||
creatorAnnotateKey = "creator"
|
||||
)
|
||||
|
||||
var adminRules = []rbac.PolicyRule{{Verbs: []string{"*"}, APIGroups: []string{"*"}, Resources: []string{"*"}}}
|
||||
@@ -96,7 +100,13 @@ func (ctl *NamespaceCtl) getKubeConfig(user string) (string, error) {
|
||||
|
||||
func (ctl *NamespaceCtl) deleteOpRuntime(item v1.Namespace) {
|
||||
|
||||
runtimeId := item.Annotations["openpitrix_runtime"]
|
||||
var runtimeId string
|
||||
if item.Annotations == nil {
|
||||
runtimeId = ""
|
||||
} else {
|
||||
runtimeId = item.Annotations[openPitrixRuntimeAnnotateKey]
|
||||
}
|
||||
|
||||
if len(runtimeId) == 0 {
|
||||
return
|
||||
}
|
||||
@@ -107,9 +117,10 @@ func (ctl *NamespaceCtl) deleteOpRuntime(item v1.Namespace) {
|
||||
|
||||
body, err := json.Marshal(deleteRuntime)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
glog.Error("runtime release failed:", item.Name, runtimeId, err)
|
||||
return
|
||||
}
|
||||
glog.Info("runtime release succeeded:", item.Name, runtimeId)
|
||||
|
||||
// todo: if delete failed, what's to be done?
|
||||
makeHttpRequest("DELETE", url, string(body))
|
||||
@@ -137,19 +148,15 @@ func (ctl *NamespaceCtl) createOpRuntime(namespace string) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) createDefaultRoleBinding(ns, user string) error {
|
||||
rolebinding, _ := ctl.K8sClient.RbacV1().RoleBindings(ns).Get(admin, metaV1.GetOptions{})
|
||||
|
||||
if rolebinding.Name != admin {
|
||||
roleBinding := &rbac.RoleBinding{ObjectMeta: metaV1.ObjectMeta{Name: admin, Namespace: ns},
|
||||
Subjects: []rbac.Subject{{Name: user, Kind: rbac.UserKind}}, RoleRef: rbac.RoleRef{Kind: "Role", Name: admin}}
|
||||
|
||||
roleBinding := &rbac.RoleBinding{ObjectMeta: metaV1.ObjectMeta{Name: admin, Namespace: ns},
|
||||
Subjects: []rbac.Subject{{Name: user, Kind: rbac.UserKind}}, RoleRef: rbac.RoleRef{Kind: "Role", Name: admin}}
|
||||
_, err := ctl.K8sClient.RbacV1().RoleBindings(ns).Create(roleBinding)
|
||||
|
||||
_, err := ctl.K8sClient.RbacV1().RoleBindings(ns).Create(roleBinding)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return err
|
||||
}
|
||||
if err != nil && !errors.IsAlreadyExists(err) {
|
||||
glog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -160,72 +167,86 @@ func (ctl *NamespaceCtl) createDefaultRole(ns string) error {
|
||||
editorRole := &rbac.Role{ObjectMeta: metaV1.ObjectMeta{Name: editor, Namespace: ns}, Rules: editorRules}
|
||||
viewerRole := &rbac.Role{ObjectMeta: metaV1.ObjectMeta{Name: viewer, Namespace: ns}, Rules: viewerRules}
|
||||
|
||||
role, _ := ctl.K8sClient.RbacV1().Roles(ns).Get(admin, metaV1.GetOptions{})
|
||||
_, err := ctl.K8sClient.RbacV1().Roles(ns).Create(adminRole)
|
||||
|
||||
if role.Name != admin {
|
||||
_, err := ctl.K8sClient.RbacV1().Roles(ns).Create(adminRole)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return err
|
||||
}
|
||||
if err != nil && !errors.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
role, _ = ctl.K8sClient.RbacV1().Roles(ns).Get(editor, metaV1.GetOptions{})
|
||||
_, err = ctl.K8sClient.RbacV1().Roles(ns).Create(editorRole)
|
||||
|
||||
if role.Name != editor {
|
||||
_, err := ctl.K8sClient.RbacV1().Roles(ns).Create(editorRole)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return err
|
||||
}
|
||||
if err != nil && !errors.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
role, _ = ctl.K8sClient.RbacV1().Roles(ns).Get(viewer, metaV1.GetOptions{})
|
||||
_, err = ctl.K8sClient.RbacV1().Roles(ns).Create(viewerRole)
|
||||
|
||||
if role.Name != viewer {
|
||||
_, err := ctl.K8sClient.RbacV1().Roles(ns).Create(viewerRole)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return err
|
||||
}
|
||||
if err != nil && !errors.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) createRoleAndRuntime(item v1.Namespace) {
|
||||
user := item.Annotations["creator"]
|
||||
var creator string
|
||||
var runtime string
|
||||
ns := item.Name
|
||||
if len(user) > 0 && len(item.Annotations[openpitrix_runtime]) == 0 {
|
||||
err := ctl.createDefaultRole(ns)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := ctl.createOpRuntime(ns)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = ctl.createDefaultRoleBinding(ns, user)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
var runtime runTime
|
||||
err = json.Unmarshal(resp, &runtime)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
item.Annotations[openpitrix_runtime] = runtime.RuntimeId
|
||||
_, err = ctl.K8sClient.CoreV1().Namespaces().Update(&item)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
}
|
||||
if item.Annotations == nil {
|
||||
creator = ""
|
||||
runtime = ""
|
||||
} else {
|
||||
runtime = item.Annotations[openPitrixRuntimeAnnotateKey]
|
||||
creator = item.Annotations[creatorAnnotateKey]
|
||||
}
|
||||
|
||||
componentsNamespaces := []string{constants.KubeSystemNamespace, constants.OpenPitrixNamespace, constants.IstioNamespace, constants.KubeSphereNamespace}
|
||||
|
||||
if len(runtime) == 0 && !slice.ContainsString(componentsNamespaces, ns, nil) {
|
||||
glog.Infoln("create runtime:", ns)
|
||||
var runtimeCreateError error
|
||||
resp, runtimeCreateError := ctl.createOpRuntime(ns)
|
||||
|
||||
if runtimeCreateError == nil {
|
||||
var runtime runTime
|
||||
runtimeCreateError = json.Unmarshal(resp, &runtime)
|
||||
if runtimeCreateError == nil {
|
||||
|
||||
if item.Annotations == nil {
|
||||
item.Annotations = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
item.Annotations[openPitrixRuntimeAnnotateKey] = runtime.RuntimeId
|
||||
_, runtimeCreateError = ctl.K8sClient.CoreV1().Namespaces().Update(&item)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if runtimeCreateError != nil {
|
||||
glog.Error("runtime create error:", runtimeCreateError)
|
||||
}
|
||||
|
||||
if len(creator) > 0 {
|
||||
roleCreateError := ctl.createDefaultRole(ns)
|
||||
glog.Infoln("create default role:", ns)
|
||||
if roleCreateError == nil {
|
||||
|
||||
roleBindingError := ctl.createDefaultRoleBinding(ns, creator)
|
||||
glog.Infoln("create default role binding:", ns)
|
||||
if roleBindingError != nil {
|
||||
glog.Error("default role binding create error:", roleBindingError)
|
||||
}
|
||||
|
||||
} else {
|
||||
glog.Error("default role create error:", roleCreateError)
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
glog.Infoln("runtime has been init:", ns, runtime)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) generateObject(item v1.Namespace) *Namespace {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package models
|
||||
package iam
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
@@ -6,11 +6,66 @@ import (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/slice"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
const ClusterRoleKind = "ClusterRole"
|
||||
|
||||
func GetUserNamespaces(username string, requiredRule v1.PolicyRule) (allNamespace bool, namespaces []string, err error) {
|
||||
|
||||
clusterRoles, err := GetClusterRoles(username)
|
||||
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
clusterRules := make([]v1.PolicyRule, 0)
|
||||
for _, role := range clusterRoles {
|
||||
clusterRules = append(clusterRules, role.Rules...)
|
||||
}
|
||||
|
||||
if requiredRule.Size() == 0 {
|
||||
if ruleValidate(clusterRules, v1.PolicyRule{
|
||||
Verbs: []string{"get", "list"},
|
||||
APIGroups: []string{""},
|
||||
Resources: []string{"namespaces"},
|
||||
}) {
|
||||
return true, nil, nil
|
||||
}
|
||||
} else if ruleValidate(clusterRules, requiredRule) {
|
||||
return true, nil, nil
|
||||
}
|
||||
|
||||
roles, err := GetRoles(username)
|
||||
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
rulesMapping := make(map[string][]v1.PolicyRule, 0)
|
||||
|
||||
for _, role := range roles {
|
||||
rules := rulesMapping[role.Namespace]
|
||||
if rules == nil {
|
||||
rules = make([]v1.PolicyRule, 0)
|
||||
}
|
||||
rules = append(rules, role.Rules...)
|
||||
rulesMapping[role.Namespace] = rules
|
||||
}
|
||||
|
||||
namespaces = make([]string, 0)
|
||||
|
||||
for namespace, rules := range rulesMapping {
|
||||
if requiredRule.Size() == 0 || ruleValidate(rules, requiredRule) {
|
||||
namespaces = append(namespaces, namespace)
|
||||
}
|
||||
}
|
||||
|
||||
return false, namespaces, nil
|
||||
}
|
||||
|
||||
func DeleteRoleBindings(username string) error {
|
||||
k8s := client.NewK8sClient()
|
||||
|
||||
@@ -208,3 +263,61 @@ func GetClusterRoles(username string) ([]v1.ClusterRole, error) {
|
||||
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
func ruleValidate(rules []v1.PolicyRule, rule v1.PolicyRule) bool {
|
||||
|
||||
for _, apiGroup := range rule.APIGroups {
|
||||
if len(rule.NonResourceURLs) == 0 {
|
||||
for _, resource := range rule.Resources {
|
||||
|
||||
//if len(Rule.ResourceNames) == 0 {
|
||||
|
||||
for _, verb := range rule.Verbs {
|
||||
if !verbValidate(rules, apiGroup, "", resource, "", verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
//} else {
|
||||
// for _, resourceName := range Rule.ResourceNames {
|
||||
// for _, verb := range Rule.Verbs {
|
||||
// if !verbValidate(rules, apiGroup, "", resource, resourceName, verb) {
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
} else {
|
||||
for _, nonResourceURL := range rule.NonResourceURLs {
|
||||
for _, verb := range rule.Verbs {
|
||||
if !verbValidate(rules, apiGroup, nonResourceURL, "", "", verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func verbValidate(rules []v1.PolicyRule, apiGroup string, nonResourceURL string, resource string, resourceName string, verb string) bool {
|
||||
for _, rule := range rules {
|
||||
if slice.ContainsString(rule.APIGroups, apiGroup, nil) || slice.ContainsString(rule.APIGroups, v1.APIGroupAll, nil) {
|
||||
if slice.ContainsString(rule.Verbs, verb, nil) || slice.ContainsString(rule.Verbs, v1.VerbAll, nil) {
|
||||
if nonResourceURL == "" {
|
||||
if slice.ContainsString(rule.Resources, resource, nil) || slice.ContainsString(rule.Resources, v1.ResourceAll, nil) {
|
||||
if resourceName == "" {
|
||||
return true
|
||||
} else if slice.ContainsString(rule.ResourceNames, resourceName, nil) || slice.ContainsString(rule.Resources, v1.ResourceAll, nil) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else if slice.ContainsString(rule.NonResourceURLs, nonResourceURL, nil) || slice.ContainsString(rule.NonResourceURLs, v1.NonResourceAll, nil) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/rbac/v1"
|
||||
)
|
||||
|
||||
@@ -30,59 +29,47 @@ const (
|
||||
clusterRulesConfigPath = "/etc/kubesphere/rules/clusterrules.json"
|
||||
)
|
||||
|
||||
type roleList struct {
|
||||
ClusterRoles []v1.ClusterRole `json:"clusterRoles" protobuf:"bytes,2,rep,name=clusterRoles"`
|
||||
Roles []v1.Role `json:"roles" protobuf:"bytes,2,rep,name=roles"`
|
||||
}
|
||||
|
||||
type action struct {
|
||||
type Action struct {
|
||||
Name string `json:"name"`
|
||||
Rules []v1.PolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
type rule struct {
|
||||
type Rule struct {
|
||||
Name string `json:"name"`
|
||||
Actions []action `json:"actions"`
|
||||
}
|
||||
|
||||
type userRuleList struct {
|
||||
ClusterRules []rule `json:"clusterRules"`
|
||||
Rules map[string][]rule `json:"rules"`
|
||||
Actions []Action `json:"actions"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
rulesConfig, err := ioutil.ReadFile(rulesConfigPath)
|
||||
if err == nil {
|
||||
config := &[]rule{}
|
||||
config := &[]Rule{}
|
||||
json.Unmarshal(rulesConfig, config)
|
||||
if len(*config) > 0 {
|
||||
roleRuleGroup = *config
|
||||
glog.Info("rules config load success")
|
||||
RoleRuleGroup = *config
|
||||
}
|
||||
}
|
||||
|
||||
clusterRulesConfig, err := ioutil.ReadFile(clusterRulesConfigPath)
|
||||
|
||||
if err == nil {
|
||||
config := &[]rule{}
|
||||
config := &[]Rule{}
|
||||
json.Unmarshal(clusterRulesConfig, config)
|
||||
if len(*config) > 0 {
|
||||
clusterRoleRuleGroup = *config
|
||||
glog.Info("cluster rules config load success")
|
||||
ClusterRoleRuleGroup = *config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
clusterRoleRuleGroup = []rule{projects, users, roles, images,
|
||||
ClusterRoleRuleGroup = []Rule{projects, users, roles, images,
|
||||
volumes, storageclasses, nodes, appCatalog, apps, components, deployments, statefulsets, daemonsets, pods, services, routes}
|
||||
|
||||
roleRuleGroup = []rule{project, deployments, statefulsets, daemonsets, pods,
|
||||
RoleRuleGroup = []Rule{project, deployments, statefulsets, daemonsets, pods,
|
||||
services, routes, volumes}
|
||||
|
||||
components = rule{
|
||||
components = Rule{
|
||||
Name: "components",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -95,9 +82,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
projects = rule{
|
||||
projects = Rule{
|
||||
Name: "projects",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -155,9 +142,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
project = rule{
|
||||
project = Rule{
|
||||
Name: "projects",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "members",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -196,9 +183,9 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
users = rule{
|
||||
users = Rule{
|
||||
Name: "users",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -253,9 +240,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
roles = rule{
|
||||
roles = Rule{
|
||||
Name: "roles",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -296,9 +283,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
nodes = rule{
|
||||
nodes = Rule{
|
||||
Name: "nodes",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -329,9 +316,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
volumes = rule{
|
||||
volumes = Rule{
|
||||
Name: "volumes",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -376,9 +363,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
storageclasses = rule{
|
||||
storageclasses = Rule{
|
||||
Name: "storageclasses",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -418,9 +405,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
images = rule{
|
||||
images = Rule{
|
||||
Name: "images",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -473,9 +460,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
appCatalog = rule{
|
||||
appCatalog = Rule{
|
||||
Name: "app_catalog",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -515,9 +502,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
apps = rule{
|
||||
apps = Rule{
|
||||
Name: "apps",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -530,9 +517,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
statefulsets = rule{
|
||||
statefulsets = Rule{
|
||||
Name: "statefulsets",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -591,9 +578,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
daemonsets = rule{
|
||||
daemonsets = Rule{
|
||||
Name: "daemonsets",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -643,9 +630,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
services = rule{
|
||||
services = Rule{
|
||||
Name: "services",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -691,9 +678,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
routes = rule{
|
||||
routes = Rule{
|
||||
Name: "routes",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -701,11 +688,6 @@ var (
|
||||
APIGroups: []string{"extensions"},
|
||||
Resources: []string{"ingresses"},
|
||||
},
|
||||
{
|
||||
Verbs: []string{"list"},
|
||||
APIGroups: []string{""},
|
||||
Resources: []string{"namespaces"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{Name: "create",
|
||||
@@ -738,9 +720,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
deployments = rule{
|
||||
deployments = Rule{
|
||||
Name: "deployments",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "view",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
@@ -801,9 +783,9 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
pods = rule{
|
||||
pods = Rule{
|
||||
Name: "pods",
|
||||
Actions: []action{
|
||||
Actions: []Action{
|
||||
{Name: "terminal",
|
||||
Rules: []v1.PolicyRule{
|
||||
{
|
||||
161
pkg/models/iam/tools.go
Normal file
161
pkg/models/iam/tools.go
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
Copyright 2018 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 iam
|
||||
|
||||
import (
|
||||
"k8s.io/api/rbac/v1"
|
||||
)
|
||||
|
||||
func GetUserRules(username string) (map[string][]Rule, error) {
|
||||
|
||||
items := make(map[string][]Rule, 0)
|
||||
userRoles, err := GetRoles(username)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rulesMapping := make(map[string][]v1.PolicyRule, 0)
|
||||
|
||||
for _, role := range userRoles {
|
||||
rules := rulesMapping[role.Namespace]
|
||||
if rules == nil {
|
||||
rules = make([]v1.PolicyRule, 0)
|
||||
}
|
||||
rules = append(rules, role.Rules...)
|
||||
rulesMapping[role.Namespace] = rules
|
||||
}
|
||||
|
||||
for namespace, policyRules := range rulesMapping {
|
||||
rules := convertToRules(policyRules)
|
||||
if len(rules) > 0 {
|
||||
items[namespace] = rules
|
||||
}
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func convertToRules(policyRules []v1.PolicyRule) []Rule {
|
||||
rules := make([]Rule, 0)
|
||||
|
||||
for i := 0; i < (len(RoleRuleGroup)); i++ {
|
||||
rule := Rule{Name: RoleRuleGroup[i].Name}
|
||||
rule.Actions = make([]Action, 0)
|
||||
for j := 0; j < (len(RoleRuleGroup[i].Actions)); j++ {
|
||||
if actionValidate(policyRules, RoleRuleGroup[i].Actions[j]) {
|
||||
rule.Actions = append(rule.Actions, RoleRuleGroup[i].Actions[j])
|
||||
}
|
||||
}
|
||||
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
return rules
|
||||
}
|
||||
|
||||
func GetUserClusterRules(username string) ([]Rule, error) {
|
||||
|
||||
rules := make([]Rule, 0)
|
||||
|
||||
clusterRoles, err := GetClusterRoles(username)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clusterRules := make([]v1.PolicyRule, 0)
|
||||
|
||||
for _, role := range clusterRoles {
|
||||
clusterRules = append(clusterRules, role.Rules...)
|
||||
}
|
||||
|
||||
for i := 0; i < (len(ClusterRoleRuleGroup)); i++ {
|
||||
rule := Rule{Name: ClusterRoleRuleGroup[i].Name}
|
||||
rule.Actions = make([]Action, 0)
|
||||
for j := 0; j < (len(ClusterRoleRuleGroup[i].Actions)); j++ {
|
||||
if actionValidate(clusterRules, ClusterRoleRuleGroup[i].Actions[j]) {
|
||||
rule.Actions = append(rule.Actions, ClusterRoleRuleGroup[i].Actions[j])
|
||||
}
|
||||
}
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func GetClusterRoleRules(name string) ([]Rule, error) {
|
||||
|
||||
clusterRole, err := GetClusterRole(name)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rules := make([]Rule, 0)
|
||||
|
||||
for i := 0; i < len(ClusterRoleRuleGroup); i++ {
|
||||
rule := Rule{Name: ClusterRoleRuleGroup[i].Name}
|
||||
rule.Actions = make([]Action, 0)
|
||||
for j := 0; j < (len(ClusterRoleRuleGroup[i].Actions)); j++ {
|
||||
if actionValidate(clusterRole.Rules, ClusterRoleRuleGroup[i].Actions[j]) {
|
||||
rule.Actions = append(rule.Actions, ClusterRoleRuleGroup[i].Actions[j])
|
||||
}
|
||||
}
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func GetRoleRules(namespace string, name string) ([]Rule, error) {
|
||||
role, err := GetRole(namespace, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rules := make([]Rule, 0)
|
||||
for i := 0; i < len(RoleRuleGroup); i++ {
|
||||
rule := Rule{Name: RoleRuleGroup[i].Name}
|
||||
rule.Actions = make([]Action, 0)
|
||||
for j := 0; j < len(RoleRuleGroup[i].Actions); j++ {
|
||||
if actionValidate(role.Rules, RoleRuleGroup[i].Actions[j]) {
|
||||
rule.Actions = append(rule.Actions, RoleRuleGroup[i].Actions[j])
|
||||
}
|
||||
}
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func actionValidate(rules []v1.PolicyRule, action Action) bool {
|
||||
for _, rule := range action.Rules {
|
||||
if !ruleValidate(rules, rule) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -246,7 +246,7 @@ func CreateKubeConfig(user string) error {
|
||||
|
||||
data := map[string]string{"config": string(config)}
|
||||
var configmap = v1.ConfigMap{TypeMeta: metav1.TypeMeta{Kind: "Configmap", APIVersion: "v1"}, ObjectMeta: metav1.ObjectMeta{Name: user}, Data: data}
|
||||
_, err = k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNameSpace).Create(&configmap)
|
||||
_, err = k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Create(&configmap)
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
return err
|
||||
@@ -257,7 +257,7 @@ func CreateKubeConfig(user string) error {
|
||||
|
||||
func GetKubeConfig(user string) (string, error) {
|
||||
k8sClient := client.NewK8sClient()
|
||||
configmap, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNameSpace).Get(user, metav1.GetOptions{})
|
||||
configmap, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(user, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
return "", err
|
||||
@@ -267,7 +267,7 @@ func GetKubeConfig(user string) (string, error) {
|
||||
|
||||
func DelKubeConfig(user string) error {
|
||||
k8sClient := client.NewK8sClient()
|
||||
err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNameSpace).Delete(user, &metav1.DeleteOptions{})
|
||||
err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Delete(user, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
return err
|
||||
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/options"
|
||||
)
|
||||
|
||||
const namespace = constants.KubeSphereControlNameSpace
|
||||
const namespace = constants.KubeSphereControlNamespace
|
||||
|
||||
type kubectlPodInfo struct {
|
||||
Namespace string `json:"namespace"`
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
)
|
||||
|
||||
func GetAllRouters() ([]coreV1.Service, error) {
|
||||
@@ -71,37 +72,30 @@ func inArray(val interface{}, array interface{}) (exists bool) {
|
||||
func GetAllRoutersOfUser(username string) ([]coreV1.Service, error) {
|
||||
|
||||
routers := make([]coreV1.Service, 0)
|
||||
clusterRoles, err := GetClusterRoles(username)
|
||||
|
||||
allNamespace, namespaces, err := iam.GetUserNamespaces(username, v1.PolicyRule{
|
||||
Verbs: []string{"get", "list"},
|
||||
APIGroups: []string{"extensions"},
|
||||
Resources: []string{"ingresses"},
|
||||
})
|
||||
|
||||
// return by cluster role
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return routers, err
|
||||
} else {
|
||||
for _, clusterRole := range clusterRoles {
|
||||
for _, rulePolicy := range clusterRole.Rules {
|
||||
if (inArray(v1.VerbAll, rulePolicy.Verbs) || inArray("view", rulePolicy.Verbs)) &&
|
||||
(inArray(v1.ResourceAll, rulePolicy.Resources) || inArray("namespaces", rulePolicy.Resources)) {
|
||||
return GetAllRouters()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return by role
|
||||
roles, err := GetRoles(username)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return routers, err
|
||||
} else {
|
||||
for _, projectRole := range roles {
|
||||
router, err := GetRouter(projectRole.Namespace)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return routers, err
|
||||
} else if router != nil {
|
||||
routers = append(routers, *router)
|
||||
}
|
||||
if allNamespace {
|
||||
return GetAllRouters()
|
||||
}
|
||||
|
||||
for _, namespace := range namespaces {
|
||||
router, err := GetRouter(namespace)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return routers, err
|
||||
} else if router != nil {
|
||||
routers = append(routers, *router)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ var (
|
||||
func PrintAndExitIfRequested() {
|
||||
|
||||
if *versionFlag {
|
||||
fmt.Printf("Kubesphere %s\n", constants.APIVERSION)
|
||||
fmt.Printf("Kubesphere %s\n", constants.APIVersion)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user