Skip to content

Commit

Permalink
v1.28.x (merge request !1280)
Browse files Browse the repository at this point in the history
Squash merge branch 'v1.28.x' into 'v1.28.x'
fix: bcs-cluster-manager version problem
  • Loading branch information
evanlixin authored and wessonli committed Jul 14, 2023
1 parent a340eb9 commit 0bd3e34
Show file tree
Hide file tree
Showing 11 changed files with 2,062 additions and 1,817 deletions.
38 changes: 7 additions & 31 deletions bcs-services/bcs-cluster-manager/api/clustermanager/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ SWAGGEROBJ:=$(patsubst %.proto, %.swagger.json, $(PROTO))

GOENVPATH = $(shell go env GOPATH)

DIRECTORY := $(PWD)
PROTO_IMAGE := "proto"

.PHONY: all clean

all:docker $(OBJ) $(GWOBJ) $(SWAGGEROBJ)
all:$(OBJ) $(GWOBJ) $(SWAGGEROBJ)

$(OBJ):$(PROTO)

Expand All @@ -20,37 +17,16 @@ $(GWOBJ):$(PROTO)
$(SWAGGEROBJ):$(PROTO)

%.pb.go: %.proto
docker run --rm \
-v $(DIRECTORY)/../../third_party:/third_party \
-v $(DIRECTORY):/proto \
${PROTO_IMAGE} \
protoc -I/third_party \
--proto_path=/proto \
--go_out=plugins=grpc:/proto \
--validate_out=lang=go:/proto $<
protoc -I../../third_party --proto_path=. --go_out=plugins=grpc:. --validate_out=lang=go:. $<
sed -i '' 's/json:"-"/json:"-" bson:"-"/g' clustermanager.pb.go

%.pb.gw.go: %.proto
docker run --rm \
-v $(DIRECTORY)/../../third_party:/third_party \
-v $(DIRECTORY):/proto \
${PROTO_IMAGE} \
protoc -I/third_party \
--proto_path=/proto \
--micro_out=/proto \
--grpc-gateway_out=allow_delete_body=true,logtostderr=true,register_func_suffix=Gw:/proto $<
protoc -I../../third_party --proto_path=. --micro_out=. \
--grpc-gateway_out=allow_delete_body=true,logtostderr=true,register_func_suffix=Gw:. $<
# mv clustermanager.micro.go clustermanager.pb.micro.go

%.swagger.json: %.proto
docker run --rm \
-v $(DIRECTORY)/../../third_party:/third_party \
-v $(DIRECTORY):/proto \
${PROTO_IMAGE} \
protoc -I/third_party \
--proto_path=/proto \
--swagger_out=allow_delete_body=true,logtostderr=true:/proto $<

docker:
@docker build -t ${PROTO_IMAGE} .
protoc -I../../third_party --proto_path=. --swagger_out=allow_delete_body=true,logtostderr=true:. $<

