Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/permission optimization #357

Merged
merged 11 commits into from
Mar 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/backend/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ func Client(cluster string) (*kubernetes.Clientset, error) {

func Manager(cluster string) (*ClusterManager, error) {
managerInterface, exist := clusterManagerSets.Load(cluster)
manager := managerInterface.(*ClusterManager)
// 如果不存在,则重新获取一次集群信息
if !exist {
BuildApiserverClient()
Expand All @@ -175,6 +174,7 @@ func Manager(cluster string) (*ClusterManager, error) {
return nil, ErrNotExist
}
}
manager := managerInterface.(*ClusterManager)
if manager.Cluster.Status == models.ClusterStatusMaintaining {
return nil, ErrMaintaining
}
Expand Down
38 changes: 24 additions & 14 deletions src/backend/controllers/base/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"net/http"
"strconv"

"github.com/astaxie/beego/orm"
"k8s.io/client-go/kubernetes"

"github.com/Qihoo360/wayne/src/backend/client"
Expand Down Expand Up @@ -44,6 +43,14 @@ func (c *APIController) Prepare() {
}
}

func (c *APIController) PreparePermission(methodActionMap map[string]string, method string, permissionType string) {
action, ok := methodActionMap[method]
if !ok {
return
}
c.CheckPermission(permissionType, action)
}

/*
* 检查资源权限
*/
Expand All @@ -55,26 +62,29 @@ func (c *APIController) CheckPermission(perType string, perAction string) {
}

perName := models.PermissionModel.MergeName(perType, perAction)
if c.AppId != 0 {
// 检查App的操作权限
_, err := models.AppUserModel.GetOneByPermission(c.AppId, c.User.Id, perName)
if err == nil {
return
} else if err != nil && err != orm.ErrNoRows {
logs.Info("Check app permission error.%v", err)
c.AbortInternalServerError("Check app permission error.")
}
}

if c.NamespaceId != 0 {
// 检查namespace的操作权限
_, err := models.NamespaceUserModel.GetOneByPermission(c.NamespaceId, c.User.Id, perName)
if err == nil {
return
} else {
logs.Info("Check namespace permission error.%v", err)
c.AbortInternalServerError("Check namespace permission error.")
}

if c.AppId != 0 {
// 检查App的操作权限
_, err := models.AppUserModel.GetOneByPermission(c.AppId, c.User.Id, perName)
if err == nil {
return
}
logs.Info("User does not have current app permissions.", c.User.Name, perName, c.AppId, err)
c.AbortForbidden(fmt.Sprintf("User (%s) does not have current app (%d) permissions (%s).", c.User.Name,
c.AppId, perName))
}

logs.Info("User does not have current namespace permissions.", c.User.Name, perName, c.NamespaceId, err)
c.AbortForbidden(fmt.Sprintf("User (%s) does not have current namespace (%d) permissions (%s).", c.User.Name,
c.NamespaceId, perName))

}

c.AbortForbidden("Permission error")
Expand Down
2 changes: 1 addition & 1 deletion src/backend/controllers/base/resulthandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (c *ResultHandlerController) HandleError(err error) int {
errorResult.Code = http.StatusNotFound
}
errorResult.SubCode = errorResult.Code
errorResult.Msg = http.StatusText(errorResult.Code)
errorResult.Msg = err.Error()
}

