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

添加业务拓扑的权限视图 #8130

Open
wants to merge 1 commit into
base: v3.14.x
Choose a base branch
from
Open
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
24 changes: 16 additions & 8 deletions src/ac/iam/initial_instance_selections.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,6 @@ func GenerateStaticInstanceSelections() []InstanceSelection {
ResourceTypeChain: []ResourceChain{
// select the business at first.
businessChain,
// {
// SystemID: SystemIDCMDB,
// ID: Set,
// },
// {
// SystemID: SystemIDCMDB,
// ID: Module,
// },
// then select the host instances.
{
SystemID: SystemIDCMDB,
Expand Down Expand Up @@ -296,5 +288,21 @@ func GenerateStaticInstanceSelections() []InstanceSelection {
ID: GeneralCache,
}},
},
// only for other system's biz topo instance selection usage, not related to actions
{
ID: BizTopoSelection,
Name: "业务拓扑",
NameEn: "Business Topology",
ResourceTypeChain: []ResourceChain{
businessChain,
{
SystemID: SystemIDCMDB,
ID: Set,
}, {
SystemID: SystemIDCMDB,
ID: Module,
},
},
},
}
}
58 changes: 30 additions & 28 deletions src/ac/iam/initial_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ var ResourceTypeIDMap = map[TypeID]string{
BizProcessServiceTemplate: "服务模板",
FieldGroupingTemplate: "字段组合模板",
GeneralCache: "通用缓存",
Set: "集群",
Module: "模块",
}