clean:
rm -f $(OBJ) $(GWOBJ) $(SWAGGEROBJ)
rm -f $(OBJ) $(GWOBJ) $(SWAGGEROBJ)
3,535 changes: 1,768 additions & 1,767 deletions bcs-services/bcs-cluster-manager/api/clustermanager/clustermanager.pb.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4737,7 +4737,7 @@ message ListProjectClusterResp {
title : "clusterExtraInfo",
description : "集群其他标识信息,cluster结构之外的数据获取"
}];
WebAnnotations web_annotations = 8[(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {
WebAnnotationsV2 web_annotations = 8[(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {
title : "web_annotations",
description : "用户所属项目的集群权限"
}];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9977,7 +9977,7 @@
}
},
"web_annotations": {
"$ref": "#/definitions/clustermanagerWebAnnotations",
"$ref": "#/definitions/clustermanagerWebAnnotationsV2",
"description": "用户所属项目的集群权限",
"title": "web_annotations"
}
Expand Down
256 changes: 256 additions & 0 deletions bcs-services/bcs-cluster-manager/internal/actions/cluster/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import (
"github.com/Tencent/bk-bcs/bcs-common/pkg/odm/drivers"
"github.com/Tencent/bk-bcs/bcs-common/pkg/odm/operator"
"github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/actions"
iauth "github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/auth"
"github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/clusterops"
"github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/utils"
"github.com/Tencent/bk-bcs/bcs-services/pkg/bcs-auth/cluster"
spb "google.golang.org/protobuf/types/known/structpb"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -315,6 +317,182 @@ func (la *ListAction) Handle(ctx context.Context, req *cmproto.ListClusterReq, r
return
}

// ListProjectClusterAction list action for project clusters
type ListProjectClusterAction struct {
ctx context.Context
model store.ClusterManagerModel
iam iam.PermClient

req *cmproto.ListProjectClusterReq
resp *cmproto.ListProjectClusterResp
clusterList []*cmproto.Cluster
}

// NewListProjectClusterAction create list action for project cluster
func NewListProjectClusterAction(model store.ClusterManagerModel, iam iam.PermClient) *ListProjectClusterAction {
return &ListProjectClusterAction{
model: model,
iam: iam,
}
}

func (la *ListProjectClusterAction) validate() error {
if err := la.req.Validate(); err != nil {
return err
}

return nil
}

func (la *ListProjectClusterAction) listProjectCluster() error {
condM := make(operator.M)

if len(la.req.ProjectID) != 0 {
condM["projectid"] = la.req.ProjectID
}

condCluster := operator.NewLeafCondition(operator.Eq, condM)
condStatus := operator.NewLeafCondition(operator.Ne, operator.M{"status": common.StatusDeleted})

branchCond := operator.NewBranchCondition(operator.And, condCluster, condStatus)
clusterList, err := la.model.ListCluster(la.ctx, branchCond, &storeopt.ListOption{})
if err != nil && !errors.Is(err, drivers.ErrTableRecordNotFound) {
blog.Errorf("ListProjectClusterAction ListCluster failed: %v", err)
return err
}

clusterIDList := make([]string, 0)
for i := range clusterList {
if clusterList[i].IsShared {
clusterList[i].IsShared = false
}
la.clusterList = append(la.clusterList, shieldClusterInfo(&clusterList[i]))
clusterIDList = append(clusterIDList, clusterList[i].ClusterID)
}

// return cluster extraInfo
la.resp.ClusterExtraInfo = returnClusterExtraInfo(la.model, clusterList)

// get shared cluster
sharedClusters, err := getSharedCluster(la.model)
if err != nil {
blog.Errorf("ListProjectClusterAction getSharedCluster failed: %v", err)
} else {
la.clusterList = append(la.clusterList, sharedClusters...)
}

// return project user cluster perms & shared cluster perms
la.resp.WebAnnotations = la.getWebAnnotations(la.req.ProjectID, clusterIDList, sharedClusters)

return nil
}

func (la *ListProjectClusterAction) getWebAnnotations(projectID string, clusterIDs []string,
sharedClusters []*cmproto.Cluster) *cmproto.WebAnnotationsV2 {
username := iauth.GetUserFromCtx(la.ctx)

blog.Infof("ListProjectClusterAction GetWebAnnotations user[%s]", username)
// default use request operator
if la.req.Operator == "" {
la.req.Operator = username
}

perms := make(map[string]map[string]interface{}, 0)

// shared cluster perms
sharedClusterIDs := make([]string, 0)
for i := range sharedClusters {
sharedClusterIDs = append(sharedClusterIDs, sharedClusters[i].ClusterID)
}
// shared cluster perms
for _, clusterID := range sharedClusterIDs {
if _, ok := perms[clusterID]; !ok {
perms[clusterID] = auth.GetV3SharedClusterPerm()
}
}

signalPerms, err := getUserClusterPermList(la.iam, actions.PermInfo{
ProjectID: projectID,
UserID: la.req.Operator,
}, clusterIDs)
if err != nil {
blog.Errorf("ListProjectClusterAction GetWebAnnotations user %s cluster perms failed, err: %s",
username, err.Error())
}
for id := range signalPerms {
perms[id] = signalPerms[id]
}

s, err := utils.MarshalInterfaceToValue(perms)
if err != nil {
blog.Errorf("MarshalInterfaceToValue failed, perms %v, err: %s", perms, err.Error())
return nil
}
webAnnotations := &cmproto.WebAnnotationsV2{
Perms: s,
}

return webAnnotations
}

// GetProjectClustersV3Perm get iam v3 perm
func (la *ListProjectClusterAction) GetProjectClustersV3Perm(user actions.PermInfo,
clusterList []string) (map[string]*spb.Struct, error) {
var (
v3Perm map[string]map[string]interface{}
err error
)

v3Perm, err = getUserClusterPermList(la.iam, user, clusterList)
if err != nil {
blog.Errorf("listCluster GetUserClusterPermList failed: %v", err.Error())
return nil, err
}

// trans result for adapt front
v3ResultPerm := make(map[string]*spb.Struct)
for clsID := range v3Perm {
actionPerm, err := spb.NewStruct(v3Perm[clsID])
if err != nil {
return nil, err
}

v3ResultPerm[clsID] = actionPerm
}

return v3ResultPerm, nil
}

func (la *ListProjectClusterAction) setResp(code uint32, msg string) {
la.resp.Code = code
la.resp.Message = msg
la.resp.Result = (code == common.BcsErrClusterManagerSuccess)
la.resp.Data = la.clusterList
}

// Handle list project cluster request
func (la *ListProjectClusterAction) Handle(ctx context.Context,
req *cmproto.ListProjectClusterReq, resp *cmproto.ListProjectClusterResp) {
if req == nil || resp == nil {
blog.Errorf("list project cluster failed, req or resp is empty")
return
}
la.ctx = ctx
la.req = req
la.resp = resp

if err := la.validate(); err != nil {
la.setResp(common.BcsErrClusterManagerInvalidParameter, err.Error())
return
}
if err := la.listProjectCluster(); err != nil {
la.setResp(common.BcsErrClusterManagerDBOperation, err.Error())
return
}
la.setResp(common.BcsErrClusterManagerSuccess, common.BcsErrClusterManagerSuccessStr)
return
}

// ListCommonClusterAction list action for cluster
type ListCommonClusterAction struct {
ctx context.Context
Expand Down Expand Up @@ -608,3 +786,81 @@ func (la *ListMastersInClusterAction) Handle(ctx context.Context,
la.setResp(common.BcsErrClusterManagerSuccess, common.BcsErrClusterManagerSuccessStr)
return
}

// getUserClusterPermList get user clusters perm
func getUserClusterPermList(iam iam.PermClient, user actions.PermInfo,
clusterList []string) (map[string]map[string]interface{}, error) {

permissions := make(map[string]map[string]interface{}, 0)
clusterPerm := cluster.NewBCSClusterPermClient(iam)

actionIDs := []string{cluster.ClusterView.String(), cluster.ClusterManage.String(), cluster.ClusterDelete.String()}
perms, err := clusterPerm.GetMultiClusterMultiActionPermission(user.UserID, user.ProjectID, clusterList, actionIDs)
if err != nil {
blog.Errorf("getUserClusterPermList GetMultiClusterMultiActionPermission failed: %v", err)
return nil, err
}

for clusterID, perm := range perms {
if permissions[clusterID] == nil {
permissions[clusterID] = make(map[string]interface{})
}
for action, res := range perm {
permissions[clusterID][action] = res
}
}

return permissions, nil
}

// getCloudProviderEngine get cluster cloud engineType
func getCloudProviderEngine(model store.ClusterManagerModel, cls cmproto.Cluster) string {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

cloud, err := model.GetCloud(ctx, cls.Provider)
if err != nil {
blog.Errorf("GetCluster[%s] GetCloudProviderEngine failed: %v", cls.ClusterID, err)
return ""
}

return cloud.GetEngineType()
}

// returnClusterExtraInfo return cluster extra info
func returnClusterExtraInfo(model store.ClusterManagerModel,
clusterList []cmproto.Cluster) map[string]*cmproto.ExtraInfo {
extraInfo := make(map[string]*cmproto.ExtraInfo, 0)

// cluster extra info
for i := range clusterList {
extraInfo[clusterList[i].ClusterID] = &cmproto.ExtraInfo{
CanDeleted: true,
ProviderType: getCloudProviderEngine(model, clusterList[i]),
}
}

return extraInfo
}

// getSharedCluster get shared clusters
func getSharedCluster(model store.ClusterManagerModel) ([]*cmproto.Cluster, error) {
condM := make(operator.M)
condM["isshared"] = true
condCluster := operator.NewLeafCondition(operator.Eq, condM)
condStatus := operator.NewLeafCondition(operator.Ne, operator.M{"status": common.StatusDeleted})

branchCond := operator.NewBranchCondition(operator.And, condCluster, condStatus)
clusterList, err := model.ListCluster(context.Background(), branchCond, &storeopt.ListOption{})
if err != nil && !errors.Is(err, drivers.ErrTableRecordNotFound) {
return nil, err
}

clusters := make([]*cmproto.Cluster, 0)

for i := range clusterList {
clusters = append(clusters, shieldClusterInfo(&clusterList[i]))
}

return clusters, nil
}
12 changes: 12 additions & 0 deletions bcs-services/bcs-cluster-manager/internal/actions/cluster/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,18 @@ func getNodeDualAddress(node *corev1.Node) (string, string) {
return utils.SliceToString(ipv4s), utils.SliceToString(ipv6s)
}

// IsSupportAutoScale support autoscale feat
func IsSupportAutoScale(cls proto.Cluster) bool {
if cls.ClusterType == common.ClusterTypeVirtual {
return false
}
if cls.ClusterCategory == Importer && cls.ImportCategory == KubeConfig {
return false
}

return true
}

func shieldClusterInfo(cluster *proto.Cluster) *proto.Cluster {
if cluster != nil {
cluster.KubeConfig = ""
Expand Down
1 change: 0 additions & 1 deletion bcs-services/bcs-cluster-manager/internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ var NoAuthMethod = []string{
"ClusterManager.CheckCloudKubeConfig",
"ClusterManager.ListCommonCluster",
"ClusterManager.CheckNodeInCluster",
"ClusterManager.ListProjectCluster",

// cloud
"ClusterManager.GetCloud",
Expand Down
9 changes: 9 additions & 0 deletions bcs-services/bcs-cluster-manager/internal/auth/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
package auth

import (
"context"

"github.com/Tencent/bk-bcs/bcs-common/pkg/auth/jwt"
middleauth "github.com/Tencent/bk-bcs/bcs-services/pkg/bcs-auth/middleware"

"github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/options"
)
Expand All @@ -40,3 +43,9 @@ func InitJWTClient(op *options.ClusterManagerOptions) error {
func GetJWTClient() *jwt.JWTClient {
return jwtClient
}

// GetUserFromCtx 通过 ctx 获取当前用户
func GetUserFromCtx(ctx context.Context) string {
authUser, _ := middleauth.GetUserFromContext(ctx)
return authUser.GetUsername()
}
Loading

0 comments on commit 0bd3e34

Please sign in to comment.