From f79a5d9b77fcb257fe16749502708c8028fe46ab Mon Sep 17 00:00:00 2001 From: kookouse Date: Thu, 16 Jan 2025 11:17:34 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=AE=89=E5=85=A8=E7=BB=84-?= =?UTF-8?q?=E8=B5=84=E6=BA=90=20=E5=85=B3=E8=81=94=E5=85=B3=E7=B3=BB?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=88=B0common=E8=A1=A8=20--story=3D12167893?= =?UTF-8?q?6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/cvm/batch_associate.go | 8 +- cmd/cloud-server/service/cvm/query.go | 19 +- .../service/cvm/security_group_rule.go | 5 +- .../service/security-group/query.go | 11 +- .../security-group/related_resource.go | 3 + .../cloud/security-group-common-rel/create.go | 63 +++++++ .../cvm-rel-manager/cvm_security_group_rel.go | 170 ++++++++++-------- cmd/hc-service/service/cvm/aws.go | 76 ++++++-- cmd/hc-service/service/cvm/cvm.go | 58 ++++++ cmd/hc-service/service/cvm/tcloud.go | 20 +-- .../security-group/aws_security_group.go | 73 ++++++-- .../security-group/huawei_security_group.go | 74 ++++++-- .../service/security-group/logics.go | 87 +++++++-- .../security-group/tcloud_security_group.go | 107 +++++++---- .../global/security_group_cvm_rel.go | 4 + .../security_group_common_rel.go | 34 +--- 16 files changed, 576 insertions(+), 236 deletions(-) diff --git a/cmd/cloud-server/service/cvm/batch_associate.go b/cmd/cloud-server/service/cvm/batch_associate.go index f0c6352cfd..6cfc933c78 100644 --- a/cmd/cloud-server/service/cvm/batch_associate.go +++ b/cmd/cloud-server/service/cvm/batch_associate.go @@ -115,9 +115,13 @@ func (svc *cvmSvc) batchAssociateSecurityGroups(cts *rest.Contexts, validHandler func (svc *cvmSvc) deleteSecurityGroupAndCvmRelationship(kt *kit.Kit, cvmID string, sgIDs []string) error { batchDeleteReq := &proto.BatchDeleteReq{ - Filter: tools.ExpressionAnd(tools.RuleEqual("cvm_id", cvmID), tools.RuleIn("security_group_id", sgIDs)), + Filter: tools.ExpressionAnd( + tools.RuleEqual("res_id", cvmID), + tools.RuleEqual("res_type", enumor.CvmCloudResType), + tools.RuleIn("security_group_id", sgIDs), + ), } - err := svc.client.DataService().Global.SGCvmRel.BatchDeleteSgCvmRels(kt.Ctx, kt.Header(), batchDeleteReq) + err := svc.client.DataService().Global.SGCommonRel.BatchDeleteSgCommonRels(kt, batchDeleteReq) if err != nil { logs.Errorf("delete security group and cvm relationship failed, err: %v, req: %+v, rid: %s", err, batchDeleteReq, kt.Rid) diff --git a/cmd/cloud-server/service/cvm/query.go b/cmd/cloud-server/service/cvm/query.go index 9fb6e28d1b..86d4bd487d 100644 --- a/cmd/cloud-server/service/cvm/query.go +++ b/cmd/cloud-server/service/cvm/query.go @@ -297,7 +297,7 @@ func (svc *cvmSvc) listCvmSecurityGroups(cts *rest.Contexts, authHandler handler itemMap := convertToBatchListCvmSecurityGroupsRespItem(securityGroupsMap) cvmToSgMap := make(map[string][]cscvm.BatchListCvmSecurityGroupsRespItem, len(req.CvmIDs)) for _, rel := range rels { - cvmToSgMap[rel.CvmID] = append(cvmToSgMap[rel.CvmID], itemMap[rel.SecurityGroupID]) + cvmToSgMap[rel.ResID] = append(cvmToSgMap[rel.ResID], itemMap[rel.SecurityGroupID]) } result := make([]cscvm.BatchListCvmSecurityGroupsResp, len(req.CvmIDs)) @@ -346,26 +346,27 @@ func (svc *cvmSvc) getSecurityGroupsMap(kt *kit.Kit, sgIDs []string) (map[string return result, nil } -func (svc *cvmSvc) listCvmSecurityGroupRels(kt *kit.Kit, cvmIDs []string) ([]cloud.SecurityGroupCvmRel, error) { +func (svc *cvmSvc) listCvmSecurityGroupRels(kt *kit.Kit, cvmIDs []string) ([]cloud.SecurityGroupCommonRel, error) { - result := make([]cloud.SecurityGroupCvmRel, 0) + result := make([]cloud.SecurityGroupCommonRel, 0) req := &core.ListReq{ - Filter: tools.ContainersExpression("cvm_id", cvmIDs), - Page: core.NewDefaultBasePage(), + Filter: tools.ExpressionAnd( + tools.RuleIn("res_id", cvmIDs), + tools.RuleEqual("res_type", enumor.CvmCloudResType), + ), + Page: core.NewDefaultBasePage(), } for { - sgCvmRels, err := svc.client.DataService().Global.SGCvmRel.ListSgCvmRels(kt.Ctx, kt.Header(), req) + sgCvmRels, err := svc.client.DataService().Global.SGCommonRel.ListSgCommonRels(kt, req) if err != nil { return nil, err } if len(sgCvmRels.Details) == 0 { break } - for _, detail := range sgCvmRels.Details { - result = append(result, detail) - } + result = append(result, sgCvmRels.Details...) req.Page.Start += uint32(core.DefaultMaxPageLimit) } diff --git a/cmd/cloud-server/service/cvm/security_group_rule.go b/cmd/cloud-server/service/cvm/security_group_rule.go index 2bf880ce97..831c69817a 100644 --- a/cmd/cloud-server/service/cvm/security_group_rule.go +++ b/cmd/cloud-server/service/cvm/security_group_rule.go @@ -110,12 +110,13 @@ func (svc *cvmSvc) listCvmSecurityGroupRules(kt *kit.Kit, vendor enumor.Vendor, func (svc *cvmSvc) checkCvmAndSecurityGroupRel(kt *kit.Kit, cvmID, sgID string) error { checkReq := &core.ListReq{ Filter: tools.ExpressionAnd( - tools.RuleEqual("cvm_id", cvmID), + tools.RuleEqual("res_id", cvmID), tools.RuleEqual("security_group_id", sgID), + tools.RuleEqual("res_type", enumor.CvmCloudResType), ), Page: core.NewCountPage(), } - rels, err := svc.client.DataService().Global.SGCvmRel.ListSgCvmRels(kt.Ctx, kt.Header(), checkReq) + rels, err := svc.client.DataService().Global.SGCommonRel.ListSgCommonRels(kt, checkReq) if err != nil { logs.Errorf("check cvm and security group relation failed, err: %v, rid: %s", err, kt.Rid) return err diff --git a/cmd/cloud-server/service/security-group/query.go b/cmd/cloud-server/service/security-group/query.go index 04f4a25097..c206c34a30 100644 --- a/cmd/cloud-server/service/security-group/query.go +++ b/cmd/cloud-server/service/security-group/query.go @@ -141,10 +141,13 @@ func (svc *securityGroupSvc) getSecurityGroup(cts *rest.Contexts, validHandler h func (svc *securityGroupSvc) queryAssociateCvmCount(kt *kit.Kit, id string) (uint64, error) { cvmRelOpt := &core.ListReq{ - Filter: tools.EqualExpression("security_group_id", id), - Page: core.NewCountPage(), + Filter: tools.ExpressionAnd( + tools.RuleEqual("security_group_id", id), + tools.RuleEqual("res_type", enumor.CvmCloudResType), + ), + Page: core.NewCountPage(), } - cvmRelResult, err := svc.client.DataService().Global.SGCvmRel.ListSgCvmRels(kt.Ctx, kt.Header(), cvmRelOpt) + cvmRelResult, err := svc.client.DataService().Global.SGCommonRel.ListSgCommonRels(kt, cvmRelOpt) if err != nil { return 0, err } @@ -231,11 +234,13 @@ func (svc *securityGroupSvc) listSecurityGroup(cts *rest.Contexts, authHandler h } // ListSecurityGroupsByCvmID list security groups by cvm_id. +// Deprecated: use ListSecurityGroupsByResID instead. func (svc *securityGroupSvc) ListSecurityGroupsByCvmID(cts *rest.Contexts) (interface{}, error) { return svc.listSGByCvmID(cts, handler.ResOperateAuth) } // ListBizSecurityGroupsByCvmID list biz security groups by cvm_id. +// Deprecated: use ListBizSecurityGroupsByResID instead. func (svc *securityGroupSvc) ListBizSecurityGroupsByCvmID(cts *rest.Contexts) (interface{}, error) { return svc.listSGByCvmID(cts, handler.BizOperateAuth) } diff --git a/cmd/cloud-server/service/security-group/related_resource.go b/cmd/cloud-server/service/security-group/related_resource.go index aa745c5740..ae4ff332a7 100644 --- a/cmd/cloud-server/service/security-group/related_resource.go +++ b/cmd/cloud-server/service/security-group/related_resource.go @@ -70,15 +70,18 @@ func (svc *securityGroupSvc) listResourceIdBySecurityGroup(cts *rest.Contexts, v } // ListCvmIdBySecurityGroup list cvm id by security group +// Deprecated: table[security_group_cvm_rel] is deprecated. Use ListResourceIdBySecurityGroup instead. func (svc *securityGroupSvc) ListCvmIdBySecurityGroup(cts *rest.Contexts) (interface{}, error) { return svc.listCvmIDBySecurityGroup(cts, handler.ResOperateAuth) } // ListBizCvmIdBySecurityGroup list biz cvm id by security group +// Deprecated: table[security_group_cvm_rel] is deprecated. Use ListBizResourceIDBySecurityGroup instead. func (svc *securityGroupSvc) ListBizCvmIdBySecurityGroup(cts *rest.Contexts) (interface{}, error) { return svc.listCvmIDBySecurityGroup(cts, handler.BizOperateAuth) } +// Deprecated: table[security_group_cvm_rel] is deprecated. func (svc *securityGroupSvc) listCvmIDBySecurityGroup(cts *rest.Contexts, validHandler handler.ValidWithAuthHandler) (interface{}, error) { id := cts.PathParameter("id").String() if len(id) == 0 { diff --git a/cmd/data-service/service/cloud/security-group-common-rel/create.go b/cmd/data-service/service/cloud/security-group-common-rel/create.go index f34ebca272..26d9dc0d8f 100644 --- a/cmd/data-service/service/cloud/security-group-common-rel/create.go +++ b/cmd/data-service/service/cloud/security-group-common-rel/create.go @@ -24,13 +24,17 @@ import ( "hcm/pkg/api/core" protocloud "hcm/pkg/api/data-service/cloud" + "hcm/pkg/criteria/enumor" "hcm/pkg/criteria/errf" "hcm/pkg/dal/dao/orm" "hcm/pkg/dal/dao/tools" "hcm/pkg/dal/dao/types" tablecloud "hcm/pkg/dal/table/cloud" + "hcm/pkg/kit" "hcm/pkg/logs" "hcm/pkg/rest" + "hcm/pkg/tools/converter" + "hcm/pkg/tools/slice" "github.com/jmoiron/sqlx" ) @@ -59,6 +63,11 @@ func (svc *sgComRelSvc) BatchCreateSgCommonRels(cts *rest.Contexts) (interface{} }) } + // check relation resource is existed + if err := svc.checkRelationResourceExist(cts.Kit, req.Rels); err != nil { + logs.Errorf("check relation resource exist failed, err: %v, rid: %s", err, cts.Kit.Rid) + return nil, nil + } if err := svc.dao.SGCommonRel().BatchCreateWithTx(cts.Kit, txn, models); err != nil { return nil, fmt.Errorf("batch create sg common rels failed, err: %v", err) } @@ -125,6 +134,12 @@ func (svc *sgComRelSvc) BatchUpsertSgCommonRels(cts *rest.Contexts) (interface{} Creator: cts.Kit.User, }) } + // check relation resource is existed + if err := svc.checkRelationResourceExist(cts.Kit, req.Rels); err != nil { + logs.Errorf("check relation resource exist failed, err: %v, rid: %s", err, cts.Kit.Rid) + return nil, nil + } + if err := svc.dao.SGCommonRel().BatchCreateWithTx(cts.Kit, txn, models); err != nil { return nil, fmt.Errorf("batch create sg common rels failed, err: %v", err) } @@ -137,3 +152,51 @@ func (svc *sgComRelSvc) BatchUpsertSgCommonRels(cts *rest.Contexts) (interface{} return nil, nil } + +func (svc *sgComRelSvc) checkRelationResourceExist(kt *kit.Kit, rels []protocloud.SGCommonRelCreate) error { + // check relation resource is existed + // 校验关联资源是否存在 + sgIDs := make([]string, 0) + resTypeToResIDsMap := make(map[enumor.CloudResourceType][]string) + for _, rel := range rels { + sgIDs = append(sgIDs, rel.SecurityGroupID) + resTypeToResIDsMap[rel.ResType] = append(resTypeToResIDsMap[rel.ResType], rel.ResID) + } + + sgMap := make(map[string]tablecloud.SecurityGroupTable) + for _, ids := range slice.Split(sgIDs, int(core.DefaultMaxPageLimit)) { + listOpt := &types.ListOption{ + Filter: tools.ContainersExpression("id", ids), + Page: core.NewDefaultBasePage(), + } + resp, err := svc.dao.SecurityGroup().List(kt, listOpt) + if err != nil { + logs.Errorf("list security group failed, err: %v, ids: %v, rid: %s", err, ids, kt.Rid) + return err + } + for _, detail := range resp.Details { + sgMap[detail.ID] = detail + } + } + + if len(sgMap) != len(converter.StringSliceToMap(sgIDs)) { + logs.Errorf("get security group count not right, ids: %v, count: %d, rid: %s", sgIDs, len(sgMap), kt.Rid) + return fmt.Errorf("get security group count not right") + } + + for resType, resIDs := range resTypeToResIDsMap { + dbResp, err := svc.dao.Cloud().ListResourceIDs(kt, resType, tools.ContainersExpression("id", resIDs)) + if err != nil { + logs.Errorf("list resource ids failed, err: %v, resType: %s, resIDs: %v, rid: %s", + err, resType, resIDs, kt.Rid) + return err + } + if len(dbResp) != len(converter.StringSliceToMap(resIDs)) { + logs.Errorf("get resource count not right, err: %v, resType: %s, resIDs: %v, rid: %s", + err, resType, resIDs, kt.Rid) + return fmt.Errorf("get resource count not right") + } + } + + return nil +} diff --git a/cmd/hc-service/logics/res-sync/cvm-rel-manager/cvm_security_group_rel.go b/cmd/hc-service/logics/res-sync/cvm-rel-manager/cvm_security_group_rel.go index 80889c7884..39cc31cc09 100644 --- a/cmd/hc-service/logics/res-sync/cvm-rel-manager/cvm_security_group_rel.go +++ b/cmd/hc-service/logics/res-sync/cvm-rel-manager/cvm_security_group_rel.go @@ -20,10 +20,12 @@ package cvmrelmgr import ( + "sort" + "hcm/pkg/api/core" + "hcm/pkg/api/core/cloud" dataproto "hcm/pkg/api/data-service" datacloud "hcm/pkg/api/data-service/cloud" - "hcm/pkg/criteria/constant" "hcm/pkg/criteria/enumor" "hcm/pkg/dal/dao/tools" "hcm/pkg/kit" @@ -31,6 +33,9 @@ import ( "hcm/pkg/tools/slice" ) +// syncCvmSGRel sync cvm securityGroup rel. +// getCvmIDWithAssResIDMap CvmAppendAssResCloudID +// 根据上面两个方法可以得知 获取到的sg列表是有序的,按照这个顺序作为优先级写入关联关系表即可 func (mgr *CvmRelManger) syncCvmSGRel(kt *kit.Kit, cvmMap map[string]string, opt *SyncRelOption) error { if err := opt.Validate(); err != nil { @@ -43,119 +48,128 @@ func (mgr *CvmRelManger) syncCvmSGRel(kt *kit.Kit, cvmMap map[string]string, opt return err } - cvmIDs, cvmRelMapFromCloud, err := mgr.getCvmIDWithAssResIDMap(enumor.SecurityGroupCloudResType, cvmMap, + cvmIDs, cvmIDToSgIDMapFromCloud, err := mgr.getCvmIDWithAssResIDMap(enumor.SecurityGroupCloudResType, cvmMap, securityGroupMap) if err != nil { logs.Errorf("get cvm id with ass res id map failed, err: %v, rid: %s", err, kt.Rid) return err } - cvmRelMapFromDB, err := mgr.getCvmSGRelMapFromDB(kt, cvmIDs) + cvmIDToRelsFromDB, err := mgr.listCvmSGRelsFromDB(kt, cvmIDs) if err != nil { logs.Errorf("get cvm_sg_rel map from db failed, err: %v, rid: %s", err, kt.Rid) return err } - addRels, delIDs := diffCvmWithAssResRel(cvmRelMapFromCloud, cvmRelMapFromDB) - - if len(addRels) > 0 { - if err = mgr.createCvmSGRel(kt, addRels); err != nil { - return err - } - } - - if len(delIDs) > 0 { - if err = mgr.deleteCvmSGRel(kt, delIDs); err != nil { - return err - } + err = mgr.compareCvmSGRel(kt, cvmIDToSgIDMapFromCloud, cvmIDToRelsFromDB, opt.Vendor) + if err != nil { + logs.Errorf("compare cvm sg rel failed, err: %v, rid: %s", err, kt.Rid) + return err } - return nil } -func (mgr *CvmRelManger) getCvmSGRelMapFromDB(kt *kit.Kit, cvmIDs []string) ( - map[string]map[string]cvmRelInfo, error) { - - listReq := &core.ListReq{ - Filter: tools.ContainersExpression("cvm_id", cvmIDs), - Page: &core.BasePage{ - Start: 0, - Limit: core.DefaultMaxPageLimit, - }, - } - result := make(map[string]map[string]cvmRelInfo) - for { - respResult, err := mgr.dataCli.Global.SGCvmRel.ListSgCvmRels(kt.Ctx, kt.Header(), listReq) - if err != nil { - logs.Errorf("list securityGroup cvm rel failed, err: %v, rid: %s", err, kt.Rid) - return nil, err - } - - for _, rel := range respResult.Details { - if _, exist := result[rel.CvmID]; !exist { - result[rel.CvmID] = make(map[string]cvmRelInfo) - } - - result[rel.CvmID][rel.SecurityGroupID] = cvmRelInfo{ - RelID: rel.ID, - AssResID: rel.SecurityGroupID, +func (mgr *CvmRelManger) compareCvmSGRel(kt *kit.Kit, cvmIDToSgIDMapFromCloud map[string][]string, + cvmIDToSGRelsMapFromDB map[string][]cloud.SGCommonRelWithBaseSecurityGroup, vendor enumor.Vendor) error { + + for cvmID, sgIDs := range cvmIDToSgIDMapFromCloud { + localSGRels := cvmIDToSGRelsMapFromDB[cvmID] + // 按优先级从小到大排序 + sort.Slice(localSGRels, func(i, j int) bool { + return localSGRels[i].Priority < localSGRels[j].Priority + }) + localLen := len(localSGRels) + cloudLen := len(sgIDs) + // 找到所有相等的列表 + var idx int + var sgID string + var stayLocalIDs []string + for ; idx < cloudLen; idx++ { + sgID = sgIDs[idx] + if idx >= localLen || localSGRels[idx].ID != sgID || localSGRels[idx].Priority != int64(idx+1) { + // 剩下的全部加入新增列表里 + break } + // 加入可以保留的安全组id列表中 + stayLocalIDs = append(stayLocalIDs, sgID) } - - if len(respResult.Details) < int(core.DefaultMaxPageLimit) { - break + err := mgr.upsertSgRelForCvm(kt, cvmID, idx, stayLocalIDs, sgIDs[idx:], vendor) + if err != nil { + logs.Errorf("fail to upsert cvm(%s) security group rel, err: %v, rid: %s", cvmID, err, kt.Rid) + return err } - listReq.Page.Start += uint32(len(respResult.Details)) } - return result, nil + return nil } -func (mgr *CvmRelManger) deleteCvmSGRel(kt *kit.Kit, ids []uint64) error { - - split := slice.Split(ids, constant.BatchOperationMaxLimit) - for _, partIDs := range split { - batchDeleteReq := &dataproto.BatchDeleteReq{ - Filter: tools.ContainersExpression("id", partIDs), - } +func (mgr *CvmRelManger) upsertSgRelForCvm(kt *kit.Kit, cvmID string, startIdx int, stayLocalIDs []string, + sgIDs []string, vendor enumor.Vendor) error { + + createDel := &datacloud.SGCommonRelBatchUpsertReq{Rels: make([]datacloud.SGCommonRelCreate, 0)} + // 删除所有不在给定id中的安全组,防止误删 + createDel.DeleteReq = &dataproto.BatchDeleteReq{Filter: tools.ExpressionAnd( + tools.RuleEqual("res_type", enumor.CvmCloudResType), + tools.RuleEqual("res_id", cvmID), + )} + for i, sgID := range sgIDs { + createDel.Rels = append(createDel.Rels, datacloud.SGCommonRelCreate{ + SecurityGroupID: sgID, + Vendor: vendor, + ResID: cvmID, + ResType: enumor.CvmCloudResType, + Priority: int64(i + startIdx + 1), + }) - if err := mgr.dataCli.Global.SGCvmRel.BatchDeleteSgCvmRels(kt.Ctx, kt.Header(), batchDeleteReq); err != nil { - logs.Errorf("batch delete securityGroup_cvm_rel failed, err: %v, rid: %s", err, kt.Rid) + } + if len(stayLocalIDs) > 0 { + createDel.DeleteReq.Filter.Rules = append(createDel.DeleteReq.Filter.Rules, + tools.RuleNotIn("security_group_id", stayLocalIDs)) + } + if len(createDel.Rels) > 0 { + // 同时需要删除和创建 + err := mgr.dataCli.Global.SGCommonRel.BatchUpsertSgCommonRels(kt, createDel) + if err != nil { + logs.Errorf("fail to upsert cvm(%s) security group rel, err: %v, req: %+v, rid: %s", + cvmID, err, createDel, kt.Rid) return err } + return nil } - logs.Infof("delete cvm securityGroup rel success, count: %d, rid: %s", len(ids), kt.Rid) + // 只需要尝试删除多余关联关系即可 + err := mgr.dataCli.Global.SGCommonRel.BatchDeleteSgCommonRels(kt, createDel.DeleteReq) + if err != nil { + logs.Errorf("fail to delete cvm(%s) security group rel, err: %v, req: %+v, rid: %s", + cvmID, err, createDel.DeleteReq, kt.Rid) + return err + } return nil } -func (mgr *CvmRelManger) createCvmSGRel(kt *kit.Kit, addRels []cvmRelInfo) error { - split := slice.Split(addRels, constant.BatchOperationMaxLimit) +func (mgr *CvmRelManger) listCvmSGRelsFromDB(kt *kit.Kit, cvmIDs []string) ( + map[string][]cloud.SGCommonRelWithBaseSecurityGroup, error) { - for _, part := range split { - lists := make([]datacloud.SGCvmRelCreate, 0) - for _, one := range part { - rel := datacloud.SGCvmRelCreate{ - SecurityGroupID: one.AssResID, - CvmID: one.CvmID, - } - lists = append(lists, rel) - } - - createReq := &datacloud.SGCvmRelBatchCreateReq{ - Rels: lists, - } + listReq := &datacloud.SGCommonRelWithSecurityGroupListReq{ + ResIDs: cvmIDs, + ResType: enumor.CvmCloudResType, + } + result := make(map[string][]cloud.SGCommonRelWithBaseSecurityGroup) + respResult, err := mgr.dataCli.Global.SGCommonRel.ListWithSecurityGroup(kt, listReq) + if err != nil { + logs.Errorf("list securityGroup cvm rel failed, err: %v, rid: %s", err, kt.Rid) + return nil, err + } - if err := mgr.dataCli.Global.SGCvmRel.BatchCreateSgCvmRels(kt.Ctx, kt.Header(), createReq); err != nil { - logs.Errorf("batch create securityGroup_cvm_rel failed, err: %v, rid: %s", err, kt.Rid) - return err + for _, rel := range *respResult { + if _, exist := result[rel.ResID]; !exist { + result[rel.ResID] = make([]cloud.SGCommonRelWithBaseSecurityGroup, 0) } + result[rel.ResID] = append(result[rel.ResID], rel) } - logs.Infof("create cvm securityGroup rel success, count: %d, rid: %s", len(addRels), kt.Rid) - - return nil + return result, nil } func (mgr *CvmRelManger) getSGMap(kt *kit.Kit) (map[string]string, error) { diff --git a/cmd/hc-service/service/cvm/aws.go b/cmd/hc-service/service/cvm/aws.go index d78d52dd8d..8eaed0628d 100644 --- a/cmd/hc-service/service/cvm/aws.go +++ b/cmd/hc-service/service/cvm/aws.go @@ -25,15 +25,19 @@ import ( syncaws "hcm/cmd/hc-service/logics/res-sync/aws" "hcm/cmd/hc-service/service/capability" + "hcm/pkg/adaptor/aws" typecvm "hcm/pkg/adaptor/types/cvm" "hcm/pkg/api/core" + corecvm "hcm/pkg/api/core/cloud/cvm" dataproto "hcm/pkg/api/data-service/cloud" - protocloud "hcm/pkg/api/data-service/cloud" protocvm "hcm/pkg/api/hc-service/cvm" + "hcm/pkg/criteria/enumor" "hcm/pkg/criteria/errf" "hcm/pkg/dal/dao/tools" + "hcm/pkg/kit" "hcm/pkg/logs" "hcm/pkg/rest" + "hcm/pkg/tools/converter" ) func (svc *cvmSvc) initAwsCvmService(cap *capability.Capability) { @@ -104,21 +108,71 @@ func (svc *cvmSvc) BatchAssociateAwsSecurityGroup(cts *rest.Contexts) (interface return nil, err } - createReq := &protocloud.SGCvmRelBatchCreateReq{} - for _, sgID := range req.SecurityGroupIDs { - createReq.Rels = append(createReq.Rels, protocloud.SGCvmRelCreate{ - SecurityGroupID: sgID, - CvmID: req.CvmID, - }) - } - if err = svc.dataCli.Global.SGCvmRel.BatchCreateSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), createReq); err != nil { - logs.Errorf("request dataservice create security group cvm rels failed, err: %v, req: %+v, rid: %s", - err, createReq, cts.Kit.Rid) + if err = svc.createSGCommonRelsForAws(cts.Kit, awsCli, req.Region, cvmList[0]); err != nil { + logs.Errorf("create sg common rels failed, err: %v, rid: %s", err, cts.Kit.Rid) return nil, err } return nil, nil } +func (svc *cvmSvc) createSGCommonRelsForAws(kt *kit.Kit, client *aws.Aws, region string, cvm corecvm.BaseCvm) error { + + awsCvms, err := svc.listAwsCvmFromCloud(kt, client, region, cvm) + if err != nil { + logs.Errorf("list aws cvm from cloud failed, err: %v, rid: %s", err, kt.Rid) + return err + } + + sgCloudIDs := make([]string, 0) + for _, one := range awsCvms[0].SecurityGroups { + sgCloudIDs = append(sgCloudIDs, converter.PtrToVal(one.GroupId)) + } + + sgCloudIDToIDMap, err := svc.getSecurityGroupMapByCloudIDs(kt, enumor.Aws, sgCloudIDs) + if err != nil { + logs.Errorf("get security group map by cloud ids failed, err: %v, cloudIDs: %v, rid: %s", + err, sgCloudIDs, kt.Rid) + return err + } + + sgIDs := make([]string, 0, len(sgCloudIDs)) + for _, cloudID := range sgCloudIDs { + sgID, ok := sgCloudIDToIDMap[cloudID] + if !ok { + logs.Errorf("security group not found, cloudID: %s, rid: %s", cloudID, kt.Rid) + return fmt.Errorf("security group (%s) not found", cloudID) + } + sgIDs = append(sgIDs, sgID) + } + + err = svc.createSGCommonRels(kt, enumor.Aws, cvm.ID, sgIDs) + if err != nil { + // 不抛出err, 尽最大努力交付 + logs.Errorf("create sg common rels failed, err: %v, rid: %s", err, kt.Rid) + } + + return nil +} + +func (svc *cvmSvc) listAwsCvmFromCloud(kt *kit.Kit, client *aws.Aws, region string, cvm corecvm.BaseCvm) ( + []typecvm.AwsCvm, error) { + + listOpt := &typecvm.AwsListOption{ + Region: region, + CloudIDs: []string{cvm.CloudID}, + } + awsCvms, _, err := client.ListCvm(kt, listOpt) + if err != nil { + logs.Errorf("list aws cvm failed, err: %v, opt: %v, rid: %s", err, listOpt, kt.Rid) + return nil, err + } + if len(awsCvms) == 0 { + logs.Errorf("aws cvm(%s) not found, rid: %s", kt.Rid, cvm.CloudID) + return nil, fmt.Errorf("aws cvm(%s) not found", cvm.CloudID) + } + return awsCvms, nil +} + // BatchCreateAwsCvm ... func (svc *cvmSvc) BatchCreateAwsCvm(cts *rest.Contexts) (interface{}, error) { req := new(protocvm.AwsBatchCreateReq) diff --git a/cmd/hc-service/service/cvm/cvm.go b/cmd/hc-service/service/cvm/cvm.go index 381a3216b9..9491fbb14d 100644 --- a/cmd/hc-service/service/cvm/cvm.go +++ b/cmd/hc-service/service/cvm/cvm.go @@ -28,9 +28,11 @@ import ( "hcm/pkg/api/core" "hcm/pkg/api/core/cloud" corecvm "hcm/pkg/api/core/cloud/cvm" + dataproto "hcm/pkg/api/data-service" protocloud "hcm/pkg/api/data-service/cloud" "hcm/pkg/client" dataservice "hcm/pkg/client/data-service" + "hcm/pkg/criteria/enumor" "hcm/pkg/dal/dao/tools" "hcm/pkg/kit" "hcm/pkg/logs" @@ -103,3 +105,59 @@ func (svc *cvmSvc) listSecurityGroupMap(kt *kit.Kit, sgIDs ...string) (map[strin return result, nil } + +func (svc *cvmSvc) getSecurityGroupMapByCloudIDs(kt *kit.Kit, vendor enumor.Vendor, cloudIDs []string) ( + map[string]string, error) { + + cloudIDs = slice.Unique(cloudIDs) + m := make(map[string]string) + for _, ids := range slice.Split(cloudIDs, int(core.DefaultMaxPageLimit)) { + req := &protocloud.SecurityGroupListReq{ + Field: []string{"id", "cloud_id"}, + Filter: tools.ExpressionAnd( + tools.RuleIn("cloud_id", ids), + tools.RuleEqual("vendor", vendor), + ), + Page: core.NewDefaultBasePage(), + } + resp, err := svc.dataCli.Global.SecurityGroup.ListSecurityGroup(kt.Ctx, kt.Header(), req) + if err != nil { + logs.Errorf("request dataservice list security group failed, err: %v, req: %+v, rid: %s", err, req, kt.Rid) + return nil, err + } + for _, one := range resp.Details { + m[one.CloudID] = one.ID + } + } + return m, nil +} + +// createSGCommonRels 先删除cvmID关联的安全组关系,再创建新的安全组关系 +func (svc *cvmSvc) createSGCommonRels(kt *kit.Kit, vendor enumor.Vendor, cvmID string, sgIDs []string) error { + + createReq := &protocloud.SGCommonRelBatchUpsertReq{ + DeleteReq: &dataproto.BatchDeleteReq{ + Filter: tools.ExpressionAnd( + tools.RuleEqual("res_id", cvmID), + tools.RuleEqual("res_type", enumor.CvmCloudResType), + tools.RuleEqual("vendor", vendor), + ), + }, + } + + for i, sgID := range sgIDs { + createReq.Rels = append(createReq.Rels, protocloud.SGCommonRelCreate{ + SecurityGroupID: sgID, + Vendor: vendor, + ResID: cvmID, + ResType: enumor.CvmCloudResType, + Priority: int64(i) + 1, + }) + } + if err := svc.dataCli.Global.SGCommonRel.BatchUpsertSgCommonRels(kt, createReq); err != nil { + logs.Errorf("request dataservice create security group cvm rels failed, err: %v, req: %+v, rid: %s", + err, createReq, kt.Rid) + return err + } + return nil +} diff --git a/cmd/hc-service/service/cvm/tcloud.go b/cmd/hc-service/service/cvm/tcloud.go index 73bda5bb3e..726e6fbf2e 100644 --- a/cmd/hc-service/service/cvm/tcloud.go +++ b/cmd/hc-service/service/cvm/tcloud.go @@ -29,8 +29,8 @@ import ( typecvm "hcm/pkg/adaptor/types/cvm" "hcm/pkg/api/core" dataproto "hcm/pkg/api/data-service/cloud" - protocloud "hcm/pkg/api/data-service/cloud" protocvm "hcm/pkg/api/hc-service/cvm" + "hcm/pkg/criteria/enumor" "hcm/pkg/criteria/errf" "hcm/pkg/dal/dao/tools" "hcm/pkg/logs" @@ -85,7 +85,8 @@ func (svc *cvmSvc) BatchAssociateTCloudSecurityGroup(cts *rest.Contexts) (interf sgMap, err := svc.listSecurityGroupMap(cts.Kit, req.SecurityGroupIDs...) if err != nil { - logs.Errorf("list security groups failed, err: %v, sgIDs: %v, rid: %s", err, req.SecurityGroupIDs, cts.Kit.Rid) + logs.Errorf("list security groups failed, err: %v, sgIDs: %v, rid: %s", + err, req.SecurityGroupIDs, cts.Kit.Rid) return nil, err } sgCloudIDs := make([]string, 0, len(req.SecurityGroupIDs)) @@ -110,17 +111,10 @@ func (svc *cvmSvc) BatchAssociateTCloudSecurityGroup(cts *rest.Contexts) (interf return nil, err } - createReq := &protocloud.SGCvmRelBatchCreateReq{} - for _, sgID := range req.SecurityGroupIDs { - createReq.Rels = append(createReq.Rels, protocloud.SGCvmRelCreate{ - SecurityGroupID: sgID, - CvmID: req.CvmID, - }) - } - if err = svc.dataCli.Global.SGCvmRel.BatchCreateSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), createReq); err != nil { - logs.Errorf("request dataservice create security group cvm rels failed, err: %v, req: %+v, rid: %s", - err, createReq, cts.Kit.Rid) - return nil, err + err = svc.createSGCommonRels(cts.Kit, enumor.TCloud, req.CvmID, req.SecurityGroupIDs) + if err != nil { + // 不抛出err, 尽最大努力交付 + logs.Errorf("create sg common rels failed, err: %v, rid: %s", err, cts.Kit.Rid) } return nil, nil } diff --git a/cmd/hc-service/service/security-group/aws_security_group.go b/cmd/hc-service/service/security-group/aws_security_group.go index ff231466d2..4989b73c6c 100644 --- a/cmd/hc-service/service/security-group/aws_security_group.go +++ b/cmd/hc-service/service/security-group/aws_security_group.go @@ -22,16 +22,21 @@ package securitygroup import ( "fmt" + "hcm/pkg/adaptor/aws" + typecvm "hcm/pkg/adaptor/types/cvm" securitygroup "hcm/pkg/adaptor/types/security-group" "hcm/pkg/api/core" corecloud "hcm/pkg/api/core/cloud" + corecvm "hcm/pkg/api/core/cloud/cvm" protocloud "hcm/pkg/api/data-service/cloud" proto "hcm/pkg/api/hc-service" + "hcm/pkg/criteria/enumor" "hcm/pkg/criteria/errf" "hcm/pkg/dal/dao/tools" "hcm/pkg/kit" "hcm/pkg/logs" "hcm/pkg/rest" + "hcm/pkg/tools/converter" ) // CreateAwsSecurityGroup create aws security group. @@ -142,17 +147,9 @@ func (g *securityGroup) AwsSecurityGroupAssociateCvm(cts *rest.Contexts) (interf return nil, err } - createReq := &protocloud.SGCvmRelBatchCreateReq{ - Rels: []protocloud.SGCvmRelCreate{ - { - SecurityGroupID: req.SecurityGroupID, - CvmID: req.CvmID, - }, - }, - } - if err = g.dataCli.Global.SGCvmRel.BatchCreateSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), createReq); err != nil { - logs.Errorf("request dataservice create security group cvm rels failed, err: %v, req: %+v, rid: %s", - err, createReq, cts.Kit.Rid) + err = g.createSGCommonRelsForAws(cts.Kit, client, sg.Region, cvm) + if err != nil { + logs.Errorf("create security group common rels failed, err: %v, rid: %s", err, cts.Kit.Rid) return nil, err } @@ -161,6 +158,52 @@ func (g *securityGroup) AwsSecurityGroupAssociateCvm(cts *rest.Contexts) (interf return nil, nil } +func (g *securityGroup) createSGCommonRelsForAws(kt *kit.Kit, client *aws.Aws, region string, + cvm *corecvm.BaseCvm) error { + + huaweiCvmFromCloud, err := g.listAwsCvmFromCloud(kt, client, region, cvm) + if err != nil { + logs.Errorf("request adaptor to list cvm from cloud failed, err: %v, rid: %s", err, kt.Rid) + return err + } + + sgCloudIDs := make([]string, 0, len(huaweiCvmFromCloud[0].SecurityGroups)) + for _, cur := range huaweiCvmFromCloud[0].SecurityGroups { + sgCloudIDs = append(sgCloudIDs, converter.PtrToVal(cur.GroupId)) + } + + sgCloudIDToIDMap, err := g.getSecurityGroupMapByCloudIDs(kt, enumor.Aws, sgCloudIDs) + if err != nil { + logs.Errorf("get security group map by cloud ids failed, err: %v, rid: %s", err, kt.Rid) + return err + } + + err = g.createSGCommonRels(kt, enumor.Aws, cvm.ID, sgCloudIDs, sgCloudIDToIDMap) + if err != nil { + logs.Errorf("create security group common rels failed, err: %v, rid: %s", err, kt.Rid) + return err + } + return nil +} + +func (g *securityGroup) listAwsCvmFromCloud(kt *kit.Kit, client *aws.Aws, region string, cvm *corecvm.BaseCvm) ( + []typecvm.AwsCvm, error) { + listOpt := &typecvm.AwsListOption{ + Region: region, + CloudIDs: []string{cvm.CloudID}, + } + awsCvms, _, err := client.ListCvm(kt, listOpt) + if err != nil { + logs.Errorf("list aws cvm failed, err: %v, opt: %v, rid: %s", err, listOpt, kt.Rid) + return nil, err + } + if len(awsCvms) == 0 { + logs.Errorf("aws cvm(%s) not found, rid: %s", kt.Rid, cvm.CloudID) + return nil, fmt.Errorf("aws cvm(%s) not found", cvm.CloudID) + } + return awsCvms, nil +} + // AwsSecurityGroupDisassociateCvm ... func (g *securityGroup) AwsSecurityGroupDisassociateCvm(cts *rest.Contexts) (interface{}, error) { req := new(proto.SecurityGroupAssociateCvmReq) @@ -193,12 +236,8 @@ func (g *securityGroup) AwsSecurityGroupDisassociateCvm(cts *rest.Contexts) (int return nil, err } - deleteReq, err := buildSGCvmRelDeleteReq(req.SecurityGroupID, req.CvmID) - if err != nil { - logs.Errorf("build sg cvm rel delete req failed, err: %v, rid: %s", err, cts.Kit.Rid) - return nil, err - } - if err = g.dataCli.Global.SGCvmRel.BatchDeleteSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), deleteReq); err != nil { + deleteReq := buildSGCommonRelDeleteReq(enumor.Aws, req.CvmID, []string{req.SecurityGroupID}, enumor.CvmCloudResType) + if err = g.dataCli.Global.SGCommonRel.BatchDeleteSgCommonRels(cts.Kit, deleteReq); err != nil { logs.Errorf("request dataservice delete security group cvm rels failed, err: %v, req: %+v, rid: %s", err, deleteReq, cts.Kit.Rid) return nil, err diff --git a/cmd/hc-service/service/security-group/huawei_security_group.go b/cmd/hc-service/service/security-group/huawei_security_group.go index a63fbd7e51..de138cfdb7 100644 --- a/cmd/hc-service/service/security-group/huawei_security_group.go +++ b/cmd/hc-service/service/security-group/huawei_security_group.go @@ -21,15 +21,20 @@ package securitygroup import ( "errors" + "fmt" + "hcm/pkg/adaptor/huawei" typecvm "hcm/pkg/adaptor/types/cvm" securitygroup "hcm/pkg/adaptor/types/security-group" "hcm/pkg/api/core" corecloud "hcm/pkg/api/core/cloud" + corecvm "hcm/pkg/api/core/cloud/cvm" protocloud "hcm/pkg/api/data-service/cloud" proto "hcm/pkg/api/hc-service" + "hcm/pkg/criteria/enumor" "hcm/pkg/criteria/errf" "hcm/pkg/dal/dao/tools" + "hcm/pkg/kit" "hcm/pkg/logs" "hcm/pkg/rest" ) @@ -119,17 +124,9 @@ func (g *securityGroup) HuaWeiSecurityGroupAssociateCvm(cts *rest.Contexts) (int return nil, err } - createReq := &protocloud.SGCvmRelBatchCreateReq{ - Rels: []protocloud.SGCvmRelCreate{ - { - SecurityGroupID: req.SecurityGroupID, - CvmID: req.CvmID, - }, - }, - } - if err = g.dataCli.Global.SGCvmRel.BatchCreateSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), createReq); err != nil { - logs.Errorf("request dataservice create security group cvm rels failed, err: %v, req: %+v, rid: %s", - err, createReq, cts.Kit.Rid) + err = g.createSGCommonRelsForHuawei(cts.Kit, client, sg.Region, cvm) + if err != nil { + logs.Errorf("create security group common rels failed, err: %v, rid: %s", err, cts.Kit.Rid) return nil, err } @@ -138,6 +135,52 @@ func (g *securityGroup) HuaWeiSecurityGroupAssociateCvm(cts *rest.Contexts) (int return nil, nil } +func (g *securityGroup) createSGCommonRelsForHuawei(kt *kit.Kit, client *huawei.HuaWei, region string, + cvm *corecvm.BaseCvm) error { + + huaweiCvmFromCloud, err := g.listHuaweiCvmFromCloud(kt, client, region, cvm.CloudID) + if err != nil { + logs.Errorf("request adaptor to list cvm from cloud failed, err: %v, rid: %s", err, kt.Rid) + return err + } + + sgCloudIDs := make([]string, 0, len(huaweiCvmFromCloud[0].SecurityGroups)) + for _, cur := range huaweiCvmFromCloud[0].SecurityGroups { + sgCloudIDs = append(sgCloudIDs, cur.Id) + } + + sgCloudIDToIDMap, err := g.getSecurityGroupMapByCloudIDs(kt, enumor.HuaWei, sgCloudIDs) + if err != nil { + logs.Errorf("get security group map by cloud ids failed, err: %v, rid: %s", err, kt.Rid) + return err + } + + err = g.createSGCommonRels(kt, enumor.HuaWei, cvm.ID, sgCloudIDs, sgCloudIDToIDMap) + if err != nil { + logs.Errorf("create security group common rels failed, err: %v, rid: %s", err, kt.Rid) + return err + } + return nil +} + +func (g *securityGroup) listHuaweiCvmFromCloud(kt *kit.Kit, client *huawei.HuaWei, region, cvmCloudID string) ( + []typecvm.HuaWeiCvm, error) { + + listOpt := &typecvm.HuaWeiListOption{ + Region: region, + CloudIDs: []string{cvmCloudID}, + } + cvms, err := client.ListCvm(kt, listOpt) + if err != nil { + logs.Errorf("request adaptor to list cvm failed, err: %v, opt: %v, rid: %s", err, listOpt, kt.Rid) + return nil, err + } + if len(cvms) == 0 { + return nil, fmt.Errorf("cvm(%s) not found from cloud", cvmCloudID) + } + return cvms, nil +} + // HuaWeiSecurityGroupDisassociateCvm ... func (g *securityGroup) HuaWeiSecurityGroupDisassociateCvm(cts *rest.Contexts) (interface{}, error) { req := new(proto.SecurityGroupAssociateCvmReq) @@ -189,12 +232,9 @@ func (g *securityGroup) HuaWeiSecurityGroupDisassociateCvm(cts *rest.Contexts) ( return nil, err } - deleteReq, err := buildSGCvmRelDeleteReq(req.SecurityGroupID, req.CvmID) - if err != nil { - logs.Errorf("build sg cvm rel delete req failed, err: %v, rid: %s", err, cts.Kit.Rid) - return nil, err - } - if err = g.dataCli.Global.SGCvmRel.BatchDeleteSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), deleteReq); err != nil { + deleteReq := buildSGCommonRelDeleteReq( + enumor.HuaWei, req.CvmID, []string{req.SecurityGroupID}, enumor.CvmCloudResType) + if err = g.dataCli.Global.SGCommonRel.BatchDeleteSgCommonRels(cts.Kit, deleteReq); err != nil { logs.Errorf("request dataservice delete security group cvm rels failed, err: %v, req: %+v, rid: %s", err, deleteReq, cts.Kit.Rid) return nil, err diff --git a/cmd/hc-service/service/security-group/logics.go b/cmd/hc-service/service/security-group/logics.go index dc190c1d1d..da5ab37d1f 100644 --- a/cmd/hc-service/service/security-group/logics.go +++ b/cmd/hc-service/service/security-group/logics.go @@ -21,6 +21,7 @@ package securitygroup import ( "errors" + "hcm/pkg/api/core" corecloud "hcm/pkg/api/core/cloud" corecvm "hcm/pkg/api/core/cloud/cvm" @@ -32,28 +33,22 @@ import ( "hcm/pkg/kit" "hcm/pkg/logs" "hcm/pkg/runtime/filter" + "hcm/pkg/tools/slice" ) -func buildSGCvmRelDeleteReq(sgID string, cvmIDs ...string) (*dataproto.BatchDeleteReq, error) { - if len(cvmIDs) == 0 { +func buildSGCommonRelDeleteReqForMultiResource(vendor enumor.Vendor, resType enumor.CloudResourceType, + sgID string, resIDs ...string) (*dataproto.BatchDeleteReq, error) { + + if len(resIDs) == 0 { return nil, errors.New("cvmIDs is required") } return &dataproto.BatchDeleteReq{ - Filter: &filter.Expression{ - Op: filter.And, - Rules: []filter.RuleFactory{ - &filter.AtomRule{ - Field: "security_group_id", - Op: filter.Equal.Factory(), - Value: sgID, - }, - &filter.AtomRule{ - Field: "cvm_id", - Op: filter.In.Factory(), - Value: cvmIDs, - }, - }, - }, + Filter: tools.ExpressionAnd( + tools.RuleEqual("security_group_id", sgID), + tools.RuleIn("res_id", resIDs), + tools.RuleEqual("res_type", resType), + tools.RuleEqual("vendor", vendor), + ), }, nil } @@ -123,3 +118,61 @@ func (g *securityGroup) getSecurityGroupAndCvm(kt *kit.Kit, sgID, cvmID string) return &sgResult.Details[0], &cvmResult.Details[0], nil } + +// createSGCommonRels 先删除cvmID关联的安全组关系,再创建新的安全组关系 +// sgCloudIDs的入参顺序决定新建的关联关系的优先级 +func (g *securityGroup) createSGCommonRels(kt *kit.Kit, vendor enumor.Vendor, cvmID string, sgCloudIDs []string, + sgCloudIDToIDMap map[string]string) error { + + createReq := &protocloud.SGCommonRelBatchUpsertReq{ + DeleteReq: &dataproto.BatchDeleteReq{ + Filter: tools.ExpressionAnd( + tools.RuleEqual("res_id", cvmID), + tools.RuleEqual("res_type", enumor.CvmCloudResType), + tools.RuleEqual("vendor", vendor), + ), + }, + } + + for i, cloudID := range sgCloudIDs { + createReq.Rels = append(createReq.Rels, protocloud.SGCommonRelCreate{ + SecurityGroupID: sgCloudIDToIDMap[cloudID], + Vendor: vendor, + ResID: cvmID, + ResType: enumor.CvmCloudResType, + Priority: int64(i) + 1, + }) + } + if err := g.dataCli.Global.SGCommonRel.BatchUpsertSgCommonRels(kt, createReq); err != nil { + logs.Errorf("request dataservice create security group cvm rels failed, err: %v, req: %+v, rid: %s", + err, createReq, kt.Rid) + return err + } + return nil +} + +func (g *securityGroup) getSecurityGroupMapByCloudIDs(kt *kit.Kit, vendor enumor.Vendor, cloudIDs []string) ( + map[string]string, error) { + + cloudIDs = slice.Unique(cloudIDs) + m := make(map[string]string) + for _, ids := range slice.Split(cloudIDs, int(core.DefaultMaxPageLimit)) { + req := &protocloud.SecurityGroupListReq{ + Field: []string{"id", "cloud_id"}, + Filter: tools.ExpressionAnd( + tools.RuleIn("cloud_id", ids), + tools.RuleEqual("vendor", vendor), + ), + Page: core.NewDefaultBasePage(), + } + resp, err := g.dataCli.Global.SecurityGroup.ListSecurityGroup(kt.Ctx, kt.Header(), req) + if err != nil { + logs.Errorf("request dataservice list security group failed, err: %v, req: %+v, rid: %s", err, req, kt.Rid) + return nil, err + } + for _, one := range resp.Details { + m[one.CloudID] = one.ID + } + } + return m, nil +} diff --git a/cmd/hc-service/service/security-group/tcloud_security_group.go b/cmd/hc-service/service/security-group/tcloud_security_group.go index fc914094f7..53714ed8c2 100644 --- a/cmd/hc-service/service/security-group/tcloud_security_group.go +++ b/cmd/hc-service/service/security-group/tcloud_security_group.go @@ -23,6 +23,9 @@ import ( "errors" "fmt" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + + "hcm/pkg/adaptor/tcloud" typecvm "hcm/pkg/adaptor/types/cvm" typelb "hcm/pkg/adaptor/types/load-balancer" securitygroup "hcm/pkg/adaptor/types/security-group" @@ -39,6 +42,7 @@ import ( "hcm/pkg/kit" "hcm/pkg/logs" "hcm/pkg/rest" + "hcm/pkg/tools/converter" "hcm/pkg/tools/slice" ) @@ -127,20 +131,11 @@ func (g *securityGroup) TCloudSecurityGroupAssociateCvm(cts *rest.Contexts) (int return nil, err } - createReq := &protocloud.SGCvmRelBatchCreateReq{ - Rels: []protocloud.SGCvmRelCreate{ - { - SecurityGroupID: req.SecurityGroupID, - CvmID: req.CvmID, - }, - }, - } - if err = g.dataCli.Global.SGCvmRel.BatchCreateSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), createReq); err != nil { - logs.Errorf("request dataservice create security group cvm rels failed, err: %v, req: %+v, rid: %s", - err, createReq, cts.Kit.Rid) + err = g.createSGCommonRelsForTCloud(cts.Kit, client, sg.Region, map[string]string{cvm.CloudID: cvm.ID}) + if err != nil { + logs.Errorf("create security group cvm rels failed, err: %v, rid: %s", err, cts.Kit.Rid) return nil, err } - // TODO: 同步主机数据 return nil, nil @@ -196,12 +191,9 @@ func (g *securityGroup) TCloudSecurityGroupDisassociateCvm(cts *rest.Contexts) ( return nil, err } - deleteReq, err := buildSGCvmRelDeleteReq(req.SecurityGroupID, req.CvmID) - if err != nil { - logs.Errorf("build sg cvm rel delete req failed, err: %v, rid: %s", err, cts.Kit.Rid) - return nil, err - } - if err = g.dataCli.Global.SGCvmRel.BatchDeleteSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), deleteReq); err != nil { + deleteReq := buildSGCommonRelDeleteReq( + enumor.TCloud, req.CvmID, []string{req.SecurityGroupID}, enumor.CvmCloudResType) + if err = g.dataCli.Global.SGCommonRel.BatchDeleteSgCommonRels(cts.Kit, deleteReq); err != nil { logs.Errorf("request dataservice delete security group cvm rels failed, err: %v, req: %+v, rid: %s", err, deleteReq, cts.Kit.Rid) return nil, err @@ -568,9 +560,9 @@ func (g *securityGroup) TCloudSGBatchAssociateCvm(cts *rest.Contexts) (any, erro if err != nil { return nil, err } - cloudCvmIDs := make([]string, 0, len(req.CvmIDs)) + cvmCloudIDToIDMap := make(map[string]string, len(req.CvmIDs)) for _, baseCvm := range cvmList { - cloudCvmIDs = append(cloudCvmIDs, baseCvm.CloudID) + cvmCloudIDToIDMap[baseCvm.CloudID] = baseCvm.ID } client, err := g.ad.TCloud(cts.Kit, sg.AccountID) @@ -581,7 +573,7 @@ func (g *securityGroup) TCloudSGBatchAssociateCvm(cts *rest.Contexts) (any, erro opt := &securitygroup.TCloudBatchAssociateCvmOption{ Region: sg.Region, CloudSecurityGroupID: sg.CloudID, - CloudCvmIDs: cloudCvmIDs, + CloudCvmIDs: converter.MapKeyToSlice(cvmCloudIDToIDMap), } if err = client.SecurityGroupCvmBatchAssociate(cts.Kit, opt); err != nil { logs.Errorf("request adaptor to tcloud security group associate cvm failed, err: %v, opt: %v, rid: %s", @@ -589,22 +581,68 @@ func (g *securityGroup) TCloudSGBatchAssociateCvm(cts *rest.Contexts) (any, erro return nil, err } - createReq := &protocloud.SGCvmRelBatchCreateReq{} - for _, cvmID := range req.CvmIDs { - createReq.Rels = append(createReq.Rels, protocloud.SGCvmRelCreate{ - SecurityGroupID: req.SecurityGroupID, - CvmID: cvmID, - }) - } - - if err = g.dataCli.Global.SGCvmRel.BatchCreateSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), createReq); err != nil { - logs.Errorf("request dataservice create security group cvm rels failed, err: %v, req: %+v, rid: %s", - err, createReq, cts.Kit.Rid) + err = g.createSGCommonRelsForTCloud(cts.Kit, client, sg.Region, cvmCloudIDToIDMap) + if err != nil { + logs.Errorf("create sg common rels failed, err: %v, rid: %s", err, cts.Kit.Rid) return nil, err } + return nil, nil } +func (g *securityGroup) createSGCommonRelsForTCloud(kt *kit.Kit, client tcloud.TCloud, region string, + cvmCloudIDToIDMap map[string]string) error { + + cloudCvms, err := g.listTCloudCvmFromCloud(kt, client, region, converter.MapKeyToSlice(cvmCloudIDToIDMap)) + if err != nil { + logs.Errorf("list cvm from cloud failed, err: %v, rid: %s", err, kt.Rid) + return err + } + + sgCloudIDs := make([]string, 0) + for _, one := range cloudCvms { + sgCloudIDs = append(sgCloudIDs, common.StringValues(one.SecurityGroupIds)...) + } + + sgCloudIDToIDMap, err := g.getSecurityGroupMapByCloudIDs(kt, enumor.TCloud, sgCloudIDs) + if err != nil { + logs.Errorf("get security group map by cloud ids failed, err: %v, cloudIDs: %v, rid: %s", + err, sgCloudIDs, kt.Rid) + return err + } + + for _, one := range cloudCvms { + cvmID, ok := cvmCloudIDToIDMap[converter.PtrToVal(one.InstanceId)] + if !ok { + logs.Errorf("cvm cloud id to id not found, cvmID: %s, rid: %s", converter.PtrToVal(one.InstanceId), kt.Rid) + return fmt.Errorf("cvm cloud id to id not found, cvmID: %s", converter.PtrToVal(one.InstanceId)) + } + err = g.createSGCommonRels(kt, enumor.TCloud, cvmID, sgCloudIDs, sgCloudIDToIDMap) + if err != nil { + // 不抛出err, 尽最大努力交付 + logs.Errorf("create sg common rels failed, err: %v, rid: %s", err, kt.Rid) + } + } + + return nil +} + +func (g *securityGroup) listTCloudCvmFromCloud(kt *kit.Kit, client tcloud.TCloud, region string, cvmCloudIDs []string) ( + []typecvm.TCloudCvm, error) { + + listOpt := &typecvm.TCloudListOption{ + CloudIDs: cvmCloudIDs, + Region: region, + } + cloudCvms, err := client.ListCvm(kt, listOpt) + if err != nil { + logs.Errorf("request adaptor to list cvm failed, err: %v, opt: %v, rid: %s", err, listOpt, kt.Rid) + return nil, nil + } + + return cloudCvms, err +} + // TCloudListSecurityGroupStatistic ... func (g *securityGroup) TCloudListSecurityGroupStatistic(cts *rest.Contexts) (any, error) { req := new(proto.TCloudListSecurityGroupStatisticReq) @@ -696,12 +734,13 @@ func (g *securityGroup) TCloudSGBatchDisassociateCvm(cts *rest.Contexts) (any, e return nil, err } - deleteReq, err := buildSGCvmRelDeleteReq(req.SecurityGroupID, req.CvmIDs...) + deleteReq, err := buildSGCommonRelDeleteReqForMultiResource(enumor.TCloud, enumor.CvmCloudResType, + req.SecurityGroupID, req.CvmIDs...) if err != nil { logs.Errorf("build sg cvm rel delete req failed, err: %v, rid: %s", err, cts.Kit.Rid) return nil, err } - if err = g.dataCli.Global.SGCvmRel.BatchDeleteSgCvmRels(cts.Kit.Ctx, cts.Kit.Header(), deleteReq); err != nil { + if err = g.dataCli.Global.SGCommonRel.BatchDeleteSgCommonRels(cts.Kit, deleteReq); err != nil { logs.Errorf("request dataservice delete security group cvm rels failed, err: %v, req: %+v, rid: %s", err, deleteReq, cts.Kit.Rid) return nil, err diff --git a/pkg/client/data-service/global/security_group_cvm_rel.go b/pkg/client/data-service/global/security_group_cvm_rel.go index 32b8e300e6..90283ddf63 100644 --- a/pkg/client/data-service/global/security_group_cvm_rel.go +++ b/pkg/client/data-service/global/security_group_cvm_rel.go @@ -44,6 +44,7 @@ type SGCvmRelClient struct { } // BatchCreateSgCvmRels security group cvm rels. +// Deprecated: use SGCommonRelClient's BatchCreateSgCommonRels instead. func (cli *SGCvmRelClient) BatchCreateSgCvmRels(ctx context.Context, h http.Header, request *protocloud.SGCvmRelBatchCreateReq) error { @@ -68,6 +69,7 @@ func (cli *SGCvmRelClient) BatchCreateSgCvmRels(ctx context.Context, h http.Head } // BatchDeleteSgCvmRels security group cvm rels. +// Deprecated: use SGCommonRelClient's BatchDeleteSgCommonRels instead. func (cli *SGCvmRelClient) BatchDeleteSgCvmRels(ctx context.Context, h http.Header, request *proto.BatchDeleteReq) error { resp := new(rest.BaseResp) @@ -91,6 +93,7 @@ func (cli *SGCvmRelClient) BatchDeleteSgCvmRels(ctx context.Context, h http.Head } // ListSgCvmRels security group cvm rels. +// Deprecated: use SGCommonRelClient's ListSgCommonRels instead. func (cli *SGCvmRelClient) ListSgCvmRels(ctx context.Context, h http.Header, request *core.ListReq) ( *protocloud.SGCvmRelListResult, error) { @@ -115,6 +118,7 @@ func (cli *SGCvmRelClient) ListSgCvmRels(ctx context.Context, h http.Header, req } // ListWithSecurityGroup security group cvm rels with security group. +// Deprecated: use SGCommonRelClient's ListWithSecurityGroup instead. func (cli *SGCvmRelClient) ListWithSecurityGroup(ctx context.Context, h http.Header, request *protocloud.SGCvmRelWithSecurityGroupListReq) ([]corecloud.SGCvmRelWithBaseSecurityGroup, error) { diff --git a/pkg/dal/dao/cloud/security-group-common-rel/security_group_common_rel.go b/pkg/dal/dao/cloud/security-group-common-rel/security_group_common_rel.go index 62f750e374..af0616175b 100644 --- a/pkg/dal/dao/cloud/security-group-common-rel/security_group_common_rel.go +++ b/pkg/dal/dao/cloud/security-group-common-rel/security_group_common_rel.go @@ -25,8 +25,6 @@ import ( "hcm/pkg/api/core" "hcm/pkg/criteria/enumor" "hcm/pkg/criteria/errf" - "hcm/pkg/dal/dao/cloud/load-balancer" - securitygroup "hcm/pkg/dal/dao/cloud/security-group" "hcm/pkg/dal/dao/orm" "hcm/pkg/dal/dao/tools" "hcm/pkg/dal/dao/types" @@ -35,7 +33,6 @@ import ( "hcm/pkg/kit" "hcm/pkg/logs" "hcm/pkg/runtime/filter" - "hcm/pkg/tools/converter" "github.com/jmoiron/sqlx" ) @@ -86,41 +83,12 @@ func (dao Dao) ListJoinSecurityGroup(kt *kit.Kit, resIDs []string, resType enumo // BatchCreateWithTx rels. func (dao Dao) BatchCreateWithTx(kt *kit.Kit, tx *sqlx.Tx, rels []cloud.SecurityGroupCommonRelTable) error { - // 校验关联资源是否存在 - sgIDs := make([]string, 0) - resIDs := make([]string, 0) - for _, rel := range rels { - sgIDs = append(sgIDs, rel.SecurityGroupID) - resIDs = append(resIDs, rel.ResID) - } - - sgMap, err := securitygroup.ListSecurityGroup(kt, dao.Orm, sgIDs) - if err != nil { - logs.Errorf("list security group failed, err: %v, ids: %v, rid: %s", err, sgIDs, kt.Rid) - return err - } - - if len(sgMap) != len(converter.StringSliceToMap(sgIDs)) { - logs.Errorf("get security group count not right, ids: %v, count: %d, rid: %s", sgIDs, len(sgMap), kt.Rid) - return fmt.Errorf("get security group count not right") - } - - resMap, err := loadbalancer.ListLbByIDs(kt, dao.Orm, resIDs) - if err != nil { - logs.Errorf("list clb by ids failed, err: %v, sgIDs: %v, resIDs: %v, rid: %s", err, sgIDs, resIDs, kt.Rid) - return err - } - - if len(resMap) != len(converter.StringSliceToMap(resIDs)) { - logs.Errorf("get clb count not right, err: %v, ids: %v, count: %d, rid: %s", err, resIDs, len(resMap), kt.Rid) - return fmt.Errorf("get clb count not right") - } tableName := table.SecurityGroupCommonRelTable sql := fmt.Sprintf(`INSERT INTO %s (%s) VALUES(%s)`, tableName, cloud.SecurityGroupCommonRelColumns.ColumnExpr(), cloud.SecurityGroupCommonRelColumns.ColonNameExpr()) - if err = dao.Orm.Txn(tx).BulkInsert(kt.Ctx, sql, rels); err != nil { + if err := dao.Orm.Txn(tx).BulkInsert(kt.Ctx, sql, rels); err != nil { logs.Errorf("insert %s failed, err: %v, rid: %s", tableName, err, kt.Rid) return fmt.Errorf("insert %s failed, err: %v", tableName, err) } From 0236e2c4105768fc1ce1a1d534d94e50eec73804 Mon Sep 17 00:00:00 2001 From: kookouse Date: Wed, 22 Jan 2025 17:12:09 +0800 Subject: [PATCH 2/2] fix: review issue --- cmd/hc-service/service/cvm/aws.go | 7 +++--- cmd/hc-service/service/cvm/cvm.go | 7 +++--- cmd/hc-service/service/cvm/tcloud.go | 5 +++-- .../security-group/aws_security_group.go | 22 ++++++++++++++----- .../security-group/huawei_security_group.go | 14 ++++++++++-- .../service/security-group/logics.go | 19 ++++++++-------- .../security-group/tcloud_security_group.go | 22 ++++++++++++++----- 7 files changed, 63 insertions(+), 33 deletions(-) diff --git a/cmd/hc-service/service/cvm/aws.go b/cmd/hc-service/service/cvm/aws.go index 8eaed0628d..522873f7dd 100644 --- a/cmd/hc-service/service/cvm/aws.go +++ b/cmd/hc-service/service/cvm/aws.go @@ -145,10 +145,11 @@ func (svc *cvmSvc) createSGCommonRelsForAws(kt *kit.Kit, client *aws.Aws, region sgIDs = append(sgIDs, sgID) } - err = svc.createSGCommonRels(kt, enumor.Aws, cvm.ID, sgIDs) + err = svc.createSGCommonRels(kt, enumor.Aws, enumor.CvmCloudResType, cvm.ID, sgIDs) if err != nil { // 不抛出err, 尽最大努力交付 - logs.Errorf("create sg common rels failed, err: %v, rid: %s", err, kt.Rid) + logs.Errorf("create sg common rels failed, err: %v, cvmID: %s, sgIDs: %v, rid: %s", + err, cvm.ID, sgIDs, kt.Rid) } return nil @@ -167,7 +168,7 @@ func (svc *cvmSvc) listAwsCvmFromCloud(kt *kit.Kit, client *aws.Aws, region stri return nil, err } if len(awsCvms) == 0 { - logs.Errorf("aws cvm(%s) not found, rid: %s", kt.Rid, cvm.CloudID) + logs.Errorf("aws cvm(%s) not found, rid: %s", cvm.CloudID, kt.Rid) return nil, fmt.Errorf("aws cvm(%s) not found", cvm.CloudID) } return awsCvms, nil diff --git a/cmd/hc-service/service/cvm/cvm.go b/cmd/hc-service/service/cvm/cvm.go index 9491fbb14d..a0d3549a89 100644 --- a/cmd/hc-service/service/cvm/cvm.go +++ b/cmd/hc-service/service/cvm/cvm.go @@ -133,14 +133,13 @@ func (svc *cvmSvc) getSecurityGroupMapByCloudIDs(kt *kit.Kit, vendor enumor.Vend } // createSGCommonRels 先删除cvmID关联的安全组关系,再创建新的安全组关系 -func (svc *cvmSvc) createSGCommonRels(kt *kit.Kit, vendor enumor.Vendor, cvmID string, sgIDs []string) error { +func (svc *cvmSvc) createSGCommonRels(kt *kit.Kit, vendor enumor.Vendor, resType enumor.CloudResourceType, cvmID string, sgIDs []string) error { createReq := &protocloud.SGCommonRelBatchUpsertReq{ DeleteReq: &dataproto.BatchDeleteReq{ Filter: tools.ExpressionAnd( tools.RuleEqual("res_id", cvmID), - tools.RuleEqual("res_type", enumor.CvmCloudResType), - tools.RuleEqual("vendor", vendor), + tools.RuleEqual("res_type", resType), ), }, } @@ -150,7 +149,7 @@ func (svc *cvmSvc) createSGCommonRels(kt *kit.Kit, vendor enumor.Vendor, cvmID s SecurityGroupID: sgID, Vendor: vendor, ResID: cvmID, - ResType: enumor.CvmCloudResType, + ResType: resType, Priority: int64(i) + 1, }) } diff --git a/cmd/hc-service/service/cvm/tcloud.go b/cmd/hc-service/service/cvm/tcloud.go index 726e6fbf2e..1ff67721df 100644 --- a/cmd/hc-service/service/cvm/tcloud.go +++ b/cmd/hc-service/service/cvm/tcloud.go @@ -111,10 +111,11 @@ func (svc *cvmSvc) BatchAssociateTCloudSecurityGroup(cts *rest.Contexts) (interf return nil, err } - err = svc.createSGCommonRels(cts.Kit, enumor.TCloud, req.CvmID, req.SecurityGroupIDs) + err = svc.createSGCommonRels(cts.Kit, enumor.TCloud, enumor.CvmCloudResType, req.CvmID, req.SecurityGroupIDs) if err != nil { // 不抛出err, 尽最大努力交付 - logs.Errorf("create sg common rels failed, err: %v, rid: %s", err, cts.Kit.Rid) + logs.Errorf("create sg common rels failed, err: %v, cvmID: %s, sgIDs: %v, rid: %s", + err, req.CvmID, req.SecurityGroupIDs, cts.Kit.Rid) } return nil, nil } diff --git a/cmd/hc-service/service/security-group/aws_security_group.go b/cmd/hc-service/service/security-group/aws_security_group.go index 4989b73c6c..fe22368afa 100644 --- a/cmd/hc-service/service/security-group/aws_security_group.go +++ b/cmd/hc-service/service/security-group/aws_security_group.go @@ -161,24 +161,34 @@ func (g *securityGroup) AwsSecurityGroupAssociateCvm(cts *rest.Contexts) (interf func (g *securityGroup) createSGCommonRelsForAws(kt *kit.Kit, client *aws.Aws, region string, cvm *corecvm.BaseCvm) error { - huaweiCvmFromCloud, err := g.listAwsCvmFromCloud(kt, client, region, cvm) + awsCvmFromCloud, err := g.listAwsCvmFromCloud(kt, client, region, cvm) if err != nil { logs.Errorf("request adaptor to list cvm from cloud failed, err: %v, rid: %s", err, kt.Rid) return err } - sgCloudIDs := make([]string, 0, len(huaweiCvmFromCloud[0].SecurityGroups)) - for _, cur := range huaweiCvmFromCloud[0].SecurityGroups { + sgCloudIDs := make([]string, 0, len(awsCvmFromCloud[0].SecurityGroups)) + for _, cur := range awsCvmFromCloud[0].SecurityGroups { sgCloudIDs = append(sgCloudIDs, converter.PtrToVal(cur.GroupId)) } - sgCloudIDToIDMap, err := g.getSecurityGroupMapByCloudIDs(kt, enumor.Aws, sgCloudIDs) + sgCloudIDToIDMap, err := g.getSecurityGroupMapByCloudIDs(kt, enumor.Aws, region, sgCloudIDs) if err != nil { logs.Errorf("get security group map by cloud ids failed, err: %v, rid: %s", err, kt.Rid) return err } - err = g.createSGCommonRels(kt, enumor.Aws, cvm.ID, sgCloudIDs, sgCloudIDToIDMap) + sgIDs := make([]string, 0, len(sgCloudIDs)) + for _, cur := range sgCloudIDs { + sgID, ok := sgCloudIDToIDMap[cur] + if !ok { + logs.Errorf("cloud id(%s) not found in security group map, rid: %s", cur, kt.Rid) + return fmt.Errorf("cloud id(%s) not found in security group map", cur) + } + sgIDs = append(sgIDs, sgID) + } + + err = g.createSGCommonRels(kt, enumor.Aws, enumor.CvmCloudResType, cvm.ID, sgIDs) if err != nil { logs.Errorf("create security group common rels failed, err: %v, rid: %s", err, kt.Rid) return err @@ -198,7 +208,7 @@ func (g *securityGroup) listAwsCvmFromCloud(kt *kit.Kit, client *aws.Aws, region return nil, err } if len(awsCvms) == 0 { - logs.Errorf("aws cvm(%s) not found, rid: %s", kt.Rid, cvm.CloudID) + logs.Errorf("aws cvm(%s) not found, rid: %s", cvm.CloudID, kt.Rid) return nil, fmt.Errorf("aws cvm(%s) not found", cvm.CloudID) } return awsCvms, nil diff --git a/cmd/hc-service/service/security-group/huawei_security_group.go b/cmd/hc-service/service/security-group/huawei_security_group.go index de138cfdb7..06fd03e461 100644 --- a/cmd/hc-service/service/security-group/huawei_security_group.go +++ b/cmd/hc-service/service/security-group/huawei_security_group.go @@ -149,13 +149,23 @@ func (g *securityGroup) createSGCommonRelsForHuawei(kt *kit.Kit, client *huawei. sgCloudIDs = append(sgCloudIDs, cur.Id) } - sgCloudIDToIDMap, err := g.getSecurityGroupMapByCloudIDs(kt, enumor.HuaWei, sgCloudIDs) + sgCloudIDToIDMap, err := g.getSecurityGroupMapByCloudIDs(kt, enumor.HuaWei, region, sgCloudIDs) if err != nil { logs.Errorf("get security group map by cloud ids failed, err: %v, rid: %s", err, kt.Rid) return err } - err = g.createSGCommonRels(kt, enumor.HuaWei, cvm.ID, sgCloudIDs, sgCloudIDToIDMap) + sgIDs := make([]string, 0, len(sgCloudIDs)) + for _, sgCloudID := range sgCloudIDs { + sgID, ok := sgCloudIDToIDMap[sgCloudID] + if !ok { + logs.Errorf("cloud id(%s) not found in security group map, rid: %s", sgCloudID, kt.Rid) + return fmt.Errorf("cloud id(%s) not found in security group map", sgCloudID) + } + sgIDs = append(sgIDs, sgID) + } + + err = g.createSGCommonRels(kt, enumor.HuaWei, enumor.CvmCloudResType, cvm.ID, sgIDs) if err != nil { logs.Errorf("create security group common rels failed, err: %v, rid: %s", err, kt.Rid) return err diff --git a/cmd/hc-service/service/security-group/logics.go b/cmd/hc-service/service/security-group/logics.go index da5ab37d1f..f68481763d 100644 --- a/cmd/hc-service/service/security-group/logics.go +++ b/cmd/hc-service/service/security-group/logics.go @@ -47,7 +47,6 @@ func buildSGCommonRelDeleteReqForMultiResource(vendor enumor.Vendor, resType enu tools.RuleEqual("security_group_id", sgID), tools.RuleIn("res_id", resIDs), tools.RuleEqual("res_type", resType), - tools.RuleEqual("vendor", vendor), ), }, nil } @@ -121,25 +120,24 @@ func (g *securityGroup) getSecurityGroupAndCvm(kt *kit.Kit, sgID, cvmID string) // createSGCommonRels 先删除cvmID关联的安全组关系,再创建新的安全组关系 // sgCloudIDs的入参顺序决定新建的关联关系的优先级 -func (g *securityGroup) createSGCommonRels(kt *kit.Kit, vendor enumor.Vendor, cvmID string, sgCloudIDs []string, - sgCloudIDToIDMap map[string]string) error { +func (g *securityGroup) createSGCommonRels(kt *kit.Kit, vendor enumor.Vendor, resType enumor.CloudResourceType, + cvmID string, sgIDs []string) error { createReq := &protocloud.SGCommonRelBatchUpsertReq{ DeleteReq: &dataproto.BatchDeleteReq{ Filter: tools.ExpressionAnd( tools.RuleEqual("res_id", cvmID), - tools.RuleEqual("res_type", enumor.CvmCloudResType), - tools.RuleEqual("vendor", vendor), + tools.RuleEqual("res_type", resType), ), }, } - for i, cloudID := range sgCloudIDs { + for i, sgID := range sgIDs { createReq.Rels = append(createReq.Rels, protocloud.SGCommonRelCreate{ - SecurityGroupID: sgCloudIDToIDMap[cloudID], + SecurityGroupID: sgID, Vendor: vendor, ResID: cvmID, - ResType: enumor.CvmCloudResType, + ResType: resType, Priority: int64(i) + 1, }) } @@ -151,8 +149,8 @@ func (g *securityGroup) createSGCommonRels(kt *kit.Kit, vendor enumor.Vendor, cv return nil } -func (g *securityGroup) getSecurityGroupMapByCloudIDs(kt *kit.Kit, vendor enumor.Vendor, cloudIDs []string) ( - map[string]string, error) { +func (g *securityGroup) getSecurityGroupMapByCloudIDs(kt *kit.Kit, vendor enumor.Vendor, region string, + cloudIDs []string) (map[string]string, error) { cloudIDs = slice.Unique(cloudIDs) m := make(map[string]string) @@ -161,6 +159,7 @@ func (g *securityGroup) getSecurityGroupMapByCloudIDs(kt *kit.Kit, vendor enumor Field: []string{"id", "cloud_id"}, Filter: tools.ExpressionAnd( tools.RuleIn("cloud_id", ids), + tools.RuleEqual("region", region), tools.RuleEqual("vendor", vendor), ), Page: core.NewDefaultBasePage(), diff --git a/cmd/hc-service/service/security-group/tcloud_security_group.go b/cmd/hc-service/service/security-group/tcloud_security_group.go index 53714ed8c2..60c64e5f32 100644 --- a/cmd/hc-service/service/security-group/tcloud_security_group.go +++ b/cmd/hc-service/service/security-group/tcloud_security_group.go @@ -23,8 +23,6 @@ import ( "errors" "fmt" - "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" - "hcm/pkg/adaptor/tcloud" typecvm "hcm/pkg/adaptor/types/cvm" typelb "hcm/pkg/adaptor/types/load-balancer" @@ -601,10 +599,10 @@ func (g *securityGroup) createSGCommonRelsForTCloud(kt *kit.Kit, client tcloud.T sgCloudIDs := make([]string, 0) for _, one := range cloudCvms { - sgCloudIDs = append(sgCloudIDs, common.StringValues(one.SecurityGroupIds)...) + sgCloudIDs = append(sgCloudIDs, converter.PtrToSlice(one.SecurityGroupIds)...) } - sgCloudIDToIDMap, err := g.getSecurityGroupMapByCloudIDs(kt, enumor.TCloud, sgCloudIDs) + sgCloudIDToIDMap, err := g.getSecurityGroupMapByCloudIDs(kt, enumor.TCloud, region, sgCloudIDs) if err != nil { logs.Errorf("get security group map by cloud ids failed, err: %v, cloudIDs: %v, rid: %s", err, sgCloudIDs, kt.Rid) @@ -617,10 +615,22 @@ func (g *securityGroup) createSGCommonRelsForTCloud(kt *kit.Kit, client tcloud.T logs.Errorf("cvm cloud id to id not found, cvmID: %s, rid: %s", converter.PtrToVal(one.InstanceId), kt.Rid) return fmt.Errorf("cvm cloud id to id not found, cvmID: %s", converter.PtrToVal(one.InstanceId)) } - err = g.createSGCommonRels(kt, enumor.TCloud, cvmID, sgCloudIDs, sgCloudIDToIDMap) + + sgIDs := make([]string, 0, len(one.SecurityGroupIds)) + for _, sgCloudID := range converter.PtrToSlice(one.SecurityGroupIds) { + sgID, ok := sgCloudIDToIDMap[sgCloudID] + if !ok { + logs.Errorf("cloud id(%s) not found in security group map, rid: %s", sgCloudID, kt.Rid) + return fmt.Errorf("cloud id(%s) not found in security group map", sgCloudID) + } + sgIDs = append(sgIDs, sgID) + } + + err = g.createSGCommonRels(kt, enumor.TCloud, enumor.CvmCloudResType, cvmID, sgIDs) if err != nil { // 不抛出err, 尽最大努力交付 - logs.Errorf("create sg common rels failed, err: %v, rid: %s", err, kt.Rid) + logs.Errorf("create sg common rels failed, err: %v, cvmID: %s, sgIDs: %v, rid: %s", + err, cvmID, converter.MapValueToSlice(sgCloudIDToIDMap), kt.Rid) } }