// GenerateResourceTypes generate all the resource types registered to IAM.
Expand Down Expand Up @@ -210,34 +212,34 @@ func genBusinessResources() []ResourceType {
},
Version: 1,
},
// only for host topology usage, not related to actions
// {
// ID: Set,
// Name: ResourceTypeIDMap[Set],
// NameEn: "Set",
// Description: "集群列表",
// DescriptionEn: "all the sets in blueking cmdb.",
// Parents: []Parent{businessParent},
// ProviderConfig: ResourceConfig{
// Path: "/auth/v3/find/resource",
// },
// Version: 1,
// },
// {
// ID: Module,
// Name: ResourceTypeIDMap[Module],
// NameEn: "Module",
// Description: "模块列表",
// DescriptionEn: "all the modules in blueking cmdb.",
// Parents: []Parent{{
// SystemID: SystemIDCMDB,
// ResourceID: Set,
// }},
// ProviderConfig: ResourceConfig{
// Path: "/auth/v3/find/resource",
// },
// Version: 1,
// },
// only for biz topology usage, not related to actions
{
ID: Set,
Name: ResourceTypeIDMap[Set],
NameEn: "Set",
Description: "业务拓扑集群",
DescriptionEn: "business topology set",
Parents: []Parent{businessParent},
ProviderConfig: ResourceConfig{
Path: "/auth/v3/find/resource",
},
Version: 1,
},
{
ID: Module,
Name: ResourceTypeIDMap[Module],
NameEn: "Module",
Description: "业务拓扑模块",
DescriptionEn: "business topology module",
Parents: []Parent{{
SystemID: SystemIDCMDB,
ResourceID: Set,
}},
ProviderConfig: ResourceConfig{
Path: "/auth/v3/find/resource",
},
Version: 1,
},
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/ac/iam/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ const (
// GeneralCache defines general resource cache auth type
GeneralCache TypeID = "general_cache"

// Set is set auth type
Set TypeID = "set"
// Module is module auth type
Module TypeID = "module"

// SkipType TODO
// for resource type, which is not need to be authorized
SkipType TypeID = "skip_type"
Expand Down Expand Up @@ -743,6 +748,8 @@ const (
SysHostRscPoolDirectorySelection InstanceSelectionID = "sys_host_rsc_pool_directory"
// GeneralCacheSelection general resource cache instance selection id
GeneralCacheSelection InstanceSelectionID = "general_cache"
// BizTopoSelection is biz topo instance selection id
BizTopoSelection InstanceSelectionID = "biz_topo"
)

// InstanceSelection TODO
Expand Down
1 change: 1 addition & 0 deletions src/common/metadata/inst.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type SetInst struct {
SetEnv string `bson:"bk_set_env" json:"bk_set_env" mapstructure:"bk_set_env"`
SetTemplateID int64 `bson:"set_template_id" json:"set_template_id" mapstructure:"set_template_id"`
ParentID int64 `bson:"bk_parent_id" json:"bk_parent_id" mapstructure:"bk_parent_id"`
Default int `bson:"default" json:"default" field:"default" mapstructure:"default"`

Creator string `field:"creator" json:"creator,omitempty" bson:"creator" mapstructure:"creator"`
CreateTime Time `field:"create_time" json:"create_time,omitempty" bson:"create_time" mapstructure:"create_time"`
Expand Down
14 changes: 14 additions & 0 deletions src/common/metadata/instance_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,17 @@ type ProcInstanceData struct {
Count int `json:"count"`
Info []Process `json:"info"`
}

// ResponseMainlineInst mainline instance response
// 只有主线模型实例的企业版本部分属性,使用前请注意
type ResponseMainlineInst struct {
BaseResp `json:",inline"`
Data MainlineInstData `json:"data"`
}

// MainlineInstData mainline instance data
// 只有主线模型实例的企业版本部分属性,使用前请注意
type MainlineInstData struct {
Count int `json:"count"`
Info []MainlineInstInfo `json:"info"`
}
219 changes: 219 additions & 0 deletions src/scene_server/auth_server/logics/list_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,3 +476,222 @@ func (lgc *Logics) ValidateListInstanceRequest(kit *rest.Kit, req *types.PullRes
}
return &filter, nil
}

// ListSetInstance list biz topo set instances
func (lgc *Logics) ListSetInstance(kit *rest.Kit, resourceType iam.TypeID, filter *types.ListInstanceFilter,
page types.Page) (*types.ListInstanceResult, error) {

if filter == nil || filter.Parent == nil || filter.Parent.Type != iam.Business {
return &types.ListInstanceResult{Count: 0, Results: make([]types.InstanceResource, 0)}, nil
}

bizID, err := strconv.ParseInt(filter.Parent.ID, 10, 64)
if err != nil {
blog.Errorf("parse filter.parent.id %s failed, err: %v, rid: %s", filter.Parent.ID, err, kit.Rid)
return &types.ListInstanceResult{Count: 0, Results: make([]types.InstanceResource, 0)}, nil
}

// read mainline object association and construct mainline topo relation map
queryCond := &metadata.QueryCondition{
Condition: map[string]interface{}{common.AssociationKindIDField: common.AssociationKindMainline},
Fields: []string{common.BKObjIDField, common.BKAsstObjIDField},
}
mlAsstRsp, err := lgc.CoreAPI.CoreService().Association().ReadModelAssociation(kit.Ctx, kit.Header, queryCond)
if err != nil {
blog.Errorf("search mainline association failed, err: %v, cond: %+v, rid: %s", err, queryCond, kit.Rid)
return nil, err
}
topoChildMap, topoParentMap := make(map[string]string), make(map[string]string)
for _, asst := range mlAsstRsp.Info {
if asst.ObjectID == common.BKInnerObjIDHost || asst.ObjectID == common.BKInnerObjIDModule {
continue
}
topoChildMap[asst.AsstObjID] = asst.ObjectID
topoParentMap[asst.ObjectID] = asst.AsstObjID
}

// generate set cond by biz id and keyword
cond := make(mapstr.MapStr)
if len(filter.Keyword) != 0 {
cond, err = lgc.genSetKeywordCond(kit, bizID, topoChildMap, filter.Keyword)
if err != nil {
return nil, err
}
}

cond[common.BKAppIDField] = bizID
setCond := &metadata.QueryCondition{
Condition: cond,
Fields: []string{common.BKSetIDField, common.BKSetNameField, common.BKParentIDField, common.BKDefaultField},
Page: metadata.BasePage{
Limit: int(page.Limit),
Start: int(page.Offset),
},
}

return lgc.listSetInstance(kit, setCond, topoParentMap)
}

func (lgc *Logics) genSetKeywordCond(kit *rest.Kit, bizID int64, topoChildMap map[string]string, keyword string) (
map[string]interface{}, error) {

// filter all mainline instances that matches the keyword
cond := mapstr.MapStr{
common.BKInstNameField: mapstr.MapStr{
common.BKDBLIKE: keyword,
common.BKDBOPTIONS: "i",
},
common.BKAppIDField: bizID,
}

for obj := topoChildMap[common.BKInnerObjIDApp]; obj != common.BKInnerObjIDSet; obj = topoChildMap[obj] {
instReq := &metadata.QueryCondition{
Condition: cond,
Fields: []string{common.BKInstIDField},
Page: metadata.BasePage{Limit: common.BKNoLimit},
}

instResp := new(metadata.ResponseMainlineInst)
err := lgc.CoreAPI.CoreService().Instance().ReadInstanceStruct(kit.Ctx, kit.Header, obj, instReq, instResp)
if err != nil {
blog.Errorf("search %s inst failed, err: %v, cond: %+v, rid: %s", obj, err, instReq, kit.Rid)
return nil, err
}
if err = instResp.CCError(); err != nil {
blog.Errorf("search %s inst failed, err: %v, cond: %+v, rid: %s", obj, err, instReq, kit.Rid)
return nil, err
}

parentIDs := make([]int64, 0)
for _, inst := range instResp.Data.Info {
parentIDs = append(parentIDs, inst.InstID)
}

cond = mapstr.MapStr{
common.GetInstNameField(topoChildMap[obj]): mapstr.MapStr{
common.BKDBLIKE: keyword,
common.BKDBOPTIONS: "i",
},
}

if len(parentIDs) != 0 {
cond = mapstr.MapStr{
common.BKDBOR: []mapstr.MapStr{
{common.BKParentIDField: mapstr.MapStr{common.BKDBIN: util.IntArrayUnique(parentIDs)}},
cond,
},
}
}
}

return cond, nil
}

func (lgc *Logics) listSetInstance(kit *rest.Kit, setCond *metadata.QueryCondition, topoParentMap map[string]string) (
*types.ListInstanceResult, error) {

// search set
setResp := new(metadata.ResponseSetInstance)
if err := lgc.CoreAPI.CoreService().Instance().ReadInstanceStruct(kit.Ctx, kit.Header, common.BKInnerObjIDSet,
setCond, setResp); err != nil {
blog.Errorf("search set failed, err: %v, cond: %+v, rid: %s", err, setCond, kit.Rid)
return nil, err
}
if err := setResp.CCError(); err != nil {
blog.Errorf("search set failed, err: %v, cond: %+v, rid: %s", err, setCond, kit.Rid)
return nil, err
}

parentIDs := make([]int64, 0)
for _, set := range setResp.Data.Info {
if set.Default != common.DefaultResSetFlag {
parentIDs = append(parentIDs, set.ParentID)
}
}

// get set parent mainline instance info
objInstMap := make(map[string]map[int64]metadata.MainlineInstInfo)
for obj := topoParentMap[common.BKInnerObjIDSet]; obj != common.BKInnerObjIDApp; obj = topoParentMap[obj] {
objInstMap[obj] = make(map[int64]metadata.MainlineInstInfo)
if len(parentIDs) == 0 {
break
}
parentIDs = util.IntArrayUnique(parentIDs)

instCond := &metadata.QueryCondition{
Condition: mapstr.MapStr{common.BKInstIDField: mapstr.MapStr{common.BKDBIN: parentIDs}},
Fields: []string{common.BKInstIDField, common.BKInstNameField, common.BKParentIDField},
Page: metadata.BasePage{Limit: len(parentIDs)},
}

instResp := new(metadata.ResponseMainlineInst)
err := lgc.CoreAPI.CoreService().Instance().ReadInstanceStruct(kit.Ctx, kit.Header, obj, instCond, instResp)
if err != nil {
blog.Errorf("search %s inst failed, err: %v, cond: %+v, rid: %s", obj, err, instCond, kit.Rid)
return nil, err
}
if err = instResp.CCError(); err != nil {
blog.Errorf("search %s inst failed, err: %v, cond: %+v, rid: %s", obj, err, instCond, kit.Rid)
return nil, err
}

parentIDs = make([]int64, 0)
for _, inst := range instResp.Data.Info {
parentIDs = append(parentIDs, inst.ParentID)
objInstMap[obj][inst.InstID] = inst
}
}

// add mainline topo path to set display name
instances := make([]types.InstanceResource, len(setResp.Data.Info))
for i, set := range setResp.Data.Info {
instances[i] = types.InstanceResource{
ID: strconv.FormatInt(set.SetID, 10),
DisplayName: set.SetName,
}

// default set do not need to add mainline topo path
if set.Default == common.DefaultResSetFlag {
continue
}

parentID := set.ParentID
for obj := topoParentMap[common.BKInnerObjIDSet]; obj != common.BKInnerObjIDApp; obj = topoParentMap[obj] {
instInfo, exists := objInstMap[obj][parentID]
if !exists {
break
}
instances[i].DisplayName = instInfo.InstName + " / " + instances[i].DisplayName
parentID = instInfo.ParentID
}
}

return &types.ListInstanceResult{Count: int64(setResp.Data.Count), Results: instances}, nil
}

// ListModuleInstance list biz topo module instances
func (lgc *Logics) ListModuleInstance(kit *rest.Kit, resourceType iam.TypeID, filter *types.ListInstanceFilter,
page types.Page) (*types.ListInstanceResult, error) {

if filter == nil || filter.Parent == nil || filter.Parent.Type != iam.Set {
return &types.ListInstanceResult{Count: 0, Results: make([]types.InstanceResource, 0)}, nil
}

setID, err := strconv.ParseInt(filter.Parent.ID, 10, 64)
if err != nil {
blog.Errorf("parse filter.parent.id %s failed, err: %v, rid: %s", filter.Parent.ID, err, kit.Rid)
return &types.ListInstanceResult{Count: 0, Results: make([]types.InstanceResource, 0)}, nil
}

cond := map[string]interface{}{
common.BKSetIDField: setID,
}

if len(filter.Keyword) != 0 {
cond[common.BKModuleNameField] = map[string]interface{}{
common.BKDBLIKE: filter.Keyword,
common.BKDBOPTIONS: "i",
}
}
return lgc.listInstance(kit, cond, resourceType, page)
}
Loading