if errorResult.Code >= http.StatusInternalServerError {
Expand Down
132 changes: 36 additions & 96 deletions src/backend/controllers/kubernetes/configmap/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

kapi "k8s.io/api/core/v1"

"github.com/Qihoo360/wayne/src/backend/client"
"github.com/Qihoo360/wayne/src/backend/controllers/base"
"github.com/Qihoo360/wayne/src/backend/models"
"github.com/Qihoo360/wayne/src/backend/resources/configmap"
Expand All @@ -17,35 +16,26 @@ type KubeConfigMapController struct {
}

func (c *KubeConfigMapController) URLMapping() {
c.Mapping("Get", c.Get)
c.Mapping("Offline", c.Offline)
c.Mapping("Deploy", c.Deploy)
c.Mapping("Create", c.Create)
}

func (c *KubeConfigMapController) Prepare() {
// Check administration
c.APIController.Prepare()
perAction := ""
_, method := c.GetControllerAndAction()
switch method {
case "Get":
perAction = models.PermissionRead
case "Deploy":
perAction = models.PermissionDeploy
case "Offline":
perAction = models.PermissionOffline
}
if perAction != "" {
c.CheckPermission(models.PermissionTypeConfigMap, perAction)

methodActionMap := map[string]string{
"Create": models.PermissionCreate,
}
_, method := c.GetControllerAndAction()
c.PreparePermission(methodActionMap, method, models.PermissionTypeKubeConfigMap)
}

// @Title deploy
// @Description deploy tpl
// @Param body body string true "The tpl content"
// @Success 200 return ok success
// @router /:configMapId/tpls/:tplId/clusters/:cluster [post]
func (c *KubeConfigMapController) Deploy() {
func (c *KubeConfigMapController) Create() {
configMapId := c.GetIntParamFromURL(":configMapId")
tplId := c.GetIntParamFromURL(":tplId")
var kubeConfigMap kapi.ConfigMap
Expand All @@ -56,91 +46,41 @@ func (c *KubeConfigMapController) Deploy() {
}

cluster := c.Ctx.Input.Param(":cluster")
cli, err := client.Client(cluster)
if err == nil {
publishHistory := &models.PublishHistory{
Type: models.PublishTypeConfigMap,
ResourceId: int64(configMapId),
ResourceName: kubeConfigMap.Name,
TemplateId: int64(tplId),
Cluster: cluster,
User: c.User.Name,
}
defer models.PublishHistoryModel.Add(publishHistory)
// 发布资源到k8s平台
_, err = configmap.CreateOrUpdateConfigMap(cli, &kubeConfigMap)
if err != nil {
publishHistory.Status = models.ReleaseFailure
publishHistory.Message = err.Error()
c.HandleError(err)
return
} else {
publishHistory.Status = models.ReleaseSuccess
// 添加发布状态
publishStatus := models.PublishStatus{
ResourceId: int64(configMapId),
TemplateId: int64(tplId),
Type: models.PublishTypeConfigMap,
Cluster: cluster,
}
err = models.PublishStatusModel.Publish(&publishStatus)
if err != nil {
logs.Error("publish publishStatus (%v) to db error.%v", publishStatus, err)
c.HandleError(err)
return
}
}
cli := c.Client(cluster)

c.Success("ok")
} else {
c.AbortBadRequestFormat("Cluster")
publishHistory := &models.PublishHistory{
Type: models.PublishTypeConfigMap,
ResourceId: int64(configMapId),
ResourceName: kubeConfigMap.Name,
TemplateId: int64(tplId),
Cluster: cluster,
User: c.User.Name,
}
}

// @Title Get
// @Description find ConfigMap by cluster
// @Success 200 {object} models.ConfigMap success
// @router /:configmap/namespaces/:namespace/clusters/:cluster [get]
func (c *KubeConfigMapController) Get() {
cluster := c.Ctx.Input.Param(":cluster")
namespace := c.Ctx.Input.Param(":namespace")
name := c.Ctx.Input.Param(":configmap")
cli, err := client.Client(cluster)
if err == nil {
result, err := configmap.GetConfigMapDetail(cli, name, namespace)

if err != nil {
logs.Error("get kubernetes configmap detail error.", cluster, namespace, name, err)
c.HandleError(err)
return
}
c.Success(result)
defer models.PublishHistoryModel.Add(publishHistory)
// 发布资源到k8s平台
_, err = configmap.CreateOrUpdateConfigMap(cli, &kubeConfigMap)
if err != nil {
publishHistory.Status = models.ReleaseFailure
publishHistory.Message = err.Error()
c.HandleError(err)
return
} else {
c.AbortBadRequestFormat("Cluster")
}
}

// @Title Delete
// @Description delete the ConfigMap
// @Param cluster path string true "the cluster want to delete"
// @Param namespace path string true "the namespace want to delete"
// @Param configmap path string true "the configmap name want to delete"
// @Success 200 {string} delete success!
// @router /:configmap/namespaces/:namespace/clusters/:cluster [delete]
func (c *KubeConfigMapController) Offline() {
cluster := c.Ctx.Input.Param(":cluster")
namespace := c.Ctx.Input.Param(":namespace")
name := c.Ctx.Input.Param(":configmap")
cli, err := client.Client(cluster)
if err == nil {
err := configmap.DeleteConfigMap(cli, name, namespace)
publishHistory.Status = models.ReleaseSuccess
// 添加发布状态
publishStatus := models.PublishStatus{
ResourceId: int64(configMapId),
TemplateId: int64(tplId),
Type: models.PublishTypeConfigMap,
Cluster: cluster,
}
err = models.PublishStatusModel.Publish(&publishStatus)
if err != nil {
logs.Error("delete configmap (%s) by cluster (%s) error.%v", name, cluster, err)
logs.Error("publish publishStatus (%v) to db error.%v", publishStatus, err)
c.HandleError(err)
return
}
c.Success("ok!")
} else {
c.AbortBadRequestFormat("Cluster")
}

c.Success("ok")

}
Loading