diff --git a/cmd/data-service/db-migration/migrations/20241128111704_modify_audit.go b/cmd/data-service/db-migration/migrations/20241128111704_modify_audit.go new file mode 100644 index 000000000..7c24ac0c3 --- /dev/null +++ b/cmd/data-service/db-migration/migrations/20241128111704_modify_audit.go @@ -0,0 +1,84 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +package migrations + +import ( + "fmt" + + "gorm.io/gorm" + + "github.com/TencentBlueKing/bk-bscp/cmd/data-service/db-migration/migrator" +) + +func init() { + // add current migration to migrator + migrator.GetMigrator().AddMigration(&migrator.Migration{ + Version: "20241128111704", + Name: "20241128111704_modify_audit", + Mode: migrator.GormMode, + Up: mig20241128111704Up, + Down: mig20241128111704Down, + }) +} + +// mig20241128111704Up for up migration +func mig20241128111704Up(tx *gorm.DB) error { + // Audits : audits + type Audits struct { + Detail string `gorm:"type:text"` + } + // Audits add new column + if tx.Migrator().HasColumn(&Audits{}, "detail") { + if err := tx.Migrator().AlterColumn(&Audits{}, "detail"); err != nil { + return err + } + } + + // 数据更新适应新版本 + err := tx.Exec("UPDATE audits SET res_type=\"release\", action=\"publish\", " + + "res_instance=REPLACE(res_instance,\"releases_name\",\"config_release_name\"), " + + "res_instance=REPLACE(res_instance,\"group\",\"config_release_scope\") WHERE " + + "action=\"publish_release_config\" and res_type=\"app_config\";").Error + + if err != nil { + return err + } + return nil +} + +// mig20241128111704Down for down migration +func mig20241128111704Down(tx *gorm.DB) error { + // Audits : audits + type Audits struct { + Detail string `gorm:"type:text"` + } + // Strategies add new column + if tx.Migrator().HasColumn(&Audits{}, "detail") { + if err := tx.Migrator().AlterColumn(&Audits{}, "detail"); err != nil { + return err + } + } + + // 回退数据更新适应旧版本 + err := tx.Exec("UPDATE audits SET res_type=\"app_config\", action=\"publish_release_config\", " + + "res_instance=REPLACE(res_instance,\"config_release_name\",\"releases_name\"), " + + "res_instance=REPLACE(res_instance,\"config_release_scope\",\"group\") WHERE " + + "action=\"publish\" and res_type=\"release\";").Error + + if err != nil { + fmt.Println("audits exec sql fail: ", err) + return err + } + + return nil +} diff --git a/cmd/data-service/service/app_template_binding.go b/cmd/data-service/service/app_template_binding.go index ee7309e3c..6fb246053 100644 --- a/cmd/data-service/service/app_template_binding.go +++ b/cmd/data-service/service/app_template_binding.go @@ -20,9 +20,9 @@ import ( "strings" "time" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/search" - "github.com/TencentBlueKing/bk-bscp/pkg/criteria/constant" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/i18n" @@ -129,6 +129,9 @@ func (s *Service) UpdateAppTemplateBinding(ctx context.Context, req *pbds.Update tx := s.dao.GenQuery().Begin() if err := s.dao.AppTemplateBinding().UpdateWithTx(kt, tx, appTemplateBinding); err != nil { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } logs.Errorf("update app template binding failed, err: %v, rid: %s", err, kt.Rid) return nil, err } @@ -1078,7 +1081,15 @@ func (s *Service) ImportFromTemplateSetToApp(ctx context.Context, req *pbds.Impo return nil, err } + isRollback := true tx := s.dao.GenQuery().Begin() + defer func() { + if isRollback { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kit.Rid) + } + } + }() appTemplateBinding := &table.AppTemplateBinding{ Spec: &table.AppTemplateBindingSpec{ TemplateSpaceIDs: tools.RemoveDuplicates(templateSpaceIds), @@ -1109,6 +1120,7 @@ func (s *Service) ImportFromTemplateSetToApp(ctx context.Context, req *pbds.Impo logs.Errorf("commit transaction failed, err: %v, rid: %s", err, kit.Rid) return nil, err } + isRollback = false return &pbbase.EmptyResp{}, nil } diff --git a/cmd/data-service/service/audit.go b/cmd/data-service/service/audit.go index 7a8fcae84..6caa3e79e 100644 --- a/cmd/data-service/service/audit.go +++ b/cmd/data-service/service/audit.go @@ -17,12 +17,14 @@ import ( "fmt" "time" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" + "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" - "github.com/TencentBlueKing/bk-bscp/pkg/types" pbapp "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/app" pbaudit "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/audit" pbstrategy "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/strategy" pbds "github.com/TencentBlueKing/bk-bscp/pkg/protocol/data-service" + "github.com/TencentBlueKing/bk-bscp/pkg/types" ) // ListAudits list audits. @@ -46,19 +48,27 @@ func (s *Service) ListAudits(ctx context.Context, req *pbds.ListAuditsReq) (*pbd var details []*pbaudit.ListAuditsAppStrategy for _, value := range aas { + // client的状态比较特殊,不能实时同步 + status := value.Audit.Status + detail := value.Audit.Detail + if value.Audit.ResourceType == string(enumor.Instance) && + value.Client.ReleaseChangeStatus == string(table.Failed) { + status = string(enumor.Failure) + detail = value.Client.FailedDetailReason + } details = append(details, &pbaudit.ListAuditsAppStrategy{ Audit: &pbaudit.Audit{ Id: value.Audit.ID, Spec: &pbaudit.AuditSpec{ ResType: value.Audit.ResourceType, Action: value.Audit.Action, - Rid: "", // 暂时用不到 - AppCode: "", // 暂时用不到 - Detail: "", // 暂时用不到 + Rid: "", // 暂时用不到 + AppCode: "", // 暂时用不到 + Detail: detail, // 暂时用不到 Operator: value.Audit.Operator, ResInstance: value.Audit.ResInstance, OperateWay: value.Audit.OperateWay, - Status: value.Audit.Status, + Status: status, IsCompare: value.Audit.IsCompare, }, Attachment: &pbaudit.AuditAttachment{ diff --git a/cmd/data-service/service/client.go b/cmd/data-service/service/client.go index f70620d0b..0c432c69c 100644 --- a/cmd/data-service/service/client.go +++ b/cmd/data-service/service/client.go @@ -26,11 +26,11 @@ import ( "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/logs" - sfs "github.com/TencentBlueKing/bk-bscp/pkg/sf-share" - "github.com/TencentBlueKing/bk-bscp/pkg/types" pbbase "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/base" pbclient "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/client" pbds "github.com/TencentBlueKing/bk-bscp/pkg/protocol/data-service" + sfs "github.com/TencentBlueKing/bk-bscp/pkg/sf-share" + "github.com/TencentBlueKing/bk-bscp/pkg/types" ) // BatchUpsertClientMetrics 批量操作client metrics @@ -913,7 +913,15 @@ func formatCpu(number float64) string { func (s *Service) RetryClients(ctx context.Context, req *pbds.RetryClientsReq) (*pbbase.EmptyResp, error) { kit := kit.FromGrpcContext(ctx) + isRollback := true tx := s.dao.GenQuery().Begin() + defer func() { + if isRollback { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kit.Rid) + } + } + }() if req.All { event := types.Event{ @@ -970,6 +978,7 @@ func (s *Service) RetryClients(ctx context.Context, req *pbds.RetryClientsReq) ( logs.Errorf("commit retry clients transaction failed, err: %v, rid: %s", err, kit.Rid) return nil, err } + isRollback = false return &pbbase.EmptyResp{}, nil } diff --git a/cmd/data-service/service/config_hook.go b/cmd/data-service/service/config_hook.go index 7a41d8459..8c54cb9a1 100644 --- a/cmd/data-service/service/config_hook.go +++ b/cmd/data-service/service/config_hook.go @@ -52,6 +52,9 @@ func (s *Service) UpdateConfigHook(ctx context.Context, req *pbds.UpdateConfigHo hook, err := s.getReleasedHook(kt, preHook) if err != nil { logs.Errorf("no released releases of the pre-hook, err: %v, rid: %s", err, kt.Rid) + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } return nil, errors.New("no released releases of the pre-hook") } diff --git a/cmd/data-service/service/config_item.go b/cmd/data-service/service/config_item.go index 0da49970c..a9dd99212 100644 --- a/cmd/data-service/service/config_item.go +++ b/cmd/data-service/service/config_item.go @@ -1245,7 +1245,15 @@ func (s *Service) UnDeleteConfigItem(ctx context.Context, req *pbds.UnDeleteConf } commitID, contentID := []uint32{}, []uint32{} + isRollback := true tx := s.dao.GenQuery().Begin() + defer func() { + if isRollback { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, grpcKit.Rid) + } + } + }() // 判断是不是新增的数据 if ci != nil && ci.ID != 0 { rci, errCi := s.dao.ReleasedCI().Get(grpcKit, req.Attachment.BizId, @@ -1260,9 +1268,6 @@ func (s *Service) UnDeleteConfigItem(ctx context.Context, req *pbds.UnDeleteConf } if err = s.dao.ConfigItem().DeleteWithTx(grpcKit, tx, ci); err != nil { logs.Errorf("recover config item failed, err: %v, rid: %s", err, grpcKit.Rid) - if rErr := tx.Rollback(); rErr != nil { - logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, grpcKit.Rid) - } return nil, errf.Errorf(errf.DBOpFailed, i18n.T(grpcKit, "recover config item failed, err: %v", err)) } @@ -1284,18 +1289,12 @@ func (s *Service) UnDeleteConfigItem(ctx context.Context, req *pbds.UnDeleteConf if err = s.dao.Commit().BatchDeleteWithTx(grpcKit, tx, commitID); err != nil { logs.Errorf("undo commit failed, err: %v, rid: %s", err, grpcKit.Rid) - if rErr := tx.Rollback(); rErr != nil { - logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, grpcKit.Rid) - } return nil, errf.Errorf(errf.DBOpFailed, i18n.T(grpcKit, "recover config item failed, err: %v", err)) } if err = s.dao.Content().BatchDeleteWithTx(grpcKit, tx, contentID); err != nil { logs.Errorf("undo content failed, err: %v, rid: %s", err, grpcKit.Rid) - if rErr := tx.Rollback(); rErr != nil { - logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, grpcKit.Rid) - } return nil, errf.Errorf(errf.DBOpFailed, i18n.T(grpcKit, "recover config item failed, err: %v", err)) } @@ -1308,9 +1307,6 @@ func (s *Service) UnDeleteConfigItem(ctx context.Context, req *pbds.UnDeleteConf } if err = s.dao.ConfigItem().RecoverConfigItem(grpcKit, tx, data); err != nil { logs.Errorf("recover config item failed, err: %v, rid: %s", err, grpcKit.Rid) - if rErr := tx.Rollback(); rErr != nil { - logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, grpcKit.Rid) - } return nil, errf.Errorf(errf.DBOpFailed, i18n.T(grpcKit, "recover config item failed, err: %v", err)) } @@ -1319,6 +1315,7 @@ func (s *Service) UnDeleteConfigItem(ctx context.Context, req *pbds.UnDeleteConf return nil, errf.Errorf(errf.DBOpFailed, i18n.T(grpcKit, "recover config item failed, err: %v", e)) } + isRollback = false return new(pbbase.EmptyResp), nil } @@ -1946,7 +1943,7 @@ func (s *Service) RemoveAppBoundTmplSet(ctx context.Context, req *pbds.RemoveApp }, } - if err = s.dao.AppTemplateBinding().Update(kit, appTemplateBinding); err != nil { + if err = s.dao.AppTemplateBinding().Update(kit, appTemplateBinding, req.TemplateSetId); err != nil { return nil, errf.Errorf(errf.DBOpFailed, i18n.T(kit, "remove the template set bound to the app failed, err: %s", err)) } diff --git a/cmd/data-service/service/credential_scope.go b/cmd/data-service/service/credential_scope.go index 5dbe05016..7bc63e01d 100644 --- a/cmd/data-service/service/credential_scope.go +++ b/cmd/data-service/service/credential_scope.go @@ -14,14 +14,17 @@ package service import ( "context" + "fmt" "time" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/logs" - "github.com/TencentBlueKing/bk-bscp/pkg/runtime/credential" pbcrs "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/credential-scope" pbds "github.com/TencentBlueKing/bk-bscp/pkg/protocol/data-service" + "github.com/TencentBlueKing/bk-bscp/pkg/runtime/credential" ) // ListCredentialScopes get credential scopes @@ -54,6 +57,11 @@ func (s *Service) UpdateCredentialScopes(ctx context.Context, kt := kit.FromGrpcContext(ctx) + credentialRecord, err := s.dao.Credential().Get(kt, req.BizId, req.CredentialId) + if err != nil { + return nil, err + } + tx := s.dao.GenQuery().Begin() for _, updated := range req.Updated { @@ -130,6 +138,18 @@ func (s *Service) UpdateCredentialScopes(ctx context.Context, } return nil, err } + + ad := s.dao.AuditDao().Decorator(kt, req.BizId, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.AssociatedAppConfigCredentialName, credentialRecord.Spec.Name), + Status: enumor.Success, + }).PrepareUpdate(&table.Credential{ID: req.CredentialId}) + if err := ad.Do(tx.Query); err != nil { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } + return nil, err + } + if err := tx.Commit(); err != nil { logs.Errorf("commit transaction failed, err: %v, rid: %s", err, kt.Rid) return nil, err diff --git a/cmd/data-service/service/hook.go b/cmd/data-service/service/hook.go index 22d2f2b15..7d5f1356b 100644 --- a/cmd/data-service/service/hook.go +++ b/cmd/data-service/service/hook.go @@ -19,16 +19,18 @@ import ( "gorm.io/gorm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/i18n" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/logs" - "github.com/TencentBlueKing/bk-bscp/pkg/tools" - "github.com/TencentBlueKing/bk-bscp/pkg/types" pbbase "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/base" pbhook "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/hook" pbds "github.com/TencentBlueKing/bk-bscp/pkg/protocol/data-service" + "github.com/TencentBlueKing/bk-bscp/pkg/tools" + "github.com/TencentBlueKing/bk-bscp/pkg/types" ) // CreateHook create hook. @@ -92,6 +94,20 @@ func (s *Service) CreateHook(ctx context.Context, req *pbds.CreateHookReq) (*pbd return nil, err } + err = s.dao.AuditDao().Decorator(kt, req.Attachment.BizId, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookName+constant.ResSeparator+constant.HookRevisionName, + hook.Spec.Name, revision.Spec.Name), + Status: enumor.Success, + Detail: revision.Spec.Memo, + }).PrepareCreate(revision).Do(tx.Query) + if err != nil { + logs.Errorf("PrepareCreate HookRevision failed, err: %v, rid: %s", err, kt.Rid) + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } + return nil, err + } + if e := tx.Commit(); e != nil { logs.Errorf("commit transaction failed, err: %v, rid: %s", e, kt.Rid) return nil, e diff --git a/cmd/data-service/service/hook_revision.go b/cmd/data-service/service/hook_revision.go index f415d8485..13c33d667 100644 --- a/cmd/data-service/service/hook_revision.go +++ b/cmd/data-service/service/hook_revision.go @@ -18,14 +18,16 @@ import ( "fmt" "time" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/logs" - "github.com/TencentBlueKing/bk-bscp/pkg/tools" - "github.com/TencentBlueKing/bk-bscp/pkg/types" pbbase "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/base" hr "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/hook-revision" pbds "github.com/TencentBlueKing/bk-bscp/pkg/protocol/data-service" + "github.com/TencentBlueKing/bk-bscp/pkg/tools" + "github.com/TencentBlueKing/bk-bscp/pkg/types" ) // CreateHookRevision create hook revision with option @@ -34,7 +36,8 @@ func (s *Service) CreateHookRevision(ctx context.Context, kt := kit.FromGrpcContext(ctx) - if _, err := s.dao.Hook().GetByID(kt, req.Attachment.BizId, req.Attachment.HookId); err != nil { + hook, err := s.dao.Hook().GetByID(kt, req.Attachment.BizId, req.Attachment.HookId) + if err != nil { logs.Errorf("get hook (%d) failed, err: %v, rid: %s", req.Attachment.HookId, err, kt.Rid) return nil, err } @@ -74,6 +77,20 @@ func (s *Service) CreateHookRevision(ctx context.Context, return nil, err } + err = s.dao.AuditDao().Decorator(kt, req.Attachment.BizId, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookName+constant.ResSeparator+constant.HookRevisionName, + hook.Spec.Name, req.Spec.Name), + Status: enumor.Success, + Detail: req.Spec.Memo, + }).PrepareCreate(hookRevision).Do(tx.Query) + if err != nil { + logs.Errorf("PrepareCreate HookRevision failed, err: %v, rid: %s", err, kt.Rid) + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } + return nil, err + } + if e := tx.Commit(); e != nil { logs.Errorf("commit transaction failed, err: %v, rid: %s", e, kt.Rid) return nil, e diff --git a/cmd/data-service/service/kv.go b/cmd/data-service/service/kv.go index 4c2bb7439..e9a70ac6b 100644 --- a/cmd/data-service/service/kv.go +++ b/cmd/data-service/service/kv.go @@ -332,7 +332,15 @@ func (s *Service) BatchUpsertKvs(ctx context.Context, req *pbds.BatchUpsertKvsRe return nil, errf.Errorf(errf.DBOpFailed, i18n.T(kt, "list kv failed, err: %v", err)) } + isRollback := true tx := s.dao.GenQuery().Begin() + defer func() { + if isRollback { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } + } + }() // 2. 检测服务配置项类型(相同的key类型是否一致) if err = s.checkKVConfigItemTypes(kt, req, kvs); err != nil { return nil, err @@ -340,9 +348,6 @@ func (s *Service) BatchUpsertKvs(ctx context.Context, req *pbds.BatchUpsertKvsRe // 3. 清空草稿区域 if err = s.clearDraftKVStore(kt, tx, req, kvs); err != nil { - if rErr := tx.Rollback(); rErr != nil { - logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) - } return nil, err } @@ -367,18 +372,12 @@ func (s *Service) BatchUpsertKvs(ctx context.Context, req *pbds.BatchUpsertKvsRe // 5. 创建或更新kv等操作 if len(toCreate) > 0 { if err = s.dao.Kv().BatchCreateWithTx(kt, tx, toCreate); err != nil { - if rErr := tx.Rollback(); rErr != nil { - logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) - } return nil, errf.Errorf(errf.DBOpFailed, i18n.T(kt, "batch import of KV config failed, err: %v", err)) } } if len(toUpdate) > 0 { if err = s.dao.Kv().BatchUpdateWithTx(kt, tx, toUpdate); err != nil { - if rErr := tx.Rollback(); rErr != nil { - logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) - } return nil, errf.Errorf(errf.DBOpFailed, i18n.T(kt, "batch import of KV config failed, err: %v", err)) } } @@ -387,6 +386,7 @@ func (s *Service) BatchUpsertKvs(ctx context.Context, req *pbds.BatchUpsertKvsRe logs.Errorf("commit transaction failed, err: %v, rid: %s", e, kt.Rid) return nil, errf.Errorf(errf.DBOpFailed, i18n.T(kt, "batch import of KV config failed, err: %v", e)) } + isRollback = false createIds, updateIds := []uint32{}, []uint32{} for _, item := range toCreate { @@ -614,6 +614,9 @@ func (s *Service) UnDeleteKv(ctx context.Context, req *pbds.UnDeleteKvReq) (*pbb toUpdate, err := s.getLatestReleasedKV(kt, req.GetBizId(), req.GetAppId(), kv) if err != nil { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } return nil, err } diff --git a/cmd/data-service/service/publish.go b/cmd/data-service/service/publish.go index 07ae37605..4da120202 100644 --- a/cmd/data-service/service/publish.go +++ b/cmd/data-service/service/publish.go @@ -24,9 +24,9 @@ import ( "gorm.io/gorm" "github.com/TencentBlueKing/bk-bscp/internal/components/itsm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/pkg/cc" - "github.com/TencentBlueKing/bk-bscp/pkg/criteria/constant" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/i18n" @@ -143,18 +143,18 @@ func (s *Service) SubmitPublishApprove( groupName = []string{"ALL"} } - resInstance := fmt.Sprintf("releases_name: %s\ngroup: %s", release.Spec.Name, strings.Join(groupName, ",")) + resInstance := fmt.Sprintf(constant.ConfigReleaseName+constant.ResSeparator+constant.ConfigReleaseScope, + release.Spec.Name, strings.Join(groupName, constant.NameSeparator)) // audit this to create strategy details - ad := s.dao.AuditDao().DecoratorV3(grpcKit, opt.BizID, &table.AuditField{ - OperateWay: grpcKit.OperateWay, - Action: enumor.PublishReleaseConfig, + ad := s.dao.AuditDao().Decorator(grpcKit, opt.BizID, &table.AuditField{ ResourceInstance: resInstance, Status: enumor.AuditStatus(opt.PublishStatus), AppId: app.AppID(), StrategyId: pshID, IsCompare: req.IsCompare, - }).PrepareCreateByInstance(pshID, req) + Detail: req.Memo, + }).PreparePublish(strategy) if err = ad.Do(tx.Query); err != nil { return nil, err } @@ -167,7 +167,7 @@ func (s *Service) SubmitPublishApprove( // itsm流程创建ticket if app.Spec.IsApprove { - scope := strings.Join(groupName, ",") + scope := strings.Join(groupName, constant.NameSeparator) ticketData, errCreate := s.submitCreateApproveTicket( grpcKit, app, release.Spec.Name, scope, req.Memo, ad.GetAuditID(), release.ID) if errCreate != nil { @@ -520,24 +520,22 @@ func (s *Service) GenerateReleaseAndPublish(ctx context.Context, req *pbds.Gener groupName = []string{"ALL"} } - resInstance := fmt.Sprintf("releases_name: %s\ngroup: %s", release.Spec.Name, strings.Join(groupName, ",")) + resInstance := fmt.Sprintf(constant.ConfigReleaseName+constant.ResSeparator+constant.ConfigReleaseScope, + release.Spec.Name, strings.Join(groupName, constant.NameSeparator)) // audit this to create strategy details - ad := s.dao.AuditDao().DecoratorV3(grpcKit, opt.BizID, &table.AuditField{ - OperateWay: grpcKit.OperateWay, - Action: enumor.PublishReleaseConfig, + ad := s.dao.AuditDao().Decorator(grpcKit, opt.BizID, &table.AuditField{ ResourceInstance: resInstance, Status: enumor.AuditStatus(opt.PublishStatus), - AppId: app.AppID(), StrategyId: pshID, - }).PrepareCreateByInstance(pshID, req) + }).PreparePublish(strategy) if err = ad.Do(tx.Query); err != nil { return nil, err } // itsm流程创建ticket if app.Spec.IsApprove { - scope := strings.Join(groupName, ",") + scope := strings.Join(groupName, constant.NameSeparator) ticketData, errCreate := s.submitCreateApproveTicket( grpcKit, app, release.Spec.Name, scope, req.ReleaseMemo, ad.GetAuditID(), release.ID) if errCreate != nil { @@ -682,7 +680,7 @@ func (s *Service) passApprove( result["itsm_ticket_status"] = constant.ItsmTicketStatusPassed } else { // 审批人列表更新 - result["approver_progress"] = strings.Join(newProgressUsers, ",") + result["approver_progress"] = strings.Join(newProgressUsers, constant.NameSeparator) } } diff --git a/cmd/data-service/service/release.go b/cmd/data-service/service/release.go index 5eeccff0e..4371c737c 100644 --- a/cmd/data-service/service/release.go +++ b/cmd/data-service/service/release.go @@ -126,6 +126,9 @@ func (s *Service) CreateRelease(ctx context.Context, req *pbds.CreateReleaseReq) // get app's all config items. cis, fErr := s.getAppConfigItems(grpcKit) if fErr != nil { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, grpcKit.Rid) + } logs.Errorf("get app's all config items failed, err: %v, rid: %s", fErr, grpcKit.Rid) return nil, fErr } @@ -133,6 +136,9 @@ func (s *Service) CreateRelease(ctx context.Context, req *pbds.CreateReleaseReq) // get app template revisions which are template config items tmplRevisions, fErr := s.getAppTmplRevisions(grpcKit) if fErr != nil { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, grpcKit.Rid) + } logs.Errorf("get app template revisions failed, err: %v, rid: %s", fErr, grpcKit.Rid) return nil, fErr } diff --git a/cmd/data-service/service/template.go b/cmd/data-service/service/template.go index 30153067c..b674ee349 100644 --- a/cmd/data-service/service/template.go +++ b/cmd/data-service/service/template.go @@ -1200,6 +1200,9 @@ func (s *Service) BatchUpdateTemplatePermissions(ctx context.Context, req *pbds. // 更新引用的服务 items, err := s.dao.AppTemplateBinding().ListAppTemplateBindingByAppIds(kt, req.GetBizId(), req.GetAppIds()) if err != nil { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } return nil, errf.Errorf(errf.DBOpFailed, i18n.T(kt, "list app template bindings by app ids failed, err: %s", err)) } diff --git a/cmd/data-service/service/template_set.go b/cmd/data-service/service/template_set.go index e4ab1f4cc..55d71860a 100644 --- a/cmd/data-service/service/template_set.go +++ b/cmd/data-service/service/template_set.go @@ -193,6 +193,9 @@ func (s *Service) UpdateTemplateSet(ctx context.Context, req *pbds.UpdateTemplat var oldTmplSets []*table.TemplateSet oldTmplSets, err = s.dao.TemplateSet().ListByIDs(kt, []uint32{req.Id}) if err != nil { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } logs.Errorf("list template sets by ids failed, err: %v, rid: %s", err, kt.Rid) return nil, err } @@ -201,6 +204,9 @@ func (s *Service) UpdateTemplateSet(ctx context.Context, req *pbds.UpdateTemplat atbs, err = s.dao.TemplateBindingRelation(). ListTemplateSetsBoundATBs(kt, req.Attachment.BizId, []uint32{req.Id}) if err != nil { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } logs.Errorf("list template set bound app template bindings failed, err: %v, rid: %s", err, kt.Rid) return nil, err } @@ -274,6 +280,9 @@ func (s *Service) DeleteTemplateSet(ctx context.Context, req *pbds.DeleteTemplat atbs, err = s.dao.TemplateBindingRelation(). ListTemplateSetsBoundATBs(kt, req.Attachment.BizId, []uint32{req.Id}) if err != nil { + if rErr := tx.Rollback(); rErr != nil { + logs.Errorf("transaction rollback failed, err: %v, rid: %s", rErr, kt.Rid) + } logs.Errorf("list template set bound app template bindings failed, err: %v, rid: %s", err, kt.Rid) return nil, err } diff --git a/internal/components/itsm/service.go b/internal/components/itsm/service.go index d043e467f..909f4779c 100644 --- a/internal/components/itsm/service.go +++ b/internal/components/itsm/service.go @@ -136,12 +136,10 @@ func GetWorkflowByService(ctx context.Context, serviceID int) (int, error) { func GetStateApproveByWorkfolw(ctx context.Context, workflowID int) (map[string]int, error) { itsmConf := cc.DataService().ITSM // 默认使用网关访问,如果为外部版,则使用ESB访问 - // 暂时使用外部地址测试,后面废除 - host := itsmConf.Host - // host := itsmConf.GatewayHost - // if itsmConf.External { - // host = itsmConf.Host - // } + host := itsmConf.GatewayHost + if itsmConf.External { + host = itsmConf.Host + } reqURL := fmt.Sprintf("%s%s?workflow_id=%d", host, getWorkflowDetailPath, workflowID) diff --git a/internal/criteria/constant/key.go b/internal/criteria/constant/key.go index 43e0668fe..f8ca4af06 100644 --- a/internal/criteria/constant/key.go +++ b/internal/criteria/constant/key.go @@ -209,3 +209,63 @@ const ( // TicketRevokedStatu 被撤销 TicketRevokedStatu = "REVOKED" ) + +// 操作记录资源实例相关 +const ( + // ResSeparator 不同资源名称叠加时分隔符 + ResSeparator = "\n" + // NameSeparator 相同资源名称叠加时分隔符 + NameSeparator = ", " + // AppName 服务名称 + AppName = "app_name: %s" + // ConfigFileAbsolutePath 配置文件绝对路径 + ConfigFileAbsolutePath = "config_file_absolute_path: %s" + // ConfigItemName 配置项名称 + ConfigItemName = "config_item_name: %s" + // HookName 脚本名称 + HookName = "hook_name: %s" + // VariableName 变量名称 + VariableName = "variable_name: %s" + // ConfigReleaseName 配置版本名称 + ConfigReleaseName = "config_release_name: %s" + // ConfigReleaseScope 配置上线范围 + ConfigReleaseScope = "config_release_scope: %s" + // GroupName 分组名称 + GroupName = "group_name: %s" + // HookRevisionName 脚本版本名称 + HookRevisionName = "hook_revision_name: %s" + // TemplateSpaceName 模版空间名称 + TemplateSpaceName = "template_space_name: %s" + // TemplateSetName 模版套餐名称 + TemplateSetName = "template_set_name: %s" + // TemplateAbsolutePath 模版文件绝对路径 + TemplateAbsolutePath = "template_absolute_path: %s" + // TemplateRevision 模版版本号 + TemplateRevision = "template_revision: %s" + // CredentialName 密钥名称 + CredentialName = "credential_name: %s" // nolint + // ReferenceHookName 引用脚本名称 + ReferenceHookName = "reference_%s_name: %s" + // ReplaceHookName 更换脚本名称 + ReplaceHookName = "replace_%s_name: %s" + // CancelPreHookName 取消脚本名称 + CancelHookName = "cancel_%s_name: %s" + // ObsoleteConfigReleaseName 废弃配置版本名称 + ObsoleteConfigReleaseName = "obsolete_config_release_name: %s" + // RestoreConfigReleaseName 恢复配置版本名称 + RestoreConfigReleaseName = "restore_config_release_name: %s" + // DeleteConfigReleaseName 删除配置版本名称 + DeleteConfigReleaseName = "delete_config_release_name: %s" + // CredentialEnableName 启用密钥名称 + CredentialEnableName = "credential_enable_name: %s" // nolint + // CredentialUnableName 禁用密钥名称 + CredentialUnableName = "credential_unable_name: %s" // nolint + // AssociatedAppConfigCredentialName 关联服务配置密钥名称 + AssociatedAppConfigCredentialName = "associated_app_config_credential_name: %s" // nolint + // ConfigRetryClientUID 配置重新拉取客户端UID + ConfigRetryClientUID = "config_retry_client_uid: %s" + // ConfigRetryClientIp 配置重新拉取客户端IP + ConfigRetryClientIp = "config_retry_client_ip: %s" + // OperateObject 等 xx 个对象进行操作 + OperateObject = "operate_objects: %d" // nolint +) diff --git a/internal/dal/dao/app.go b/internal/dal/dao/app.go index 95877b3c8..8c63b52ff 100644 --- a/internal/dal/dao/app.go +++ b/internal/dal/dao/app.go @@ -19,7 +19,9 @@ import ( rawgen "gorm.io/gen" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/i18n" @@ -180,7 +182,12 @@ func (dao *appDao) Create(kit *kit.Kit, g *table.App) (uint32, error) { } g.ID = id - ad := dao.auditDao.DecoratorV2(kit, g.BizID).PrepareCreate(g) + ad := dao.auditDao.Decorator(kit, g.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.AppName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + AppId: g.ID, + }).PrepareCreate(g) eDecorator := dao.event.Eventf(kit) // 多个使用事务处理 @@ -242,7 +249,13 @@ func (dao *appDao) Update(kit *kit.Kit, g *table.App) error { // 更新操作, 获取当前记录做审计 m := dao.genQ.App q := dao.genQ.App.WithContext(kit.Ctx) - ad := dao.auditDao.DecoratorV2(kit, g.BizID).PrepareUpdate(g, oldOne) + kit.AppID = g.ID + ad := dao.auditDao.Decorator(kit, g.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.AppName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + AppId: g.ID, + }).PrepareUpdate(g) eDecorator := dao.event.Eventf(kit) // 多个使用事务处理 @@ -302,7 +315,11 @@ func (dao *appDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.App) err if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, g.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.AppName, oldOne.Spec.Name), + Status: enumor.Success, + AppId: g.ID, + }).PrepareDelete(g) if err = ad.Do(tx.Query); err != nil { return err } diff --git a/internal/dal/dao/app_template_binding.go b/internal/dal/dao/app_template_binding.go index 674a5d1cc..f6b422fad 100644 --- a/internal/dal/dao/app_template_binding.go +++ b/internal/dal/dao/app_template_binding.go @@ -15,12 +15,15 @@ package dao import ( "errors" "fmt" + "strings" rawgen "gorm.io/gen" "gorm.io/gorm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/dal/utils" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/types" @@ -31,7 +34,7 @@ type AppTemplateBinding interface { // CreateWithTx create one app template binding instance with transaction. CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, atb *table.AppTemplateBinding) (uint32, error) // Update one app template binding's info. - Update(kit *kit.Kit, atb *table.AppTemplateBinding) error + Update(kit *kit.Kit, atb *table.AppTemplateBinding, removeTemplateSetId uint32) error // UpdateWithTx Update one app template binding's info with transaction. UpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, atb *table.AppTemplateBinding) error // BatchUpdateWithTx batch update app template binding's instances with transaction. @@ -124,22 +127,60 @@ func (dao *appTemplateBindingDao) ListAppTemplateBindingByAppIds(kit *kit.Kit, b // UpsertWithTx create or update one template variable instance with transaction. func (dao *appTemplateBindingDao) UpsertWithTx(kit *kit.Kit, tx *gen.QueryTx, atb *table.AppTemplateBinding) error { - m := dao.genQ.AppTemplateBinding + m := tx.AppTemplateBinding q := tx.AppTemplateBinding.WithContext(kit.Ctx) + + tSet := tx.TemplateSet + tSpace := tx.TemplateSpace + tssn := []types.TemplateSetSpaceName{} + + // 查询空间名称及套餐名称 + err := tSet.WithContext(kit.Ctx).Select(tSet.Name.As("template_set_name"), tSpace.Name.As("template_space_name")). + Join(tSpace.WithContext(kit.Ctx), tSpace.ID.EqCol(tSet.TemplateSpaceID)). + Where(tSet.ID.In(atb.Spec.TemplateSetIDs...)).Scan(&tssn) + if err != nil { + return err + } + + var templateSpaceNames []string + templateSpaceNamesM := make(map[string]struct{}) + var templateSetNames []string + for _, v := range tssn { + // 去重 + if _, ok := templateSpaceNamesM[v.TemplateSpaceName]; !ok { + templateSpaceNames = append(templateSpaceNames, v.TemplateSpaceName) + templateSpaceNamesM[v.TemplateSpaceName] = struct{}{} + } + templateSetNames = append(templateSetNames, v.TemplateSetName) + } + + resInstance := fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + strings.Join(templateSpaceNames, constant.NameSeparator), + strings.Join(templateSetNames, constant.NameSeparator)) + old, findErr := q.Where(m.BizID.Eq(atb.Attachment.BizID), m.AppID.Eq(atb.Attachment.AppID)).Take() - var ad AuditDo // if old exists, update it. if findErr == nil { atb.ID = old.ID - if _, err := tx.AppTemplateBinding.WithContext(kit.Ctx). + if _, err = tx.AppTemplateBinding.WithContext(kit.Ctx). Where(m.BizID.Eq(atb.Attachment.BizID), m.ID.Eq(atb.ID)). Select(m.Bindings, m.TemplateSpaceIDs, m.TemplateSetIDs, m.TemplateIDs, m.TemplateRevisionIDs, m.LatestTemplateIDs, m.Creator, m.Reviser, m.UpdatedAt). Updates(atb); err != nil { return err } - ad = dao.auditDao.DecoratorV2(kit, atb.Attachment.BizID).PrepareUpdate(atb, old) + + // audit + ad := dao.auditDao.Decorator(kit, atb.Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + AppId: atb.Attachment.AppID, + }).PrepareUpdate(&table.ConfigItem{ID: atb.ID}) + if err = ad.Do(tx.Query); err != nil { + return err + } + } else if errors.Is(findErr, gorm.ErrRecordNotFound) { // if old not exists, create it. id, err := dao.idGen.One(kit, table.Name(atb.TableName())) @@ -147,13 +188,21 @@ func (dao *appTemplateBindingDao) UpsertWithTx(kit *kit.Kit, tx *gen.QueryTx, at return err } atb.ID = id - if err := tx.AppTemplateBinding.WithContext(kit.Ctx).Create(atb); err != nil { + if err = tx.AppTemplateBinding.WithContext(kit.Ctx).Create(atb); err != nil { + return err + } + // audit + ad := dao.auditDao.Decorator(kit, atb.Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + AppId: atb.Attachment.AppID, + }).PrepareCreate(&table.AppTemplateBinding{ID: atb.ID}) + if err = ad.Do(tx.Query); err != nil { return err } - ad = dao.auditDao.DecoratorV2(kit, atb.Attachment.BizID).PrepareCreate(atb) } - return ad.Do(tx.Query) + return nil } // GetAppTemplateBindingByAppID 通过业务和服务ID获取模板绑定关系 @@ -187,7 +236,40 @@ func (dao *appTemplateBindingDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, g return 0, err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + tSet := tx.TemplateSet + tSpace := tx.TemplateSpace + tssn := []types.TemplateSetSpaceName{} + + // 查询空间名称及套餐名称 + err = tSet.WithContext(kit.Ctx).Select(tSet.Name.As("template_set_name"), tSpace.Name.As("template_space_name")). + Join(tSpace.WithContext(kit.Ctx), tSpace.ID.EqCol(tSet.TemplateSpaceID)). + Where(tSet.ID.In(g.Spec.TemplateSetIDs...)).Scan(&tssn) + if err != nil { + return 0, err + } + + var templateSpaceNames []string + templateSpaceNamesM := make(map[string]struct{}) + var templateSetNames []string + for _, v := range tssn { + // 去重 + if _, ok := templateSpaceNamesM[v.TemplateSpaceName]; !ok { + templateSpaceNames = append(templateSpaceNames, v.TemplateSpaceName) + templateSpaceNamesM[v.TemplateSpaceName] = struct{}{} + } + templateSetNames = append(templateSetNames, v.TemplateSetName) + } + + resInstance := fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + strings.Join(templateSpaceNames, constant.NameSeparator), + strings.Join(templateSetNames, constant.NameSeparator)) + // audit + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + AppId: g.Attachment.AppID, + }).PrepareCreate(&table.AppTemplateBinding{ID: g.ID}) + if err = ad.Do(tx.Query); err != nil { return 0, err } @@ -196,26 +278,50 @@ func (dao *appTemplateBindingDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, g } // Update one app template binding instance. -func (dao *appTemplateBindingDao) Update(kit *kit.Kit, g *table.AppTemplateBinding) error { +func (dao *appTemplateBindingDao) Update(kit *kit.Kit, g *table.AppTemplateBinding, removeTemplateSetId uint32) error { if err := g.ValidateUpdate(); err != nil { return err } if err := dao.validateAttachmentExist(kit, g.Attachment); err != nil { return err } + // 删除操作,当前update接口是被当作删除使用,获取当前记录做审计 - // 更新操作, 获取当前记录做审计 - m := dao.genQ.AppTemplateBinding - q := dao.genQ.AppTemplateBinding.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() + tSet := dao.genQ.TemplateSet + tSpace := dao.genQ.TemplateSpace + tssn := []types.TemplateSetSpaceName{} + + // 查询空间名称及套餐名称 + err := tSet.WithContext(kit.Ctx).Select(tSet.Name.As("template_set_name"), tSpace.Name.As("template_space_name")). + Join(tSpace.WithContext(kit.Ctx), tSpace.ID.EqCol(tSet.TemplateSpaceID)). + Where(tSet.ID.In(removeTemplateSetId)).Scan(&tssn) if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + + var templateSpaceNames []string + var templateSetNames []string + for _, v := range tssn { + // 无需去重 + templateSpaceNames = append(templateSpaceNames, v.TemplateSpaceName) + templateSetNames = append(templateSetNames, v.TemplateSetName) + } + + resInstance := fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + strings.Join(templateSpaceNames, constant.NameSeparator), + strings.Join(templateSetNames, constant.NameSeparator)) + + // audit + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + AppId: g.Attachment.AppID, + }).PrepareDelete(&table.AppTemplateBinding{ID: g.ID}) // 多个使用事务处理 updateTx := func(tx *gen.Query) error { - q = tx.AppTemplateBinding.WithContext(kit.Ctx) + m := tx.AppTemplateBinding + q := tx.AppTemplateBinding.WithContext(kit.Ctx) if _, err = q.Where(m.BizID.Eq(g.Attachment.BizID), m.ID.Eq(g.ID)). Select(m.Bindings, m.TemplateSpaceIDs, m.TemplateSetIDs, m.TemplateIDs, m.TemplateRevisionIDs, m.LatestTemplateIDs, m.Creator, m.Reviser, m.UpdatedAt). @@ -228,7 +334,7 @@ func (dao *appTemplateBindingDao) Update(kit *kit.Kit, g *table.AppTemplateBindi } return nil } - if err = dao.genQ.Transaction(updateTx); err != nil { + if err := dao.genQ.Transaction(updateTx); err != nil { return err } @@ -248,20 +354,51 @@ func (dao *appTemplateBindingDao) UpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, // 更新操作, 获取当前记录做审计 m := tx.AppTemplateBinding q := tx.AppTemplateBinding.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() - if err != nil { + + if _, err := q.Where(m.BizID.Eq(g.Attachment.BizID), m.ID.Eq(g.ID)). + Select(m.Bindings, m.TemplateSpaceIDs, m.TemplateSetIDs, m.TemplateIDs, m.TemplateRevisionIDs, + m.LatestTemplateIDs, m.Creator, m.Reviser, m.UpdatedAt). + Updates(g); err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) - if err = ad.Do(tx.Query); err != nil { + + // 更新操作, 获取当前记录做审计 + tSet := dao.genQ.TemplateSet + tSpace := dao.genQ.TemplateSpace + tssn := []types.TemplateSetSpaceName{} + + // 查询空间名称及套餐名称 + err := tSet.WithContext(kit.Ctx).Select(tSet.Name.As("template_set_name"), tSpace.Name.As("template_space_name")). + Join(tSpace.WithContext(kit.Ctx), tSpace.ID.EqCol(tSet.TemplateSpaceID)). + Where(tSet.ID.In(g.Spec.TemplateSetIDs...)).Scan(&tssn) + if err != nil { return err } - q = tx.AppTemplateBinding.WithContext(kit.Ctx) - if _, err = q.Where(m.BizID.Eq(g.Attachment.BizID), m.ID.Eq(g.ID)). - Select(m.Bindings, m.TemplateSpaceIDs, m.TemplateSetIDs, m.TemplateIDs, m.TemplateRevisionIDs, - m.LatestTemplateIDs, m.Creator, m.Reviser, m.UpdatedAt). - Updates(g); err != nil { + var templateSpaceNames []string + templateSpaceNamesM := make(map[string]struct{}) + var templateSetNames []string + for _, v := range tssn { + // 去重 + if _, ok := templateSpaceNamesM[v.TemplateSpaceName]; !ok { + templateSpaceNames = append(templateSpaceNames, v.TemplateSpaceName) + templateSpaceNamesM[v.TemplateSpaceName] = struct{}{} + } + templateSetNames = append(templateSetNames, v.TemplateSetName) + } + + resInstance := fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + strings.Join(templateSpaceNames, constant.NameSeparator), + strings.Join(templateSetNames, constant.NameSeparator)) + + // audit + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + AppId: g.Attachment.AppID, + }).PrepareUpdate(&table.AppTemplateBinding{ID: g.ID}) + + if err = ad.Do(tx.Query); err != nil { return err } @@ -300,11 +437,46 @@ func (dao *appTemplateBindingDao) Delete(kit *kit.Kit, g *table.AppTemplateBindi if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + // 更新操作, 获取当前记录做审计 + tSet := dao.genQ.TemplateSet + tSpace := dao.genQ.TemplateSpace + tssn := []types.TemplateSetSpaceName{} + + // 查询空间名称及套餐名称 + err = tSet.WithContext(kit.Ctx).Select(tSet.Name.As("template_set_name"), tSpace.Name.As("template_space_name")). + Join(tSpace.WithContext(kit.Ctx), tSpace.ID.EqCol(tSet.TemplateSpaceID)). + Where(tSet.ID.In(oldOne.Spec.TemplateSetIDs...)).Scan(&tssn) + if err != nil { + return err + } + + var templateSpaceNames []string + templateSpaceNamesM := make(map[string]struct{}) + var templateSetNames []string + for _, v := range tssn { + // 去重 + if _, ok := templateSpaceNamesM[v.TemplateSpaceName]; !ok { + templateSpaceNames = append(templateSpaceNames, v.TemplateSpaceName) + templateSpaceNamesM[v.TemplateSpaceName] = struct{}{} + } + templateSetNames = append(templateSetNames, v.TemplateSetName) + } + + resInstance := fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + strings.Join(templateSpaceNames, constant.NameSeparator), + strings.Join(templateSetNames, constant.NameSeparator)) + + // audit + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + AppId: oldOne.Attachment.AppID, + }).PrepareDelete(&table.AppTemplateBinding{ID: g.ID}) // 多个使用事务处理 deleteTx := func(tx *gen.Query) error { - q = tx.AppTemplateBinding.WithContext(kit.Ctx) + m := tx.AppTemplateBinding + q := tx.AppTemplateBinding.WithContext(kit.Ctx) if _, err = q.Where(m.BizID.Eq(g.Attachment.BizID)).Delete(g); err != nil { return err } @@ -314,7 +486,7 @@ func (dao *appTemplateBindingDao) Delete(kit *kit.Kit, g *table.AppTemplateBindi } return nil } - if err = dao.genQ.Transaction(deleteTx); err != nil { + if err := dao.genQ.Transaction(deleteTx); err != nil { return err } diff --git a/internal/dal/dao/app_template_variable.go b/internal/dal/dao/app_template_variable.go index 47cf7487d..7f7c5f908 100644 --- a/internal/dal/dao/app_template_variable.go +++ b/internal/dal/dao/app_template_variable.go @@ -14,10 +14,13 @@ package dao import ( "errors" + "fmt" "gorm.io/gorm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" ) @@ -94,7 +97,11 @@ func (dao *appTemplateVariableDao) Upsert(kit *kit.Kit, g *table.AppTemplateVari Updates(g); err != nil { return err } - ad = dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, old) + ad = dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.VariableName, g.Spec.GetVariableNames()), + Status: enumor.Success, + AppId: g.Attachment.AppID, + }).PrepareUpdate(old) } else if errors.Is(findErr, gorm.ErrRecordNotFound) { // if old not exists, create it. id, err := dao.idGen.One(kit, table.Name(g.TableName())) @@ -105,7 +112,11 @@ func (dao *appTemplateVariableDao) Upsert(kit *kit.Kit, g *table.AppTemplateVari if err := tx.AppTemplateVariable.WithContext(kit.Ctx).Create(g); err != nil { return err } - ad = dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ad = dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.VariableName, g.Spec.GetVariableNames()), + Status: enumor.Success, + AppId: g.Attachment.AppID, + }).PrepareCreate(g) } return ad.Do(tx) @@ -137,7 +148,11 @@ func (dao *appTemplateVariableDao) UpsertWithTx(kit *kit.Kit, tx *gen.QueryTx, g Updates(g); err != nil { return err } - ad = dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, old) + ad = dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.VariableName, g.Spec.GetVariableNames()), + Status: enumor.Success, + AppId: g.Attachment.AppID, + }).PrepareUpdate(old) } else if errors.Is(findErr, gorm.ErrRecordNotFound) { // if old not exists, create it. id, err := dao.idGen.One(kit, table.Name(g.TableName())) @@ -148,7 +163,11 @@ func (dao *appTemplateVariableDao) UpsertWithTx(kit *kit.Kit, tx *gen.QueryTx, g if err := tx.AppTemplateVariable.WithContext(kit.Ctx).Create(g); err != nil { return err } - ad = dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ad = dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.VariableName, g.Spec.GetVariableNames()), + Status: enumor.Success, + AppId: g.Attachment.AppID, + }).PrepareCreate(g) } return ad.Do(tx.Query) diff --git a/internal/dal/dao/audit.go b/internal/dal/dao/audit.go index 38f51ef0e..cb1b280aa 100644 --- a/internal/dal/dao/audit.go +++ b/internal/dal/dao/audit.go @@ -34,9 +34,7 @@ import ( type AuditDao interface { // Decorator is used to handle the audit process as a pipeline // according CUD scenarios. - Decorator(kit *kit.Kit, bizID uint32, res enumor.AuditResourceType) AuditDecorator - DecoratorV2(kit *kit.Kit, bizID uint32) AuditPrepare - DecoratorV3(kit *kit.Kit, bizID uint32, a *table.AuditField) AuditPrepare + Decorator(kit *kit.Kit, bizID uint32, a *table.AuditField) AuditPrepare // One insert one resource's audit. One(kit *kit.Kit, audit *table.Audit, opt *AuditOption) error // ListAuditsAppStrategy List audit apo strategy. @@ -83,19 +81,9 @@ type audit struct { idGen IDGenInterface } -// Decorator return audit decorator for to record audit. -func (au *audit) Decorator(kit *kit.Kit, bizID uint32, res enumor.AuditResourceType) AuditDecorator { - return initAuditBuilder(kit, bizID, res, au) -} - -// DecoratorV2 return audit decorator for to record audit. -func (au *audit) DecoratorV2(kit *kit.Kit, bizID uint32) AuditPrepare { - return initAuditBuilderV2(kit, bizID, au) -} - -// DecoratorV2 return audit decorator for to record audit. -func (au *audit) DecoratorV3(kit *kit.Kit, bizID uint32, a *table.AuditField) AuditPrepare { - return initAuditBuilderV3(kit, bizID, a, au) +// DecoratorV3 return audit decorator for to record audit. +func (au *audit) Decorator(kit *kit.Kit, bizID uint32, a *table.AuditField) AuditPrepare { + return initAuditBuilder(kit, bizID, a, au) } // One audit one resource's operation. @@ -142,7 +130,8 @@ func (au *audit) ListAuditsAppStrategy( } // priority display publish version config - publishCount, err := query.Where(audit.Action.Eq(string(enumor.PublishReleaseConfig))). + publishCount, err := query.Where(audit.Action.Eq(string(enumor.Publish)), + audit.ResourceType.Eq(string(enumor.Release))). Order(audit.CreatedAt.Desc()). ScanByPage(&publishs, int(req.Start), int(req.Limit)) if err != nil { @@ -159,7 +148,8 @@ func (au *audit) ListAuditsAppStrategy( if err != nil { return nil, 0, err } - noPublishCount, err := query2.Not(audit.Action.Eq(string(enumor.PublishReleaseConfig))). + noPublishCount, err := query2.Not(audit.Action.Eq(string(enumor.Publish)), + audit.ResourceType.Eq(string(enumor.Release))). Order(audit.CreatedAt.Desc()). ScanByPage(&noPublishs, int(residueOffset), int(req.Limit)-len(publishs)) if err != nil { @@ -171,16 +161,18 @@ func (au *audit) ListAuditsAppStrategy( } // createQuery create same query +// nolint funlen func (au *audit) createQuery(kit *kit.Kit, req *pbds.ListAuditsReq) (gen.IAuditDo, error) { audit := au.genQ.Audit app := au.genQ.App strategy := au.genQ.Strategy + client := au.genQ.Client // 后续改造中去掉audit.ResourceType.In,现在加上为了适配原来的数据 result := audit.WithContext(kit.Ctx).Select(audit.ID, audit.ResourceType, audit.ResourceID, audit.Action, audit.BizID, audit.AppID, audit.Operator, audit.CreatedAt, audit.ResInstance, audit.OperateWay, audit.Status, - audit.IsCompare, - app.Name, app.Creator, + audit.IsCompare, audit.Detail, + app.Name, app.Creator, client.ReleaseChangeStatus, client.FailedDetailReason, strategy.PublishType, strategy.PublishTime, strategy.PublishTime, strategy.FinalApprovalTime, strategy.PublishStatus, strategy.RejectReason, strategy.Approver, strategy.ApproverProgress, strategy.UpdatedAt, strategy.Reviser, strategy.Creator, strategy.ReleaseID, strategy.Scope, @@ -188,9 +180,10 @@ func (au *audit) createQuery(kit *kit.Kit, req *pbds.ListAuditsReq) (gen.IAuditD strategy.ItsmTicketType, strategy.ApproveType, strategy.Memo). LeftJoin(app, app.ID.EqCol(audit.AppID)). LeftJoin(strategy, strategy.ID.EqCol(audit.StrategyId)). - Where(audit.BizID.Eq(req.BizId), audit.ResourceType.In(string(enumor.ResAppConfig), string(enumor.ResGroup), - string(enumor.ResHook), string(enumor.ResTemplate), string(enumor.ResVariable), - string(enumor.ResCredential), string(enumor.ResInstance))) + LeftJoin(client, audit.ResourceID.EqCol(client.ID), audit.ResourceType.Eq(string(enumor.Instance))). + Where(audit.BizID.Eq(req.BizId), audit.ResourceType.In(string(enumor.App), string(enumor.Config), + string(enumor.Hook), string(enumor.Release), string(enumor.Group), + string(enumor.Template), string(enumor.Credential), string(enumor.Instance), string(enumor.Variable))) if req.Id != 0 { result = result.Where(audit.ID.Eq(req.Id)) @@ -220,13 +213,16 @@ func (au *audit) createQuery(kit *kit.Kit, req *pbds.ListAuditsReq) (gen.IAuditD } // 仅看上线操作 - if req.Operate == string(enumor.PublishReleaseConfig) { + if req.Operate == string(enumor.Publish) { result = result.Where(audit.Action.Eq(req.Operate)) } // 仅看失败操作 if req.Operate == string(enumor.Failure) { - result = result.Where(audit.Status.Eq(req.Operate)) + result = result.Where( + audit.WithContext(kit.Ctx).Where(audit.Status.Eq(req.Operate)). + Or(client.ReleaseChangeStatus.Eq(string(table.Failed))), + ) } if req.Name != "" { diff --git a/internal/dal/dao/audit_builder.go b/internal/dal/dao/audit_builder.go deleted file mode 100644 index 7624f5d58..000000000 --- a/internal/dal/dao/audit_builder.go +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Blueking Container Service available. - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dao - -import ( - "encoding/json" - "errors" - "fmt" - "reflect" - "strconv" - "time" - - "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" - "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" - "github.com/TencentBlueKing/bk-bscp/pkg/kit" - "github.com/TencentBlueKing/bk-bscp/pkg/logs" - filter2 "github.com/TencentBlueKing/bk-bscp/pkg/runtime/filter" -) - -// initAuditBuilder create a new audit builder instance. -func initAuditBuilder(kit *kit.Kit, bizID uint32, res enumor.AuditResourceType, ad *audit) AuditDecorator { - - ab := &AuditBuilder{ - toAudit: &table.Audit{ - BizID: bizID, - ResourceType: res, - CreatedAt: time.Now().UTC(), - Operator: kit.User, - Rid: kit.Rid, - AppCode: kit.AppCode, - }, - ad: ad, - bizID: bizID, - kit: kit, - } - - if bizID <= 0 { - ab.hitErr = errors.New("invalid audit biz id") - } - - if len(kit.User) == 0 { - ab.hitErr = errors.New("invalid audit operator") - } - - return ab -} - -// AuditDecorator is audit decorator interface, use to record audit. -type AuditDecorator interface { - AuditCreate(cur interface{}, opt *AuditOption) error - PrepareUpdate(updatedTo interface{}) AuditDecorator - PrepareDelete(resID uint32) AuditDecorator - AuditPublish(cur interface{}, opt *AuditOption) error - Do(opt *AuditOption) error -} - -// AuditBuilder is a wrapper decorator to handle all the resource's -// audit operation. -type AuditBuilder struct { - hitErr error - - toAudit *table.Audit - bizID uint32 - kit *kit.Kit - prev interface{} - changed map[string]interface{} - ad *audit -} - -// AuditCreate set the resource's current details. -// Note: -// 1. must call this after the resource has already been created. -// 2. cur should be a *struct. -func (ab *AuditBuilder) AuditCreate(cur interface{}, opt *AuditOption) error { - if ab.hitErr != nil { - return ab.hitErr - } - - ab.toAudit.Action = enumor.Create - ab.prev = cur - - switch val := cur.(type) { - case *table.ConfigItem: - configItem := val - ab.toAudit.AppID = configItem.Attachment.AppID - ab.toAudit.ResourceID = configItem.ID - - case *table.Content: - content := val - ab.toAudit.AppID = content.Attachment.AppID - ab.toAudit.ResourceID = content.ID - - case *table.Commit: - commit := val - ab.toAudit.AppID = commit.Attachment.AppID - ab.toAudit.ResourceID = commit.ID - - case *table.Release: - release := val - ab.toAudit.AppID = release.Attachment.AppID - ab.toAudit.ResourceID = release.ID - - case *table.Hook: - sset := val - ab.toAudit.ResourceID = sset.ID - - case *table.TemplateSpace: - sset := val - ab.toAudit.ResourceID = sset.ID - - case *table.Group: - sset := val - ab.toAudit.ResourceID = sset.ID - - case []*table.ReleasedConfigItem: - items := val - ab.toAudit.AppID = items[0].Attachment.AppID - ab.toAudit.ResourceID = items[0].ReleaseID - - default: - logs.Errorf("unsupported audit create resource: %s, type: %s, rid: %v", ab.toAudit.ResourceType, - reflect.TypeOf(cur), ab.toAudit.Rid) - return fmt.Errorf("unsupported audit create resource: %s", ab.toAudit.ResourceType) - } - - detail := &table.AuditBasicDetail{ - Prev: ab.prev, - Changed: nil, - } - js, err := json.Marshal(detail) - if err != nil { - return fmt.Errorf("marshal audit detail failed, err: %v", err) - } - ab.toAudit.Detail = string(js) - - return ab.ad.One(ab.kit, ab.toAudit, opt) -} - -// AuditPublish set the publish content's current details. -// Note: -// 1. must call this after the resource has already been published. -// 2. cur should be a *struct. -func (ab *AuditBuilder) AuditPublish(cur interface{}, opt *AuditOption) error { - if ab.hitErr != nil { - return ab.hitErr - } - - ab.toAudit.Action = enumor.Publish - ab.prev = cur - - switch val := cur.(type) { - case *table.Strategy: - strategy := val - ab.toAudit.AppID = strategy.Attachment.AppID - ab.toAudit.ResourceID = strategy.ID - - default: - logs.Errorf("unsupported audit publish resource: %s, type: %s, rid: %v", ab.toAudit.ResourceType, - reflect.TypeOf(cur), ab.toAudit.Rid) - return fmt.Errorf("unsupported audit publish resource: %s", ab.toAudit.ResourceType) - } - - detail := &table.AuditBasicDetail{ - Prev: ab.prev, - Changed: nil, - } - js, err := json.Marshal(detail) - if err != nil { - return fmt.Errorf("marshal audit detail failed, err: %v", err) - } - ab.toAudit.Detail = string(js) - - return ab.ad.One(ab.kit, ab.toAudit, opt) -} - -// PrepareUpdate prepare the resource's previous instance details by -// get the instance's detail from db and save it to ab.prev for later use. -// Note: -// 1. call this before resource is updated. -// 2. updatedTo means 'to be updated to data', it should be a *struct. -func (ab *AuditBuilder) PrepareUpdate(updatedTo interface{}) AuditDecorator { - if ab.hitErr != nil { - return ab - } - - ab.toAudit.Action = enumor.Update - - switch val := updatedTo.(type) { - case *table.ConfigItem: - ci := val - if err := ab.decorateConfigItemUpdate(ci); err != nil { - ab.hitErr = err - return ab - } - - case *table.Group: - group := val - if err := ab.decorateGroupUpdate(group); err != nil { - ab.hitErr = err - return ab - } - - default: - logs.Errorf("unsupported audit update resource: %s, type: %s, rid: %v", ab.toAudit.ResourceType, - reflect.TypeOf(updatedTo), ab.toAudit.Rid) - ab.hitErr = fmt.Errorf("unsupported audit update resource: %s", ab.toAudit.ResourceType) - return ab - } - - detail := &table.AuditBasicDetail{ - Prev: ab.prev, - Changed: ab.changed, - } - - js, err := json.Marshal(detail) - if err != nil { - ab.hitErr = fmt.Errorf("marshal audit detail failed, err: %v", err) - return ab - } - ab.toAudit.Detail = string(js) - - return ab -} - -func (ab *AuditBuilder) decorateConfigItemUpdate(ci *table.ConfigItem) error { - ab.toAudit.AppID = ci.Attachment.AppID - ab.toAudit.ResourceID = ci.ID - - prevCI, err := ab.getConfigItem(ci.ID) - if err != nil { - return err - } - - ab.prev = prevCI - - changed, err := parseChangedSpecFields(prevCI, ci) - if err != nil { - ab.hitErr = err - return fmt.Errorf("parse config item changed spec field failed, err: %v", err) - } - - ab.changed = changed - return nil -} - -func (ab *AuditBuilder) decorateGroupUpdate(group *table.Group) error { - ab.toAudit.ResourceID = group.ID - - preGroup, err := ab.getGroup(group.ID) - if err != nil { - return err - } - - ab.prev = preGroup - - changed, err := parseChangedSpecFields(preGroup, group) - if err != nil { - ab.hitErr = err - return fmt.Errorf("parse group changed spec field failed, err: %v", err) - } - - ab.changed = changed - return nil -} - -// PrepareDelete prepare the resource's previous instance details by -// get the instance's detail from db and save it to ab.prev for later use. -// Note: call this before resource is deleted. -func (ab *AuditBuilder) PrepareDelete(resID uint32) AuditDecorator { - if ab.hitErr != nil { - return ab - } - - ab.toAudit.Action = enumor.Delete - - switch ab.toAudit.ResourceType { - case enumor.ConfigItem: - configItem, err := ab.getConfigItem(resID) - if err != nil { - ab.hitErr = err - return ab - } - ab.toAudit.AppID = configItem.Attachment.AppID - ab.toAudit.ResourceID = configItem.ID - ab.prev = configItem - - case enumor.Group: - group, err := ab.getGroup(resID) - if err != nil { - ab.hitErr = err - return ab - } - ab.toAudit.ResourceID = group.ID - ab.prev = group - - default: - ab.hitErr = fmt.Errorf("unsupported audit deleted resource: %s", ab.toAudit.ResourceType) - return ab - } - - detail := &table.AuditBasicDetail{ - Prev: ab.prev, - Changed: nil, - } - - js, err := json.Marshal(detail) - if err != nil { - ab.hitErr = fmt.Errorf("marshal audit detail failed, err: %v", err) - return ab - } - ab.toAudit.Detail = string(js) - - return ab -} - -// Do save audit log to the db immediately. -func (ab *AuditBuilder) Do(opt *AuditOption) error { - - if ab.hitErr != nil { - return ab.hitErr - } - - return ab.ad.One(ab.kit, ab.toAudit, opt) - -} - -func (ab *AuditBuilder) getConfigItem(configItemID uint32) (*table.ConfigItem, error) { - var sqlSentence []string - sqlSentence = append(sqlSentence, "SELECT ", table.ConfigItemColumns.NamedExpr(), " FROM ", - table.ConfigItemTable.Name(), " WHERE id = ", strconv.Itoa(int(configItemID)), " AND biz_id = ", - strconv.Itoa(int(ab.bizID))) - filter := filter2.SqlJoint(sqlSentence) - - one := new(table.ConfigItem) - err := ab.ad.orm.Do(ab.ad.sd.MustSharding(ab.bizID)).Get(ab.kit.Ctx, one, filter) - if err != nil { - return nil, fmt.Errorf("get config item details failed, err: %v", err) - } - - return one, nil -} - -func (ab *AuditBuilder) getGroup(groupID uint32) (*table.Group, error) { - var sqlSentence []string - sqlSentence = append(sqlSentence, "SELECT ", table.GroupColumns.NamedExpr(), " FROM ", table.GroupTable.Name(), - " WHERE id = ", strconv.Itoa(int(groupID)), " AND biz_id = ", strconv.Itoa(int(ab.bizID))) - filter := filter2.SqlJoint(sqlSentence) - - one := new(table.Group) - err := ab.ad.orm.Do(ab.ad.sd.MustSharding(ab.bizID)).Get(ab.kit.Ctx, one, filter) - if err != nil { - return nil, fmt.Errorf("get group details failed, err: %v", err) - } - - return one, nil -} - -// parseChangedSpecFields parse the changed filed with pre and cur *structs' Spec field. -// both pre and curl should be a *struct, if not, it will 'panic'. -// Note: -// 1. the pre and cur should be the same structs' pointer, and should -// have a 'Spec' struct field. -// 2. this func only compare 'Spec' field. -// 3. if one of the cur's Spec's filed value is zero, then this filed will be ignored. -// 4. the returned update field's key is this field's 'db' tag. -func parseChangedSpecFields(pre, cur interface{}) (map[string]interface{}, error) { - preV := reflect.ValueOf(pre) - if preV.Kind() != reflect.Ptr { - return nil, errors.New("parse changed spec field, but pre data is not a *struct") - } - - curV := reflect.ValueOf(cur) - if curV.Kind() != reflect.Ptr { - return nil, errors.New("parse changed spec field, but cur data is not a *struct") - } - - // make sure the pre and data is the same struct. - if !reflect.TypeOf(pre).AssignableTo(reflect.TypeOf(cur)) { - return nil, errors.New("parse changed spec field, but pre and cur resource type is not different, " + - "can not be compared") - } - - prevSpec := preV.Elem().FieldByName("Spec") - curSpec := curV.Elem().FieldByName("Spec") - if prevSpec.IsZero() || curSpec.IsZero() { - return nil, errors.New("pre or cur data do not has a 'Spec' struct field") - } - - prevSpecV := prevSpec.Elem() - curSpecV := curSpec.Elem() - changedField := make(map[string]interface{}) - - // compare spec's detail - for i := 0; i < prevSpecV.NumField(); i++ { - preName := prevSpecV.Type().Field(i).Name - curFieldV := curSpecV.FieldByName(preName) - if curFieldV.IsZero() { - // if this filed value is a zero value, then skip it. - // which means it is not updated. - continue - } - - if reflect.DeepEqual(prevSpecV.Field(i).Interface(), curFieldV.Interface()) { - // this field's value is not changed. - continue - } - - dbTag := prevSpecV.Type().Field(i).Tag.Get("db") - if len(dbTag) == 0 { - // fallback to json tag - dbTag = prevSpecV.Type().Field(i).Tag.Get("json") - } - - if len(dbTag) == 0 { - return nil, fmt.Errorf("filed: %s do not have a db or json tag, can not compare", preName) - } - - changedField[dbTag] = curFieldV.Interface() - } - - return changedField, nil -} diff --git a/internal/dal/dao/audit_builder_test.go b/internal/dal/dao/audit_builder_test.go index b3b2762fe..0d72bd428 100644 --- a/internal/dal/dao/audit_builder_test.go +++ b/internal/dal/dao/audit_builder_test.go @@ -13,61 +13,9 @@ package dao import ( - "fmt" "testing" - - "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" ) func TestParseChangedSpecFields(t *testing.T) { - pre := &table.App{ - ID: 1, - BizID: 2, - Spec: &table.AppSpec{ - Name: "api", - ConfigType: table.File, - Memo: "this is a memo", - }, - Revision: nil, - } - - cur := &table.App{ - ID: 1, - BizID: 2, - Spec: &table.AppSpec{ - Name: "server", - ConfigType: "", - Memo: "this is a changed memo!", - }, - Revision: nil, - } - - changed, err := parseChangedSpecFields(pre, cur) - if err != nil { - t.Errorf("test parse changed spec fields failed, err: %v", err) - return - } - - nameV, exist := changed["name"] - if !exist { - t.Error("test parse changed spec fields failed, name should be changed.") - return - } - - if fmt.Sprintf("%v", nameV) != "server" { - t.Error("test parse changed spec fields failed, name's value is mistake.") - return - } - - memoV, exist := changed["memo"] - if !exist { - t.Error("test parse changed spec fields failed, memo should be changed.") - return - } - - if fmt.Sprintf("%v", memoV) != "this is a changed memo!" { - t.Error("test parse changed spec fields failed, memo's value is mistake.") - return - } } diff --git a/internal/dal/dao/audit_builder_v2.go b/internal/dal/dao/audit_builder_v2.go index d81bfcc78..93c4875ae 100644 --- a/internal/dal/dao/audit_builder_v2.go +++ b/internal/dal/dao/audit_builder_v2.go @@ -13,9 +13,7 @@ package dao import ( - "encoding/json" "errors" - "fmt" "time" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" @@ -40,40 +38,13 @@ type AuditRes interface { // AuditPrepare auditBuilder interface type AuditPrepare interface { PrepareCreate(obj AuditRes) AuditDo - PrepareUpdate(obj, oldObj AuditRes) AuditDo + PrepareUpdate(obj AuditRes) AuditDo PrepareDelete(obj AuditRes) AuditDo PreparePublish(obj AuditRes) AuditDo - PrepareCreateByInstance(resId uint32, obj interface{}) AuditDo } -// initAuditBuilderV2 create a new audit builder instance. -func initAuditBuilderV2(kit *kit.Kit, bizID uint32, ad *audit) AuditPrepare { - ab := &AuditBuilderV2{ - toAudit: &table.Audit{ - BizID: bizID, - CreatedAt: time.Now().UTC(), - Operator: kit.User, - Rid: kit.Rid, - AppCode: kit.AppCode, - }, - ad: ad, - bizID: bizID, - kit: kit, - } - - if bizID <= 0 { - ab.hitErr = errors.New("invalid audit biz id") - } - - if len(kit.User) == 0 { - ab.hitErr = errors.New("invalid audit operator") - } - - return ab -} - -// initAuditBuilderV3 create a new audit builder instance. -func initAuditBuilderV3(kit *kit.Kit, bizID uint32, au *table.AuditField, ad *audit) AuditPrepare { +// initAuditBuilder create a new audit builder instance. +func initAuditBuilder(kit *kit.Kit, bizID uint32, au *table.AuditField, ad *audit) AuditPrepare { ab := &AuditBuilderV2{ toAudit: &table.Audit{ BizID: bizID, @@ -81,20 +52,18 @@ func initAuditBuilderV3(kit *kit.Kit, bizID uint32, au *table.AuditField, ad *au Operator: kit.User, Rid: kit.Rid, AppCode: kit.AppCode, - Action: au.Action, Status: au.Status, ResInstance: au.ResourceInstance, - OperateWay: au.OperateWay, + OperateWay: kit.OperateWay, StrategyId: au.StrategyId, IsCompare: au.IsCompare, + Detail: au.Detail, }, ad: ad, bizID: bizID, kit: kit, } - ab.toAudit.ResourceType = enumor.ActionMap[ab.toAudit.Action] - // default value if ab.toAudit.OperateWay != string(enumor.WebUI) { ab.toAudit.OperateWay = string(enumor.API) @@ -124,8 +93,6 @@ type AuditBuilderV2 struct { toAudit *table.Audit bizID uint32 kit *kit.Kit - prev interface{} - changed map[string]interface{} ad *audit } @@ -148,68 +115,15 @@ func (ab *AuditBuilderV2) PrepareCreate(obj AuditRes) AuditDo { ab.toAudit.ResourceType = enumor.AuditResourceType(obj.ResType()) ab.toAudit.ResourceID = obj.ResID() ab.toAudit.Action = enumor.Create - ab.prev = obj - - detail := &table.AuditBasicDetail{ - Prev: ab.prev, - Changed: nil, - } - - js, err := json.Marshal(detail) - if err != nil { - ab.hitErr = err - return ab - } - ab.toAudit.Detail = string(js) - - return ab -} - -// PrepareCreateByInstance 创建资源 -func (ab *AuditBuilderV2) PrepareCreateByInstance(resId uint32, obj interface{}) AuditDo { - ab.toAudit.ResourceID = resId - ab.prev = obj - - detail := &table.AuditBasicDetail{ - Prev: ab.prev, - Changed: nil, - } - - js, err := json.Marshal(detail) - if err != nil { - ab.hitErr = err - return ab - } - ab.toAudit.Detail = string(js) return ab } // PrepareUpdate 更新资源, 会记录 spec 对比值 -func (ab *AuditBuilderV2) PrepareUpdate(obj, oldObj AuditRes) AuditDo { +func (ab *AuditBuilderV2) PrepareUpdate(obj AuditRes) AuditDo { ab.toAudit.ResourceType = enumor.AuditResourceType(obj.ResType()) ab.toAudit.ResourceID = obj.ResID() ab.toAudit.Action = enumor.Update - ab.prev = oldObj - - changed, err := parseChangedSpecFields(oldObj, obj) - if err != nil { - ab.hitErr = err - return ab - } - ab.changed = changed - - detail := &table.AuditBasicDetail{ - Prev: ab.prev, - Changed: ab.changed, - } - - js, err := json.Marshal(detail) - if err != nil { - ab.hitErr = fmt.Errorf("marshal audit detail failed, err: %v", err) - return ab - } - ab.toAudit.Detail = string(js) return ab } @@ -219,19 +133,7 @@ func (ab *AuditBuilderV2) PrepareDelete(obj AuditRes) AuditDo { ab.toAudit.ResourceType = enumor.AuditResourceType(obj.ResType()) ab.toAudit.ResourceID = obj.ResID() ab.toAudit.Action = enumor.Delete - ab.prev = obj - - detail := &table.AuditBasicDetail{ - Prev: ab.prev, - Changed: nil, - } - js, err := json.Marshal(detail) - if err != nil { - ab.hitErr = fmt.Errorf("marshal audit detail failed, err: %v", err) - return ab - } - ab.toAudit.Detail = string(js) return ab } @@ -240,19 +142,6 @@ func (ab *AuditBuilderV2) PreparePublish(obj AuditRes) AuditDo { ab.toAudit.ResourceType = enumor.AuditResourceType(obj.ResType()) ab.toAudit.ResourceID = obj.ResID() ab.toAudit.Action = enumor.Publish - ab.prev = obj - - detail := &table.AuditBasicDetail{ - Prev: ab.prev, - Changed: nil, - } - - js, err := json.Marshal(detail) - if err != nil { - ab.hitErr = err - return ab - } - ab.toAudit.Detail = string(js) return ab } diff --git a/internal/dal/dao/client.go b/internal/dal/dao/client.go index 8c5740a41..464771c89 100644 --- a/internal/dal/dao/client.go +++ b/internal/dal/dao/client.go @@ -24,8 +24,10 @@ import ( "gorm.io/gen/field" "gorm.io/gorm/clause" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/dal/utils" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" pbclient "github.com/TencentBlueKing/bk-bscp/pkg/protocol/core/client" @@ -168,6 +170,11 @@ func (dao *clientDao) UpdateRetriedClientsStatusWithTx(kit *kit.Kit, tx *gen.Que m := dao.genQ.Client q := tx.Client.WithContext(kit.Ctx) + clients, err := q.Where(m.ID.In(ids...)).Find() + if err != nil { + return err + } + if len(ids) == 0 && all { q = q.Where(m.ReleaseChangeStatus.Eq(string(table.Failed))) } @@ -175,12 +182,45 @@ func (dao *clientDao) UpdateRetriedClientsStatusWithTx(kit *kit.Kit, tx *gen.Que if len(ids) > 0 { q = q.Where(m.ID.In(ids...)) } - _, err := q.Select(m.ReleaseChangeStatus).Updates(map[string]interface{}{ + _, err = q.Select(m.ReleaseChangeStatus).Updates(map[string]interface{}{ m.ReleaseChangeStatus.ColumnName().String(): table.Processing, }) if err != nil { return err } + + // 单个重试 + if len(ids) == 1 { + ad := dao.auditDao.Decorator(kit, clients[0].Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigRetryClientUID+constant.ResSeparator+ + constant.ConfigRetryClientIp, clients[0].Attachment.UID, clients[0].Spec.Ip), + Status: enumor.Success, + AppId: clients[0].Attachment.AppID, + }).PrepareUpdate(clients[0]) + err = ad.Do(tx.Query) + if err != nil { + return err + } + } + + // 批量重试 + if len(ids) > 1 { + // 截取前三个对象 + var ips []string + for i := 0; i < len(clients) && i < 3; i++ { + ips = append(ips, clients[i].Spec.Ip) + } + ad := dao.auditDao.Decorator(kit, clients[0].Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.OperateObject+constant.ResSeparator+constant.ConfigRetryClientIp, + len(clients), strings.Join(ips, constant.NameSeparator)), + Status: enumor.Success, + AppId: clients[0].Attachment.AppID, + }).PrepareUpdate(&table.Client{}) + err = ad.Do(tx.Query) + if err != nil { + return err + } + } return nil } diff --git a/internal/dal/dao/client_query.go b/internal/dal/dao/client_query.go index 3abd871e8..5f5e33e16 100644 --- a/internal/dal/dao/client_query.go +++ b/internal/dal/dao/client_query.go @@ -86,11 +86,6 @@ func (dao *clientQueryDao) Delete(kit *kit.Kit, data *table.ClientQuery) error { // 删除操作, 获取当前记录做审计 m := dao.genQ.ClientQuery q := dao.genQ.ClientQuery.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(data.ID), m.BizID.Eq(data.Attachment.BizID), m.AppID.Eq(data.Attachment.AppID)).Take() - if err != nil { - return err - } - ad := dao.auditDao.DecoratorV2(kit, data.Attachment.BizID).PrepareDelete(oldOne) // 多个使用事务处理 deleteTx := func(tx *gen.Query) error { @@ -99,9 +94,6 @@ func (dao *clientQueryDao) Delete(kit *kit.Kit, data *table.ClientQuery) error { return e } - if e := ad.Do(tx); e != nil { - return e - } return nil } if e := dao.genQ.Transaction(deleteTx); e != nil { @@ -127,16 +119,11 @@ func (dao *clientQueryDao) Create(kit *kit.Kit, data *table.ClientQuery) (uint32 } data.ID = id - ad := dao.auditDao.DecoratorV2(kit, data.Attachment.BizID).PrepareCreate(data) - createTx := func(tx *gen.Query) error { q := tx.ClientQuery.WithContext(kit.Ctx) if err = q.Create(data); err != nil { return err } - if err = ad.Do(tx); err != nil { - return err - } return nil } diff --git a/internal/dal/dao/commit.go b/internal/dal/dao/commit.go index 9ac6b7fa5..486c27e37 100644 --- a/internal/dal/dao/commit.go +++ b/internal/dal/dao/commit.go @@ -99,18 +99,12 @@ func (dao *commitDao) Create(kit *kit.Kit, commit *table.Commit) (uint32, error) commit.ID = id - ad := dao.auditDao.DecoratorV2(kit, commit.Attachment.BizID).PrepareCreate(commit) - createTx := func(tx *gen.Query) error { q := tx.Commit.WithContext(kit.Ctx) if err = q.Create(commit); err != nil { return err } - if err = ad.Do(tx); err != nil { - return err - } - return nil } if err = dao.genQ.Transaction(createTx); err != nil { @@ -143,11 +137,6 @@ func (dao *commitDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, commit *table. return 0, err } - ad := dao.auditDao.DecoratorV2(kit, commit.Attachment.BizID).PrepareCreate(commit) - if err := ad.Do(tx.Query); err != nil { - return 0, fmt.Errorf("audit create commit failed, err: %v", err) - } - return id, nil } diff --git a/internal/dal/dao/config_item.go b/internal/dal/dao/config_item.go index 7ab224ffe..11cc3907c 100644 --- a/internal/dal/dao/config_item.go +++ b/internal/dal/dao/config_item.go @@ -15,13 +15,17 @@ package dao import ( "errors" "fmt" + "path" + "strings" "github.com/samber/lo" "gorm.io/gen/field" "gorm.io/gorm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/pkg/cc" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/i18n" @@ -144,29 +148,19 @@ func (dao *configItemDao) UpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, ci *table. return err } - oldOne, err := q.Where(m.ID.Eq(ci.ID), m.BizID.Eq(ci.Attachment.BizID)).Take() - if err != nil { - return err - } - - ad := dao.auditDao.DecoratorV2(kit, ci.Attachment.BizID).PrepareUpdate(ci, oldOne) - - updateTx := func(tx *gen.Query) error { - q = tx.ConfigItem.WithContext(kit.Ctx) - if _, err = q.Select(m.Name, m.Path, m.FileType, m.FileMode, m.Memo, m.User, m.UserGroup, - m.Privilege, m.Reviser, m.UpdatedAt). - Where(m.ID.Eq(ci.ID), m.BizID.Eq(ci.Attachment.BizID)).Updates(ci); err != nil { - return err - } - - if err = ad.Do(tx); err != nil { - return fmt.Errorf("audit update config item failed, err: %v", err) - } - return nil + ad := dao.auditDao.Decorator(kit, ci.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigFileAbsolutePath, path.Join(ci.Spec.Path, ci.Spec.Name)), + Status: enumor.Success, + AppId: ci.Attachment.AppID, + }).PrepareUpdate(ci) + if err := ad.Do(tx.Query); err != nil { + return fmt.Errorf("audit update config item failed, err: %v", err) } - if err = dao.genQ.Transaction(updateTx); err != nil { - logs.Errorf("update config item: %d failed, err: %v, rid: %v", ci.ID, err, kit.Rid) + q = tx.ConfigItem.WithContext(kit.Ctx) + if _, err := q.Select(m.Name, m.Path, m.FileType, m.FileMode, m.Memo, m.User, m.UserGroup, + m.Privilege, m.Reviser, m.UpdatedAt). + Where(m.ID.Eq(ci.ID), m.BizID.Eq(ci.Attachment.BizID)).Updates(ci); err != nil { return err } @@ -187,7 +181,11 @@ func (dao *configItemDao) RecoverConfigItem(kit *kit.Kit, tx *gen.QueryTx, ci *t return err } - ad := dao.auditDao.DecoratorV2(kit, ci.Attachment.BizID).PrepareCreate(ci) + ad := dao.auditDao.Decorator(kit, ci.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigFileAbsolutePath, path.Join(ci.Spec.Path, ci.Spec.Name)), + Status: enumor.Success, + AppId: ci.Attachment.AppID, + }).PrepareCreate(ci) if err := tx.ConfigItem.WithContext(kit.Ctx).Create(ci); err != nil { return err @@ -232,7 +230,11 @@ func (dao *configItemDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, ci *table. } ci.ID = id - ad := dao.auditDao.DecoratorV2(kit, ci.Attachment.BizID).PrepareCreate(ci) + ad := dao.auditDao.Decorator(kit, ci.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigFileAbsolutePath, path.Join(ci.Spec.Path, ci.Spec.Name)), + Status: enumor.Success, + AppId: ci.Attachment.AppID, + }).PrepareCreate(ci) if err := tx.ConfigItem.WithContext(kit.Ctx).Create(ci); err != nil { return 0, err @@ -267,6 +269,23 @@ func (dao *configItemDao) BatchCreateWithTx(kit *kit.Kit, tx *gen.QueryTx, if err := tx.ConfigItem.WithContext(kit.Ctx).CreateInBatches(configItems, 500); err != nil { return err } + + // 截取前三个对象 + var paths []string + for i := 0; i < len(configItems) && i < 3; i++ { + paths = append(paths, path.Join(configItems[i].Spec.Path, configItems[i].Spec.Name)) + } + ad := dao.auditDao.Decorator(kit, configItems[0].Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.OperateObject+constant.ResSeparator+constant.ConfigItemName, + len(configItems), strings.Join(paths, constant.NameSeparator)), + Status: enumor.Success, + AppId: configItems[0].Attachment.AppID, + }).PrepareCreate(configItems[0]) + err = ad.Do(tx.Query) + if err != nil { + return err + } + return nil } @@ -298,27 +317,26 @@ func (dao *configItemDao) Update(kit *kit.Kit, ci *table.ConfigItem) error { return err } - oldOne, err := q.Where(m.ID.Eq(ci.ID), m.BizID.Eq(ci.Attachment.BizID)).Take() - if err != nil { - return err - } - - ad := dao.auditDao.DecoratorV2(kit, ci.Attachment.BizID).PrepareUpdate(ci, oldOne) + ad := dao.auditDao.Decorator(kit, ci.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigFileAbsolutePath, path.Join(ci.Spec.Path, ci.Spec.Name)), + Status: enumor.Success, + AppId: ci.Attachment.AppID, + }).PrepareUpdate(ci) updateTx := func(tx *gen.Query) error { q = tx.ConfigItem.WithContext(kit.Ctx) - if _, err = q.Omit(m.ID, m.BizID, m.AppID). + if _, err := q.Omit(m.ID, m.BizID, m.AppID). Where(m.ID.Eq(ci.ID), m.BizID.Eq(ci.Attachment.BizID)).Updates(ci); err != nil { return err } - if err = ad.Do(tx); err != nil { + if err := ad.Do(tx); err != nil { return fmt.Errorf("audit update config item failed, err: %v", err) } return nil } - if err = dao.genQ.Transaction(updateTx); err != nil { + if err := dao.genQ.Transaction(updateTx); err != nil { logs.Errorf("update config item: %d failed, err: %v, rid: %v", ci.ID, err, kit.Rid) return err } @@ -337,6 +355,22 @@ func (dao *configItemDao) BatchUpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, confi if err := tx.ConfigItem.WithContext(kit.Ctx).Save(configItems...); err != nil { return err } + + // 截取前三个对象 + var paths []string + for i := 0; i < len(configItems) && i < 3; i++ { + paths = append(paths, path.Join(configItems[i].Spec.Path, configItems[i].Spec.Name)) + } + ad := dao.auditDao.Decorator(kit, configItems[0].Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.OperateObject+constant.ResSeparator+constant.ConfigItemName, + len(configItems), strings.Join(paths, constant.NameSeparator)), + Status: enumor.Success, + AppId: configItems[0].Attachment.AppID, + }).PrepareUpdate(configItems[0]) + err := ad.Do(tx.Query) + if err != nil { + return err + } return nil } @@ -410,22 +444,25 @@ func (dao *configItemDao) Delete(kit *kit.Kit, ci *table.ConfigItem) error { if err != nil { return err } - - ad := dao.auditDao.DecoratorV2(kit, ci.Attachment.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, ci.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigFileAbsolutePath, path.Join(oldOne.Spec.Path, oldOne.Spec.Name)), + Status: enumor.Success, + AppId: ci.Attachment.AppID, + }).PrepareDelete(ci) // delete config item with transaction. deleteTx := func(tx *gen.Query) error { q = tx.ConfigItem.WithContext(kit.Ctx) - if _, err = q.Where(m.ID.Eq(ci.ID), m.BizID.Eq(ci.Attachment.BizID)).Delete(); err != nil { + if _, err := q.Where(m.ID.Eq(ci.ID), m.BizID.Eq(ci.Attachment.BizID)).Delete(); err != nil { return err } - if err = ad.Do(tx); err != nil { + if err := ad.Do(tx); err != nil { return err } return nil } - if err = dao.genQ.Transaction(deleteTx); err != nil { + if err := dao.genQ.Transaction(deleteTx); err != nil { logs.Errorf("delete config item: %d failed, err: %v, rid: %v", ci.ID, err, kit.Rid) return err } @@ -455,7 +492,11 @@ func (dao *configItemDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, ci *table. if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, ci.Attachment.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, ci.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigFileAbsolutePath, path.Join(oldOne.Spec.Path, oldOne.Spec.Name)), + Status: enumor.Success, + AppId: ci.Attachment.AppID, + }).PrepareDelete(ci) _, err = q.Where(m.ID.Eq(ci.ID), m.BizID.Eq(ci.Attachment.BizID)).Delete() if err != nil { diff --git a/internal/dal/dao/content.go b/internal/dal/dao/content.go index f11555227..f12df1672 100644 --- a/internal/dal/dao/content.go +++ b/internal/dal/dao/content.go @@ -83,18 +83,12 @@ func (dao *contentDao) Create(kit *kit.Kit, content *table.Content) (uint32, err content.ID = id - ad := dao.auditDao.DecoratorV2(kit, content.Attachment.BizID).PrepareCreate(content) - createTx := func(tx *gen.Query) error { q := tx.Content.WithContext(kit.Ctx) if err = q.Create(content); err != nil { return err } - if err = ad.Do(tx); err != nil { - return err - } - return nil } if err = dao.genQ.Transaction(createTx); err != nil { @@ -127,10 +121,6 @@ func (dao *contentDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, content *tabl return 0, err } - ad := dao.auditDao.DecoratorV2(kit, content.Attachment.BizID).PrepareCreate(content) - if err := ad.Do(tx.Query); err != nil { - return 0, fmt.Errorf("audit create content failed, err: %v", err) - } return id, nil } diff --git a/internal/dal/dao/credential.go b/internal/dal/dao/credential.go index 64a57f347..b9a8692f4 100644 --- a/internal/dal/dao/credential.go +++ b/internal/dal/dao/credential.go @@ -18,9 +18,11 @@ import ( rawgen "gorm.io/gen" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/dal/utils" "github.com/TencentBlueKing/bk-bscp/pkg/cc" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" @@ -168,7 +170,11 @@ func (dao *credentialDao) Create(kit *kit.Kit, g *table.Credential) (uint32, err } g.ID = id - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.CredentialName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareCreate(g) // 多个使用事务处理 createTx := func(tx *gen.Query) error { @@ -263,7 +269,11 @@ func (dao *credentialDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, bizID, id if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, bizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, bizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.CredentialName, oldOne.Spec.Name), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + }).PrepareDelete(oldOne) if _, e := q.Where(m.BizID.Eq(bizID), m.ID.Eq(id)).Delete(); e != nil { return e @@ -328,7 +338,16 @@ func (dao *credentialDao) Update(kit *kit.Kit, g *table.Credential) error { Revision: &table.CreatedRevision{Creator: kit.User}, } eDecorator := dao.event.Eventf(kit) - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + resInstance := fmt.Sprintf(constant.CredentialEnableName, g.Spec.Name) + // 禁用秘钥 + if !g.Spec.Enable { + resInstance = fmt.Sprintf(constant.CredentialUnableName, g.Spec.Name) + } + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareUpdate(g) // 多个使用事务处理 updateTx := func(tx *gen.Query) error { diff --git a/internal/dal/dao/credential_scope.go b/internal/dal/dao/credential_scope.go index 3192989d3..29d981c13 100644 --- a/internal/dal/dao/credential_scope.go +++ b/internal/dal/dao/credential_scope.go @@ -75,12 +75,6 @@ func (dao *credentialScopeDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *ta if err := q.Create(g); err != nil { return 0, err } - - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) - if err := ad.Do(tx.Query); err != nil { - return 0, err - } - return g.ID, nil } @@ -119,20 +113,10 @@ func (dao *credentialScopeDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, bizID // 删除操作, 获取当前记录做审计 m := tx.CredentialScope q := tx.CredentialScope.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(id), m.BizID.Eq(bizID)).Take() - if err != nil { - return err - } - if _, err := q.Where(m.BizID.Eq(bizID), m.ID.Eq(id)).Delete(); err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, bizID).PrepareDelete(oldOne) - if err := ad.Do(tx.Query); err != nil { - return err - } - return nil } @@ -144,22 +128,11 @@ func (dao *credentialScopeDao) UpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *ta m := tx.CredentialScope - // 更新操作, 获取当前记录做审计 - oldOne, err := tx.CredentialScope.WithContext(kit.Ctx).Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() - if err != nil { - return err - } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) - if _, err := tx.CredentialScope.WithContext(kit.Ctx).Where(m.BizID.Eq(g.Attachment.BizID), m.ID.Eq(g.ID)). Omit(m.BizID, m.ID).Updates(g); err != nil { return err } - if err := ad.Do(tx.Query); err != nil { - return err - } - return nil } diff --git a/internal/dal/dao/group.go b/internal/dal/dao/group.go index 8cdff69b1..663c2343c 100644 --- a/internal/dal/dao/group.go +++ b/internal/dal/dao/group.go @@ -15,8 +15,10 @@ package dao import ( "fmt" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/dal/utils" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" @@ -92,7 +94,11 @@ func (dao *groupDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Group) return 0, err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.GroupName, g.Spec.Name), + Status: enumor.Success, + AppId: g.ID, + }).PrepareCreate(g) if err = ad.Do(tx.Query); err != nil { return 0, fmt.Errorf("audit create group failed, err: %v", err) } @@ -113,13 +119,13 @@ func (dao *groupDao) UpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Group) m := tx.Group - oldOne, err := m.WithContext(kit.Ctx).Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() - if err != nil { - return err - } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.GroupName, g.Spec.Name), + Status: enumor.Success, + AppId: g.ID, + }).PrepareUpdate(g) - _, err = m.WithContext(kit.Ctx). + _, err := m.WithContext(kit.Ctx). Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)). Select(m.Name, m.Public, m.Selector, m.UID, m.Reviser). Updates(g) @@ -194,7 +200,10 @@ func (dao *groupDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Group) return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.GroupName, oldOne.Spec.Name), + Status: enumor.Success, + }).PrepareDelete(oldOne) if _, err = m.WithContext(kit.Ctx).Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Delete(); err != nil { return err diff --git a/internal/dal/dao/hook.go b/internal/dal/dao/hook.go index 68b487d93..fab2dc27c 100644 --- a/internal/dal/dao/hook.go +++ b/internal/dal/dao/hook.go @@ -14,12 +14,15 @@ package dao import ( "errors" + "fmt" "gorm.io/datatypes" rawgen "gorm.io/gen" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/dal/utils" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" dtypes "github.com/TencentBlueKing/bk-bscp/pkg/dal/types" @@ -75,12 +78,12 @@ func (dao *hookDao) UpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Hook) e // 更新操作, 获取当前记录做审计 m := tx.Hook q := tx.Hook.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() - if err != nil { - return err - } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareUpdate(g) if _, err := q.Where(m.BizID.Eq(g.Attachment.BizID), m.ID.Eq(g.ID)).Updates(g); err != nil { return err @@ -165,7 +168,11 @@ func (dao *hookDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Hook) ( } g.ID = id - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareCreate(g) // 多个使用事务处理 @@ -324,7 +331,11 @@ func (dao *hookDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Hook) e if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, oldOne.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookName, oldOne.Spec.Name), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + }).PrepareDelete(oldOne) _, err = q.Where(m.BizID.Eq(g.Attachment.BizID)).Delete(g) if err != nil { @@ -347,11 +358,12 @@ func (dao *hookDao) Update(kit *kit.Kit, g *table.Hook) error { // 更新操作, 获取当前记录做审计 m := dao.genQ.Hook q := dao.genQ.Hook.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() - if err != nil { - return err - } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareUpdate(g) // 多个使用事务处理 updateTx := func(tx *gen.Query) error { diff --git a/internal/dal/dao/hook_revision.go b/internal/dal/dao/hook_revision.go index 665914568..3c2b08586 100644 --- a/internal/dal/dao/hook_revision.go +++ b/internal/dal/dao/hook_revision.go @@ -16,7 +16,9 @@ import ( "encoding/base64" "fmt" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/types" @@ -76,7 +78,11 @@ func (dao *hookRevisionDao) Create(kit *kit.Kit, hr *table.HookRevision) (uint32 } hr.ID = id - ad := dao.auditDao.DecoratorV2(kit, hr.Attachment.BizID).PrepareCreate(hr) + ad := dao.auditDao.Decorator(kit, hr.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookRevisionName, hr.Spec.Name), + Status: enumor.Success, + Detail: hr.Spec.Memo, + }).PrepareCreate(hr) // 多个使用事务处理 createTx := func(tx *gen.Query) error { @@ -115,16 +121,10 @@ func (dao *hookRevisionDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, hr *tabl } hr.ID = id - ad := dao.auditDao.DecoratorV2(kit, hr.Attachment.BizID).PrepareCreate(hr) - err = tx.HookRevision.WithContext(kit.Ctx).Create(hr) if err != nil { return 0, err } - err = ad.Do(tx.Query) - if err != nil { - return 0, err - } return hr.ID, nil } @@ -319,29 +319,29 @@ func (dao *hookRevisionDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, hr *tabl // 删除操作, 获取当前记录做审计 m := tx.HookRevision q := tx.HookRevision.WithContext(kit.Ctx) + hook := tx.Hook + hookCtx := tx.Hook.WithContext(kit.Ctx) oldOne, err := q.Where(m.ID.Eq(hr.ID), m.BizID.Eq(hr.Attachment.BizID)).Take() if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, hr.Attachment.BizID).PrepareDelete(oldOne) - - // 多个使用事务处理 - deleteTx := func(tx *gen.Query) error { - q = tx.HookRevision.WithContext(kit.Ctx) - if _, e := q.Where(m.BizID.Eq(hr.Attachment.BizID), m.ID.Eq(hr.ID)).Delete(hr); e != nil { - return e - } - - if e := ad.Do(tx); e != nil { - return e - } - return nil + hookRecord, err := hookCtx.Where(hook.ID.Eq(oldOne.Attachment.HookID)).Take() + if err != nil { + return err } - if e := dao.genQ.Transaction(deleteTx); e != nil { + + q = tx.HookRevision.WithContext(kit.Ctx) + if _, e := q.Where(m.BizID.Eq(hr.Attachment.BizID), m.ID.Eq(hr.ID)).Delete(hr); e != nil { return e } - return nil + ad := dao.auditDao.Decorator(kit, hr.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookName+constant.ResSeparator+constant.HookRevisionName, + hookRecord.Spec.Name, oldOne.Spec.Name), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + }).PrepareDelete(oldOne) + return ad.Do(tx.Query) } // DeleteByHookIDWithTx delete revision revision with transaction @@ -398,11 +398,12 @@ func (dao *hookRevisionDao) UpdatePubStateWithTx(kit *kit.Kit, tx *gen.QueryTx, q := tx.HookRevision.WithContext(kit.Ctx) m := tx.HookRevision - oldOne, err := q.Where(m.HookID.Eq(hr.Attachment.HookID), m.BizID.Eq(hr.Attachment.BizID)).Take() + hook := tx.Hook + hookCtx := tx.Hook.WithContext(kit.Ctx) + hookRecord, err := hookCtx.Where(hook.ID.Eq(hr.Attachment.HookID)).Take() if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, hr.Attachment.BizID).PrepareUpdate(hr, oldOne) if _, e := q.Where(m.ID.Eq(hr.ID), m.BizID.Eq(hr.Attachment.BizID)). Omit(m.UpdatedAt). @@ -410,8 +411,17 @@ func (dao *hookRevisionDao) UpdatePubStateWithTx(kit *kit.Kit, tx *gen.QueryTx, return e } - if e := ad.Do(tx.Query); e != nil { - return e + if hr.Spec != nil && hr.Spec.State == table.HookRevisionStatusDeployed { + ad := dao.auditDao.Decorator(kit, hr.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookName+constant.ResSeparator+constant.HookRevisionName, + hookRecord.Spec.Name, hr.Spec.Name), + Status: enumor.Success, + Detail: hr.Spec.Memo, + }).PreparePublish(hr) + + if e := ad.Do(tx.Query); e != nil { + return e + } } return nil @@ -427,11 +437,19 @@ func (dao *hookRevisionDao) Update(kit *kit.Kit, hr *table.HookRevision) error { q := dao.genQ.HookRevision.WithContext(kit.Ctx) m := dao.genQ.HookRevision - oldOne, err := q.Where(m.HookID.Eq(hr.Attachment.HookID), m.BizID.Eq(hr.Attachment.BizID)).Take() + hook := dao.genQ.Hook + hookCtx := dao.genQ.Hook.WithContext(kit.Ctx) + hookRecord, err := hookCtx.Where(hook.ID.Eq(hr.Attachment.HookID)).Take() if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, hr.Attachment.BizID).PrepareUpdate(hr, oldOne) + + ad := dao.auditDao.Decorator(kit, hr.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.HookName+constant.ResSeparator+constant.HookRevisionName, + hookRecord.Spec.Name, hr.Spec.Name), + Status: enumor.Success, + Detail: hr.Spec.Memo, + }).PrepareUpdate(hr) hr.Spec.Content = base64.StdEncoding.EncodeToString([]byte(hr.Spec.Content)) diff --git a/internal/dal/dao/kv.go b/internal/dal/dao/kv.go index d85fe4c12..1ac2a575e 100644 --- a/internal/dal/dao/kv.go +++ b/internal/dal/dao/kv.go @@ -17,8 +17,10 @@ import ( "fmt" "time" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/dal/utils" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/i18n" @@ -204,13 +206,15 @@ func (dao *kvDao) UpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, kv *table.Kv) erro // 编辑操作, 获取当前记录做审计 m := tx.Kv q := tx.Kv.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(kv.ID), m.BizID.Eq(kv.Attachment.BizID), m.AppID.Eq(kv.Attachment.AppID)).Take() - if err != nil { - return err - } - ad := dao.auditDao.DecoratorV2(kit, kv.Attachment.BizID).PrepareUpdate(kv, oldOne) - _, err = q.Where(m.BizID.Eq(kv.Attachment.BizID), m.ID.Eq(kv.ID)).Select(m.Version, m.UpdatedAt, + ad := dao.auditDao.Decorator(kit, kv.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigItemName, kv.Spec.Key), + Status: enumor.Success, + Detail: kv.Spec.Memo, + AppId: kv.Attachment.AppID, + }).PrepareUpdate(kv) + + _, err := q.Where(m.BizID.Eq(kv.Attachment.BizID), m.ID.Eq(kv.ID)).Select(m.Version, m.UpdatedAt, m.Reviser, m.KvState, m.Signature, m.Md5, m.ByteSize, m.CertificateExpirationDate).Updates(kv) if err != nil { return err @@ -235,7 +239,12 @@ func (dao *kvDao) Create(kit *kit.Kit, kv *table.Kv) (uint32, error) { } kv.ID = id - ad := dao.auditDao.DecoratorV2(kit, kv.Attachment.BizID).PrepareCreate(kv) + ad := dao.auditDao.Decorator(kit, kv.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigItemName, kv.Spec.Key), + Status: enumor.Success, + Detail: kv.Spec.Memo, + AppId: kv.Attachment.AppID, + }).PrepareCreate(kv) createTx := func(tx *gen.Query) error { q := tx.Kv.WithContext(kit.Ctx) @@ -265,11 +274,13 @@ func (dao *kvDao) Update(kit *kit.Kit, kv *table.Kv) error { // 更新操作, 获取当前记录做审计 m := dao.genQ.Kv q := dao.genQ.Kv.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(kv.ID), m.BizID.Eq(kv.Attachment.BizID)).Take() - if err != nil { - return err - } - ad := dao.auditDao.DecoratorV2(kit, kv.Attachment.BizID).PrepareUpdate(kv, oldOne) + + ad := dao.auditDao.Decorator(kit, kv.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigItemName, kv.Spec.Key), + Status: enumor.Success, + Detail: kv.Spec.Memo, + AppId: kv.Attachment.AppID, + }).PrepareUpdate(kv) // 多个使用事务处理 updateTx := func(tx *gen.Query) error { @@ -368,7 +379,12 @@ func (dao *kvDao) Delete(kit *kit.Kit, kv *table.Kv) error { if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, kv.Attachment.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, kv.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigItemName, oldOne.Spec.Key), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + AppId: oldOne.Attachment.AppID, + }).PrepareDelete(oldOne) // 多个使用事务处理 deleteTx := func(tx *gen.Query) error { @@ -404,7 +420,12 @@ func (dao *kvDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, kv *table.Kv) erro if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, kv.Attachment.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, kv.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigItemName, oldOne.Spec.Key), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + AppId: oldOne.Attachment.AppID, + }).PrepareDelete(oldOne) _, err = q.Where(m.BizID.Eq(kv.Attachment.BizID), m.ID.Eq(kv.ID)).Delete(kv) if err != nil { @@ -443,7 +464,12 @@ func (dao *kvDao) DeleteByStateWithTx(kit *kit.Kit, tx *gen.QueryTx, kv *table.K if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, kv.Attachment.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, kv.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigItemName, oldOne.Spec.Key), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + AppId: oldOne.Attachment.AppID, + }).PrepareDelete(oldOne) _, err = q.Where(m.BizID.Eq(kv.Attachment.BizID), m.AppID.Eq(kv.Attachment.AppID), m.KvState.Eq(string(kv.KvState))).Delete(kv) diff --git a/internal/dal/dao/publish.go b/internal/dal/dao/publish.go index 81dac8d73..6d747dfc6 100644 --- a/internal/dal/dao/publish.go +++ b/internal/dal/dao/publish.go @@ -33,9 +33,6 @@ type Publish interface { // Publish publish an app's release with its strategy. // once an app's strategy along with its release id is published, // all its released config items are effected immediately. - Publish(kit *kit.Kit, opt *types.PublishOption) (id uint32, err error) - - PublishWithTx(kit *kit.Kit, tx *gen.QueryTx, opt *types.PublishOption) (id uint32, err error) SubmitWithTx(kit *kit.Kit, tx *gen.QueryTx, opt *types.PublishOption) (id uint32, err error) @@ -51,56 +48,6 @@ type pubDao struct { event Event } -// Publish publish an app's release with its strategy. -// once an app's strategy along with its release id is published, -// all its released config items are effected immediately. -// return the published strategy history record id. -func (dao *pubDao) Publish(kit *kit.Kit, opt *types.PublishOption) (uint32, error) { - if opt == nil { - return 0, errors.New("publish strategy option is nil") - } - - if err := opt.Validate(); err != nil { - return 0, err - } - - // 手动事务处理 - tx := dao.genQ.Begin() - if err := dao.validatePublishGroups(kit, tx, opt); err != nil { - if e := tx.Rollback(); e != nil { - logs.Errorf("rollback publish transaction failed, err: %v, rid: %s", e, kit.Rid) - } - return 0, err - } - stgID, err := func() (uint32, error) { - groups := make([]*table.Group, 0, len(opt.Groups)) - var err error - if len(opt.Groups) > 0 { - m := tx.Group - q := tx.Group.WithContext(kit.Ctx) - groups, err = q.Where(m.ID.In(opt.Groups...), m.BizID.Eq(opt.BizID)).Find() - if err != nil { - logs.Errorf("get to be published groups(%s) failed, err: %v, rid: %s", - tools.JoinUint32(opt.Groups, ","), err, kit.Rid) - return 0, err - } - } - return dao.publish(kit, tx, opt, groups) - }() - if err != nil { - if e := tx.Rollback(); e != nil { - logs.Errorf("rollback publish transaction failed, err: %v, rid: %s", e, kit.Rid) - } - return 0, err - } - if err = tx.Commit(); err != nil { - logs.Errorf("commit publish transaction failed, err: %v, rid: %s", err, kit.Rid) - return 0, err - } - - return stgID, nil -} - func (dao *pubDao) validatePublishGroups(kt *kit.Kit, tx *gen.QueryTx, opt *types.PublishOption) error { for _, groupID := range opt.Groups { // frontend would set groupID 0 as default. @@ -190,95 +137,6 @@ func genStrategy(kit *kit.Kit, opt *types.PublishOption, stgID uint32, groups [] } } -// PublishWithTx publish with transaction -func (dao *pubDao) PublishWithTx(kit *kit.Kit, tx *gen.QueryTx, opt *types.PublishOption) (uint32, error) { - if opt == nil { - return 0, errors.New("publish strategy option is nil") - } - - if err := opt.Validate(); err != nil { - return 0, err - } - - if err := dao.validatePublishGroups(kit, tx, opt); err != nil { - if e := tx.Rollback(); e != nil { - logs.Errorf("rollback publish transaction failed, err: %v, rid: %s", e, kit.Rid) - } - return 0, err - } - - groups := make([]*table.Group, 0, len(opt.Groups)) - var err error - if len(opt.Groups) > 0 { - m := tx.Group - q := tx.Group.WithContext(kit.Ctx) - groups, err = q.Where(m.ID.In(opt.Groups...), m.BizID.Eq(opt.BizID)).Find() - if err != nil { - logs.Errorf("get to be published groups(%s) failed, err: %v, rid: %s", - tools.JoinUint32(opt.Groups, ","), err, kit.Rid) - return 0, err - } - } - return dao.publish(kit, tx, opt, groups) -} - -func (dao *pubDao) publish(kit *kit.Kit, tx *gen.QueryTx, opt *types.PublishOption, groups []*table.Group) ( - uint32, error) { - eDecorator := dao.event.Eventf(kit) - // create strategy to publish it later - stgID, err := dao.idGen.One(kit, table.StrategyTable) - if err != nil { - logs.Errorf("generate strategy id failed, err: %v, rid: %s", err, kit.Rid) - return 0, err - } - stg := genStrategy(kit, opt, stgID, groups) - - sq := tx.Strategy.WithContext(kit.Ctx) - if err := sq.Create(stg); err != nil { - return 0, err - } - - // audit this to create strategy details - ad := dao.auditDao.DecoratorV2(kit, opt.BizID).PrepareCreate(stg) - if err := ad.Do(tx.Query); err != nil { - return 0, err - } - // audit this to publish details - ad = dao.auditDao.DecoratorV2(kit, opt.BizID).PreparePublish(stg) - if err := ad.Do(tx.Query); err != nil { - return 0, err - } - - // add release publish num - if err := dao.updateReleasePublishInfo(kit, tx.Query, opt); err != nil { - logs.Errorf("increate release publish num failed, err: %v, rid: %s", err, kit.Rid) - return 0, err - } - - if err := dao.upsertReleasedGroups(kit, tx.Query, opt, stg); err != nil { - logs.Errorf("upsert group current releases failed, err: %v, rid: %s", err, kit.Rid) - return 0, err - } - - // fire the event with txn to ensure the if save the event failed then the business logic is failed anyway. - one := types.Event{ - Spec: &table.EventSpec{ - Resource: table.Publish, - // use the published strategy history id, which represent a real publish operation. - ResourceID: opt.ReleaseID, - OpType: table.InsertOp, - }, - Attachment: &table.EventAttachment{BizID: opt.BizID, AppID: opt.AppID}, - Revision: &table.CreatedRevision{Creator: kit.User}, - } - if err := eDecorator.FireWithTx(tx, one); err != nil { - logs.Errorf("fire publish strategy event failed, err: %v, rid: %s", err, kit.Rid) - return 0, errors.New("fire event failed, " + err.Error()) - } - - return stgID, nil -} - // updateReleasePublishInfo update release publish info, include publish num and fully released status. func (dao *pubDao) updateReleasePublishInfo(kit *kit.Kit, tx *gen.Query, opt *types.PublishOption) error { m := tx.Release diff --git a/internal/dal/dao/release.go b/internal/dal/dao/release.go index 962eacbbc..971e96d16 100644 --- a/internal/dal/dao/release.go +++ b/internal/dal/dao/release.go @@ -18,8 +18,10 @@ import ( "github.com/pkg/errors" "gorm.io/gorm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/dal/sharding" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" @@ -89,7 +91,12 @@ func (dao *releaseDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Rele return 0, err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ConfigReleaseName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + AppId: g.Attachment.AppID, + }).PrepareCreate(g) if err := ad.Do(tx.Query); err != nil { return 0, err } @@ -181,17 +188,59 @@ func (dao *releaseDao) validateAttachmentResExist(kit *kit.Kit, am *table.Releas func (dao *releaseDao) UpdateDeprecated(kit *kit.Kit, bizID, appID, releaseID uint32, deprecated bool) error { m := dao.genQ.Release - _, err := m.WithContext(kit.Ctx). - Where(m.ID.Eq(releaseID), m.AppID.Eq(appID), m.BizID.Eq(bizID)). - Update(m.Deprecated, deprecated) + release, err := m.WithContext(kit.Ctx).Where(m.ID.Eq(releaseID), m.AppID.Eq(appID), m.BizID.Eq(bizID)).Take() + if err != nil { + return err + } + + resInstance := fmt.Sprintf(constant.RestoreConfigReleaseName, release.Spec.Name) + if deprecated { + resInstance = fmt.Sprintf(constant.ObsoleteConfigReleaseName, release.Spec.Name) + } + + ad := dao.auditDao.Decorator(kit, bizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + Detail: release.Spec.Memo, + AppId: appID, + }).PrepareUpdate(release) + updateTx := func(tx *gen.Query) error { + if _, err = tx.Release.WithContext(kit.Ctx). + Where(m.ID.Eq(releaseID), m.AppID.Eq(appID), m.BizID.Eq(bizID)). + Update(m.Deprecated, deprecated); err != nil { + return err + } + + return ad.Do(tx) + } + if err = dao.genQ.Transaction(updateTx); err != nil { + return err + } + return err } // DeleteWithTx delete release with tx. func (dao *releaseDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, bizID, appID, releaseID uint32) error { m := tx.Release - _, err := m.WithContext(kit.Ctx).Where(m.ID.Eq(releaseID), m.AppID.Eq(appID), m.BizID.Eq(bizID)).Delete() - return err + + release, err := m.WithContext(kit.Ctx).Where(m.ID.Eq(releaseID), m.AppID.Eq(appID), m.BizID.Eq(bizID)).Take() + if err != nil { + return err + } + + _, err = m.WithContext(kit.Ctx).Where(m.ID.Eq(releaseID), m.AppID.Eq(appID), m.BizID.Eq(bizID)).Delete() + if err != nil { + return err + } + + ad := dao.auditDao.Decorator(kit, bizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.DeleteConfigReleaseName, release.Spec.Name), + Status: enumor.Success, + Detail: release.Spec.Memo, + AppId: appID, + }).PrepareDelete(release) + return ad.Do(tx.Query) } // ListReleaseStrategies list release strategie the latest three pieces of data published diff --git a/internal/dal/dao/release_ci.go b/internal/dal/dao/release_ci.go index d4f2ff72f..093679b7a 100644 --- a/internal/dal/dao/release_ci.go +++ b/internal/dal/dao/release_ci.go @@ -90,11 +90,6 @@ func (dao *releasedCIDao) BulkCreateWithTx(kit *kit.Kit, tx *gen.QueryTx, items return fmt.Errorf("create released config items in batch failed, err: %v", err) } - ad := dao.auditDao.DecoratorV2(kit, items[0].Attachment.BizID).PrepareCreate(table.RciList(items)) - if err := ad.Do(tx.Query); err != nil { - return err - } - return nil } diff --git a/internal/dal/dao/released_app_template.go b/internal/dal/dao/released_app_template.go index f1e787599..3f90fea89 100644 --- a/internal/dal/dao/released_app_template.go +++ b/internal/dal/dao/released_app_template.go @@ -85,11 +85,6 @@ func (dao *releasedAppTemplateDao) BulkCreateWithTx( return fmt.Errorf("create released template config items in batch failed, err: %v", err) } - ad := dao.auditDao.DecoratorV2(kit, items[0].Attachment.BizID).PrepareCreate(table.RatiList(items)) - if err := ad.Do(tx.Query); err != nil { - return err - } - return nil } diff --git a/internal/dal/dao/released_app_template_variable.go b/internal/dal/dao/released_app_template_variable.go index aafc97ee1..4a5bec99c 100644 --- a/internal/dal/dao/released_app_template_variable.go +++ b/internal/dal/dao/released_app_template_variable.go @@ -60,11 +60,6 @@ func (dao *releasedAppTemplateVariableDao) CreateWithTx( return 0, err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) - if err := ad.Do(tx.Query); err != nil { - return 0, err - } - return g.ID, nil } diff --git a/internal/dal/dao/released_hooks.go b/internal/dal/dao/released_hooks.go index b29ec4ebc..15b0129fd 100644 --- a/internal/dal/dao/released_hooks.go +++ b/internal/dal/dao/released_hooks.go @@ -15,10 +15,13 @@ package dao import ( "encoding/base64" "errors" + "fmt" "gorm.io/gorm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" @@ -146,6 +149,13 @@ func (dao *releasedHookDao) UpsertWithTx(kit *kit.Kit, tx *gen.QueryTx, rh *tabl if _, e := m.WithContext(kit.Ctx).Updates(rh); e != nil { return e } + + ad := dao.auditDao.Decorator(kit, rh.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ReplaceHookName, rh.HookType, rh.HookName), + Status: enumor.Success, + AppId: rh.AppID, + }).PrepareUpdate(&table.ConfigItem{ID: rh.ID}) + return ad.Do(tx.Query) } else if errors.Is(err, gorm.ErrRecordNotFound) { // if old not exists, create it. id, e := dao.idGen.One(kit, table.Name(rh.TableName())) @@ -153,8 +163,18 @@ func (dao *releasedHookDao) UpsertWithTx(kit *kit.Kit, tx *gen.QueryTx, rh *tabl return e } rh.ID = id - return m.WithContext(kit.Ctx).Create(rh) + if err = m.WithContext(kit.Ctx).Create(rh); err != nil { + return err + } + + ad := dao.auditDao.Decorator(kit, rh.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ReferenceHookName, rh.HookType, rh.HookName), + Status: enumor.Success, + AppId: rh.AppID, + }).PrepareCreate(&table.ConfigItem{ID: rh.ID}) + return ad.Do(tx.Query) } + return err } @@ -203,8 +223,19 @@ func (dao *releasedHookDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, rh *tabl rh.ID = id - if err := tx.ReleasedHook.WithContext(kit.Ctx).Create(rh); err != nil { + if err = tx.ReleasedHook.WithContext(kit.Ctx).Create(rh); err != nil { + return 0, err + } + + ad := dao.auditDao.Decorator(kit, rh.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.ReferenceHookName, rh.HookType, rh.HookName), + Status: enumor.Success, + AppId: rh.AppID, + }).PrepareCreate(&table.ConfigItem{ID: rh.ID}) + + if err = ad.Do(tx.Query); err != nil { return 0, err + } return id, nil @@ -259,9 +290,24 @@ func (dao *releasedHookDao) DeleteByUniqueKeyWithTx(kit *kit.Kit, tx *gen.QueryT return err } m := tx.ReleasedHook - _, err := m.WithContext(kit.Ctx).Where(m.BizID.Eq(rh.BizID), m.AppID.Eq(rh.AppID), + oldOne, err := m.WithContext(kit.Ctx).Where(m.BizID.Eq(rh.BizID), m.AppID.Eq(rh.AppID), + m.ReleaseID.Eq(rh.ReleaseID), m.HookType.Eq(rh.HookType.String())).Take() + if err != nil { + return err + } + + _, err = m.WithContext(kit.Ctx).Where(m.BizID.Eq(rh.BizID), m.AppID.Eq(rh.AppID), m.ReleaseID.Eq(rh.ReleaseID), m.HookType.Eq(rh.HookType.String())).Delete() - return err + if err != nil { + return err + } + + ad := dao.auditDao.Decorator(kit, rh.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.CancelHookName, oldOne.HookType, oldOne.HookName), + Status: enumor.Success, + AppId: rh.AppID, + }).PrepareDelete(&table.ConfigItem{ID: rh.ID}) + return ad.Do(tx.Query) } // DeleteByHookIDAndReleaseIDWithTx deletes the released hook by hook id and release id with transaction. diff --git a/internal/dal/dao/released_kv.go b/internal/dal/dao/released_kv.go index b097eb1a9..e672ebc85 100644 --- a/internal/dal/dao/released_kv.go +++ b/internal/dal/dao/released_kv.go @@ -81,11 +81,6 @@ func (dao *releasedKvDao) BulkCreateWithTx(kit *kit.Kit, tx *gen.QueryTx, kvs [] return fmt.Errorf("create released kv in batch failed, err: %v", err) } - ad := dao.auditDao.DecoratorV2(kit, kvs[0].Attachment.BizID).PrepareCreate(table.RkvList(kvs)) - if err := ad.Do(tx.Query); err != nil { - return err - } - return nil } diff --git a/internal/dal/dao/template.go b/internal/dal/dao/template.go index 7bd5720fb..05cd79951 100644 --- a/internal/dal/dao/template.go +++ b/internal/dal/dao/template.go @@ -15,14 +15,18 @@ package dao import ( "errors" "fmt" + "path" + "strings" rawgen "gorm.io/gen" "gorm.io/gen/field" "gorm.io/gorm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/dal/utils" "github.com/TencentBlueKing/bk-bscp/internal/search" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/types" @@ -82,12 +86,20 @@ func (dao *templateDao) UpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Tem // 更新操作, 获取当前记录做审计 m := tx.Template q := tx.Template.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() + + ts := tx.TemplateSpace + tsCtx := tx.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateAbsolutePath, + tsRecord.Spec.Name, path.Join(g.Spec.Path, g.Spec.Name)), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareUpdate(g) if err := ad.Do(tx.Query); err != nil { return err } @@ -129,6 +141,28 @@ func (dao *templateDao) BatchUpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, templat if err := tx.Template.WithContext(kit.Ctx).Save(templates...); err != nil { return err } + // 现在的操作是对同一个模板空间进行批量新增 + templateSpace, err := tx.TemplateSpace.WithContext(kit.Ctx). + Where(tx.TemplateSpace.ID.Eq(templates[0].Attachment.TemplateSpaceID)).Take() + if err != nil { + return err + } + + // 截取前三个对象 + var paths []string + for i := 0; i < len(templates) && i < 3; i++ { + paths = append(paths, path.Join(templates[i].Spec.Path, templates[i].Spec.Name)) + } + ad := dao.auditDao.Decorator(kit, templates[0].Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.OperateObject+ + constant.ResSeparator+constant.TemplateAbsolutePath, templateSpace.Spec.Name, len(templates), + strings.Join(paths, constant.NameSeparator)), + Status: enumor.Success, + }).PrepareUpdate(templates[0]) + err = ad.Do(tx.Query) + if err != nil { + return err + } return nil } @@ -152,6 +186,28 @@ func (dao *templateDao) BatchCreateWithTx(kit *kit.Kit, tx *gen.QueryTx, templat if err != nil { return err } + // 现在的操作是对同一个模板空间进行批量新增 + templateSpace, err := tx.TemplateSpace.WithContext(kit.Ctx). + Where(tx.TemplateSpace.ID.Eq(templates[0].Attachment.TemplateSpaceID)).Take() + if err != nil { + return err + } + // 截取前三个对象 + var paths []string + for i := 0; i < len(templates) && i < 3; i++ { + paths = append(paths, path.Join(templates[i].Spec.Path, templates[i].Spec.Name)) + } + ad := dao.auditDao.Decorator(kit, templates[0].Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.OperateObject+ + constant.ResSeparator+constant.TemplateAbsolutePath, templateSpace.Spec.Name, len(templates), + strings.Join(paths, constant.NameSeparator)), + Status: enumor.Success, + }).PrepareCreate(templates[0]) + err = ad.Do(tx.Query) + if err != nil { + return err + } + return nil } @@ -172,7 +228,11 @@ func (dao *templateDao) Create(kit *kit.Kit, g *table.Template) (uint32, error) } g.ID = id - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateAbsolutePath, path.Join(g.Spec.Path, g.Spec.Name)), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareCreate(g) // 多个使用事务处理 createTx := func(tx *gen.Query) error { @@ -208,11 +268,23 @@ func (dao *templateDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Tem g.ID = id q := tx.Template.WithContext(kit.Ctx) - if err := q.Create(g); err != nil { + if err = q.Create(g); err != nil { + return 0, err + } + + ts := tx.TemplateSpace + tsCtx := tx.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { return 0, err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateAbsolutePath, + tsRecord.Spec.Name, path.Join(g.Spec.Path, g.Spec.Name)), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareCreate(g) if err := ad.Do(tx.Query); err != nil { return 0, err } @@ -229,11 +301,20 @@ func (dao *templateDao) Update(kit *kit.Kit, g *table.Template) error { // 更新操作, 获取当前记录做审计 m := dao.genQ.Template q := dao.genQ.Template.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() + + ts := dao.genQ.TemplateSpace + tsCtx := dao.genQ.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateAbsolutePath, + tsRecord.Spec.Name, path.Join(g.Spec.Path, g.Spec.Name)), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareUpdate(g) // 多个使用事务处理 updateTx := func(tx *gen.Query) error { @@ -314,7 +395,19 @@ func (dao *templateDao) Delete(kit *kit.Kit, g *table.Template) error { if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + ts := dao.genQ.TemplateSpace + tsCtx := dao.genQ.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { + return err + } + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateAbsolutePath, + tsRecord.Spec.Name, path.Join(oldOne.Spec.Path, oldOne.Spec.Name)), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + }).PrepareDelete(oldOne) // 多个使用事务处理 deleteTx := func(tx *gen.Query) error { @@ -348,7 +441,19 @@ func (dao *templateDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table.Tem if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + ts := tx.TemplateSpace + tsCtx := tx.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { + return err + } + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateAbsolutePath, + tsRecord.Spec.Name, path.Join(oldOne.Spec.Path, oldOne.Spec.Name)), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + }).PrepareDelete(oldOne) if err := ad.Do(tx.Query); err != nil { return err } diff --git a/internal/dal/dao/template_revision.go b/internal/dal/dao/template_revision.go index c242039a5..435df6150 100644 --- a/internal/dal/dao/template_revision.go +++ b/internal/dal/dao/template_revision.go @@ -15,12 +15,15 @@ package dao import ( "errors" "fmt" + "path" rawgen "gorm.io/gen" "gorm.io/gorm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/search" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/types" @@ -132,7 +135,20 @@ func (dao *templateRevisionDao) Create(kit *kit.Kit, g *table.TemplateRevision) } g.ID = id - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ts := dao.genQ.TemplateSpace + tsCtx := dao.genQ.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { + return 0, err + } + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateRevision+ + constant.ResSeparator+constant.TemplateAbsolutePath, tsRecord.Spec.Name, g.Spec.RevisionName, + path.Join(g.Spec.Path, g.Spec.Name)), + Status: enumor.Success, + Detail: g.Spec.RevisionMemo, + }).PrepareCreate(g) // 多个使用事务处理 createTx := func(tx *gen.Query) error { @@ -168,11 +184,24 @@ func (dao *templateRevisionDao) CreateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *t g.ID = id q := tx.TemplateRevision.WithContext(kit.Ctx) - if err := q.Create(g); err != nil { + if err = q.Create(g); err != nil { + return 0, err + } + + ts := tx.TemplateSpace + tsCtx := tx.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { return 0, err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateRevision+ + constant.ResSeparator+constant.TemplateAbsolutePath, tsRecord.Spec.Name, g.Spec.RevisionName, + path.Join(g.Spec.Path, g.Spec.Name)), + Status: enumor.Success, + Detail: g.Spec.RevisionMemo, + }).PrepareCreate(g) if err := ad.Do(tx.Query); err != nil { return 0, err } @@ -228,7 +257,20 @@ func (dao *templateRevisionDao) Delete(kit *kit.Kit, g *table.TemplateRevision) if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + ts := dao.genQ.TemplateSpace + tsCtx := dao.genQ.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { + return err + } + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateRevision+ + constant.ResSeparator+constant.TemplateAbsolutePath, tsRecord.Spec.Name, oldOne.Spec.RevisionName, + path.Join(oldOne.Spec.Path, oldOne.Spec.Name)), + Status: enumor.Success, + Detail: oldOne.Spec.RevisionMemo, + }).PrepareDelete(oldOne) // 多个使用事务处理 deleteTx := func(tx *gen.Query) error { diff --git a/internal/dal/dao/template_set.go b/internal/dal/dao/template_set.go index 545133615..35f2dfd42 100644 --- a/internal/dal/dao/template_set.go +++ b/internal/dal/dao/template_set.go @@ -15,14 +15,18 @@ package dao import ( "errors" "fmt" + "path" + "strings" "gorm.io/datatypes" rawgen "gorm.io/gen" "gorm.io/gorm" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/search" "github.com/TencentBlueKing/bk-bscp/pkg/cc" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" dtypes "github.com/TencentBlueKing/bk-bscp/pkg/dal/types" @@ -108,6 +112,40 @@ func (dao *templateSetDao) BatchAddTmplsToTmplSetsWithTx(kit *kit.Kit, tx *gen.Q return nil } + // 单个添加模板套餐 + for i := range templateSet { + templates, err := tx.Template.WithContext(kit.Ctx).Where(tx.Template.ID.In(templateSet[i].Spec.TemplateIDs...)). + Find() + if err != nil { + return err + } + + templateSpace, err := tx.TemplateSpace.WithContext(kit.Ctx). + Where(tx.TemplateSpace.ID.Eq(templateSet[i].Attachment.TemplateSpaceID)).Take() + if err != nil { + return err + } + + var templateNames []string + for _, v := range templates { + templateNames = append(templateNames, path.Join(v.Spec.Path, v.Spec.Name)) + } + + resInstance := fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName+ + constant.ResSeparator+constant.TemplateAbsolutePath, templateSpace.Spec.Name, templateSet[i].Spec.Name, + strings.Join(templateNames, constant.NameSeparator)) + + ad := dao.auditDao.Decorator(kit, templateSet[i].Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + }).PrepareCreate(templateSet[i]) + err = ad.Do(tx.Query) + if err != nil { + return err + } + + } + return tx.TemplateSet.WithContext(kit.Ctx).Save(templateSet...) } @@ -141,7 +179,19 @@ func (dao *templateSetDao) Create(kit *kit.Kit, g *table.TemplateSet) (uint32, e } g.ID = id - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + ts := dao.genQ.TemplateSpace + tsCtx := dao.genQ.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { + return 0, err + } + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + tsRecord.Spec.Name, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareCreate(g) // 多个使用事务处理 createTx := func(tx *gen.Query) error { @@ -177,11 +227,20 @@ func (dao *templateSetDao) Update(kit *kit.Kit, g *table.TemplateSet) error { // 更新操作, 获取当前记录做审计 q := dao.genQ.TemplateSet.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() + + ts := dao.genQ.TemplateSpace + tsCtx := dao.genQ.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + tsRecord.Spec.Name, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareUpdate(g) // 多个使用事务处理 updateTx := func(tx *gen.Query) error { @@ -217,15 +276,60 @@ func (dao *templateSetDao) UpdateWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table. // 更新操作, 获取当前记录做审计 m := tx.TemplateSet q := tx.TemplateSet.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() + + oldOne, err := q.Where(m.ID.Eq(g.ID)).Take() if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) - if err := ad.Do(tx.Query); err != nil { + + deleteTemplate := tools.Difference(oldOne.Spec.TemplateIDs, g.Spec.TemplateIDs) + + ts := tx.TemplateSpace + tsCtx := tx.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { return err } + // 移除套餐的模板文件 + if len(deleteTemplate) > 0 { + templates, err := tx.Template.WithContext(kit.Ctx).Where(tx.Template.ID.In(deleteTemplate...)). + Find() + if err != nil { + return err + } + var templateNames []string + for _, v := range templates { + templateNames = append(templateNames, path.Join(v.Spec.Path, v.Spec.Name)) + } + + resInstance := fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName+ + constant.ResSeparator+constant.TemplateAbsolutePath, tsRecord.Spec.Name, oldOne.Spec.Name, + strings.Join(templateNames, constant.NameSeparator)) + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareDelete(g) + if err := ad.Do(tx.Query); err != nil { + return err + } + } else { + // 仅仅是更新模板套餐 + resInstance := fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + tsRecord.Spec.Name, g.Spec.Name) + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: resInstance, + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareUpdate(g) + if err := ad.Do(tx.Query); err != nil { + return err + } + } + if len(g.Spec.TemplateIDs) == 0 { g.Spec.TemplateIDs = []uint32{} } @@ -287,7 +391,20 @@ func (dao *templateSetDao) Delete(kit *kit.Kit, g *table.TemplateSet) error { if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + + ts := dao.genQ.TemplateSpace + tsCtx := dao.genQ.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { + return err + } + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + tsRecord.Spec.Name, oldOne.Spec.Name), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + }).PrepareDelete(oldOne) // 多个使用事务处理 deleteTx := func(tx *gen.Query) error { @@ -321,7 +438,19 @@ func (dao *templateSetDao) DeleteWithTx(kit *kit.Kit, tx *gen.QueryTx, g *table. if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + ts := tx.TemplateSpace + tsCtx := tx.TemplateSpace.WithContext(kit.Ctx) + tsRecord, err := tsCtx.Where(ts.ID.Eq(g.Attachment.TemplateSpaceID)).Take() + if err != nil { + return err + } + + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + tsRecord.Spec.Name, oldOne.Spec.Name), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + }).PrepareDelete(oldOne) if err := ad.Do(tx.Query); err != nil { return err } diff --git a/internal/dal/dao/template_space.go b/internal/dal/dao/template_space.go index def5c0d07..9be83b4f4 100644 --- a/internal/dal/dao/template_space.go +++ b/internal/dal/dao/template_space.go @@ -17,9 +17,10 @@ import ( rawgen "gorm.io/gen" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/search" - "github.com/TencentBlueKing/bk-bscp/pkg/criteria/constant" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/types" @@ -87,8 +88,17 @@ func (dao *templateSpaceDao) Create(kit *kit.Kit, g *table.TemplateSpace) (uint3 } sg.ID = tmplSetID - tmplSpaceAD := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) - tmplSetAD := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(sg) + tmplSpaceAD := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareCreate(g) + tmplSetAD := dao.auditDao.Decorator(kit, sg.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + g.Spec.Name, sg.Spec.Name), + Status: enumor.Success, + Detail: sg.Spec.Memo, + }).PrepareCreate(sg) // 多个使用事务处理 createTx := func(tx *gen.Query) error { @@ -133,7 +143,11 @@ func (dao *templateSpaceDao) Update(kit *kit.Kit, g *table.TemplateSpace) error if oldOne.Spec.Name == constant.DefaultTmplSpaceCNName { return fmt.Errorf("can't update default template space") } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName, oldOne.Spec.Name), // 命名空间不更改名称 + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareUpdate(g) // 多个使用事务处理 updateTx := func(tx *gen.Query) error { @@ -206,7 +220,11 @@ func (dao *templateSpaceDao) Delete(kit *kit.Kit, g *table.TemplateSpace) error if oldOne.Spec.Name == constant.DefaultTmplSpaceCNName { return fmt.Errorf("can't delete default template space") } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName, oldOne.Spec.Name), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + }).PrepareDelete(oldOne) // 多个使用事务处理 deleteTx := func(tx *gen.Query) error { @@ -290,8 +308,17 @@ func (dao *templateSpaceDao) CreateDefault(kit *kit.Kit, bizID uint32) (uint32, } sg.ID = tmplSetID - tmplSpaceAD := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) - tmplSetAD := dao.auditDao.DecoratorV2(kit, sg.Attachment.BizID).PrepareCreate(sg) + tmplSpaceAD := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareCreate(g) + tmplSetAD := dao.auditDao.Decorator(kit, sg.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.TemplateSpaceName+constant.ResSeparator+constant.TemplateSetName, + g.Spec.Name, sg.Spec.Name), + Status: enumor.Success, + Detail: sg.Spec.Memo, + }).PrepareCreate(sg) // 多个使用事务处理 createTx := func(tx *gen.Query) error { diff --git a/internal/dal/dao/template_variable.go b/internal/dal/dao/template_variable.go index 8fbec19d1..2ddf33219 100644 --- a/internal/dal/dao/template_variable.go +++ b/internal/dal/dao/template_variable.go @@ -13,11 +13,15 @@ package dao import ( + "fmt" + rawgen "gorm.io/gen" + "github.com/TencentBlueKing/bk-bscp/internal/criteria/constant" "github.com/TencentBlueKing/bk-bscp/internal/dal/gen" "github.com/TencentBlueKing/bk-bscp/internal/dal/utils" "github.com/TencentBlueKing/bk-bscp/internal/search" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/dal/table" "github.com/TencentBlueKing/bk-bscp/pkg/kit" @@ -80,7 +84,11 @@ func (dao *templateVariableDao) Create(kit *kit.Kit, g *table.TemplateVariable) } g.ID = tmplSpaceID - tmplSpaceAD := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareCreate(g) + tmplSpaceAD := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.VariableName, g.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareCreate(g) // 多个使用事务处理 createTx := func(tx *gen.Query) error { @@ -109,11 +117,16 @@ func (dao *templateVariableDao) Update(kit *kit.Kit, g *table.TemplateVariable) // 更新操作, 获取当前记录做审计 m := dao.genQ.TemplateVariable q := dao.genQ.TemplateVariable.WithContext(kit.Ctx) - oldOne, err := q.Where(m.ID.Eq(g.ID), m.BizID.Eq(g.Attachment.BizID)).Take() + + oldOne, err := q.Where(m.ID.Eq(g.ID)).Take() if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareUpdate(g, oldOne) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.VariableName, oldOne.Spec.Name), + Status: enumor.Success, + Detail: g.Spec.Memo, + }).PrepareUpdate(g) // 多个使用事务处理 updateTx := func(tx *gen.Query) error { @@ -190,7 +203,11 @@ func (dao *templateVariableDao) Delete(kit *kit.Kit, g *table.TemplateVariable) if err != nil { return err } - ad := dao.auditDao.DecoratorV2(kit, g.Attachment.BizID).PrepareDelete(oldOne) + ad := dao.auditDao.Decorator(kit, g.Attachment.BizID, &table.AuditField{ + ResourceInstance: fmt.Sprintf(constant.VariableName, oldOne.Spec.Name), + Status: enumor.Success, + Detail: oldOne.Spec.Memo, + }).PrepareDelete(oldOne) // 多个使用事务处理 deleteTx := func(tx *gen.Query) error { diff --git a/pkg/criteria/enumor/audit.go b/pkg/criteria/enumor/audit.go index 97ea6cc5c..7dea5bde2 100644 --- a/pkg/criteria/enumor/audit.go +++ b/pkg/criteria/enumor/audit.go @@ -23,125 +23,38 @@ type AuditResourceType string const ( // App 应用模块资源 App AuditResourceType = "app" - // ConfigItem 配置项资源 - ConfigItem AuditResourceType = "config_item" - // Commit 提交资源 - Commit AuditResourceType = "commit" - // Content 配置内容 - Content AuditResourceType = "content" - // Release 版本资源 - Release AuditResourceType = "release" - // StrategySet 策略集资源 - StrategySet AuditResourceType = "strategy_set" - // CRInstance 当前已发布的实例版本 - CRInstance AuditResourceType = "current_released_instance" - // Strategy 策略资源 - Strategy AuditResourceType = "strategy" + // Config 配置资源 + Config AuditResourceType = "config" // Hook hook脚本资源 Hook AuditResourceType = "hook" - // TemplateSpace 模版空间 - TemplateSpace AuditResourceType = "template_space" + // Variable 变量 + Variable AuditResourceType = "variable" + // Release 版本资源 + Release AuditResourceType = "release" // Group 分组资源 Group AuditResourceType = "group" - // Credential 凭据资源 + // Template 模版 + Template AuditResourceType = "template" + // Credential 客户端秘钥 Credential AuditResourceType = "credential" - // CredentialScope 凭据规则资源 - CredentialScope AuditResourceType = "credential_scope" //nolint:gosec - - // 新版操作记录资源类型 - - // ResAppConfig 服务配置 - ResAppConfig AuditResourceType = "app_config" - // ResGroup 分组 - ResGroup AuditResourceType = "group" - // ResHook hook脚本资源 - ResHook AuditResourceType = "hook" - // ResTemplate 配置模版 - ResTemplate AuditResourceType = "template" - // ResVariable 变量 - ResVariable AuditResourceType = "variable" - // ResCredential 客户端秘钥 - ResCredential AuditResourceType = "credential" - // ResInstance 客户端实例 - ResInstance AuditResourceType = "instance" + // Instance 客户端实例 + Instance AuditResourceType = "instance" ) -// AuditResourceTypeEnums resource type map. -var AuditResourceTypeEnums = map[AuditResourceType]bool{ - App: true, - ConfigItem: true, - Commit: true, - Content: true, - Release: true, - StrategySet: true, - Strategy: true, - Hook: true, - TemplateSpace: true, - Group: true, - Credential: true, - CredentialScope: true, -} - -// ActionMap enum all action -var ActionMap = map[AuditAction]AuditResourceType{ - CreateApp: ResAppConfig, - UpdateApp: ResAppConfig, - DeleteApp: ResAppConfig, - PublishReleaseConfig: ResAppConfig, // 上线配置版本 -} - -// Exist judge enum value exist. -func (a AuditResourceType) Exist() bool { - _, exist := AuditResourceTypeEnums[a] - return exist -} - // AuditAction audit action type. type AuditAction string const ( // Create 创建 - Create AuditAction = "Create" + Create AuditAction = "create" // Update 更新 - Update AuditAction = "Update" + Update AuditAction = "update" // Delete 删除 - Delete AuditAction = "Delete" + Delete AuditAction = "delete" // Publish 发布 - Publish AuditAction = "Publish" - // FinishPublish 结束发布 - FinishPublish AuditAction = "FinishPublish" - // Rollback 回滚版本 - Rollback AuditAction = "Rollback" - // Reload Reload配置版本 - Reload AuditAction = "Reload" - - // CreateApp 创建服务 - CreateApp AuditAction = "create_app" - // UpdateApp 更新服务 - UpdateApp AuditAction = "update_app" - // DeleteApp 删除服务 - DeleteApp AuditAction = "delete_app" - // PublishReleaseConfig 上线版本配置 - PublishReleaseConfig AuditAction = "publish_release_config" + Publish AuditAction = "publish" ) -// AuditActionEnums op type map. -var AuditActionEnums = map[AuditAction]bool{ - Create: true, - Update: true, - Delete: true, - Publish: true, - FinishPublish: true, - Rollback: true, - Reload: true, -} - -// Exist judge enum value exist. -func (a AuditAction) Exist() bool { - _, exist := AuditActionEnums[a] - return exist -} - // AuditStatus audit status. type AuditStatus string diff --git a/pkg/dal/table/app.go b/pkg/dal/table/app.go index d86f6cc4f..e33e41ae4 100644 --- a/pkg/dal/table/app.go +++ b/pkg/dal/table/app.go @@ -17,6 +17,7 @@ import ( "fmt" "time" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/validator" "github.com/TencentBlueKing/bk-bscp/pkg/i18n" @@ -53,7 +54,7 @@ func (a *App) ResID() uint32 { // ResType AuditRes interface func (a *App) ResType() string { - return "app" + return string(enumor.App) } // ValidateCreate validate app's info when created. diff --git a/pkg/dal/table/app_template_binding.go b/pkg/dal/table/app_template_binding.go index 9b5a66981..3e958d4ea 100644 --- a/pkg/dal/table/app_template_binding.go +++ b/pkg/dal/table/app_template_binding.go @@ -18,6 +18,7 @@ import ( "errors" "fmt" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/dal/types" ) @@ -46,7 +47,7 @@ func (t *AppTemplateBinding) ResID() uint32 { // ResType AuditRes interface func (t *AppTemplateBinding) ResType() string { - return "app_template_binding" + return string(enumor.Config) } // ValidateCreate validate AppTemplateBinding is valid or not when create it. diff --git a/pkg/dal/table/app_template_variable.go b/pkg/dal/table/app_template_variable.go index b41cb6584..eff1a5c43 100644 --- a/pkg/dal/table/app_template_variable.go +++ b/pkg/dal/table/app_template_variable.go @@ -16,7 +16,9 @@ import ( "database/sql/driver" "encoding/json" "errors" + "strings" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/kit" ) @@ -45,7 +47,7 @@ func (t *AppTemplateVariable) ResID() uint32 { // ResType AuditRes interface func (t *AppTemplateVariable) ResType() string { - return "app_template_variable" + return string(enumor.Variable) } // ValidateUpsert validate AppTemplateVariable is valid or not when create or update it. @@ -134,6 +136,15 @@ func (t *AppTemplateVariableSpec) ValidateUpsert(kit *kit.Kit) error { return nil } +// GetVariableNames get variable names +func (t *AppTemplateVariableSpec) GetVariableNames() string { + var name []string + for _, v := range t.Variables { + name = append(name, v.Name) + } + return strings.Join(name, ",") +} + // AppTemplateVariableAttachment defines the AppTemplateVariable attachments. type AppTemplateVariableAttachment struct { BizID uint32 `json:"biz_id" gorm:"column:biz_id"` diff --git a/pkg/dal/table/audit.go b/pkg/dal/table/audit.go index 5dc4cfe31..2d6e5d732 100644 --- a/pkg/dal/table/audit.go +++ b/pkg/dal/table/audit.go @@ -68,9 +68,8 @@ type AuditBasicDetail struct { // AuditField defines the audit's basic field type AuditField struct { - OperateWay string - Action enumor.AuditAction ResourceInstance string + Detail string Status enumor.AuditStatus AppId uint32 StrategyId uint32 diff --git a/pkg/dal/table/client.go b/pkg/dal/table/client.go index 02dd460da..7b68fecac 100644 --- a/pkg/dal/table/client.go +++ b/pkg/dal/table/client.go @@ -16,6 +16,8 @@ import ( "errors" "fmt" "time" + + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" ) // Client is a client @@ -81,7 +83,7 @@ func (c *Client) ResID() uint32 { // ResType AuditRes interface func (c *Client) ResType() string { - return "client" + return string(enumor.Instance) } // ValidateCreate validate app's info when created. diff --git a/pkg/dal/table/config_item.go b/pkg/dal/table/config_item.go index 1cadd38b0..0170ee89c 100644 --- a/pkg/dal/table/config_item.go +++ b/pkg/dal/table/config_item.go @@ -57,7 +57,7 @@ func (c *ConfigItem) ResID() uint32 { // ResType AuditRes interface func (c *ConfigItem) ResType() string { - return "config_item" + return string(enumor.Config) } // TableName is the config item's database table name. diff --git a/pkg/dal/table/credential_scope.go b/pkg/dal/table/credential_scope.go index 18a0740e1..0ee863aa0 100644 --- a/pkg/dal/table/credential_scope.go +++ b/pkg/dal/table/credential_scope.go @@ -16,6 +16,7 @@ import ( "errors" "time" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/runtime/credential" ) @@ -45,7 +46,7 @@ func (c *CredentialScope) ResID() uint32 { // ResType AuditRes interface func (c *CredentialScope) ResType() string { - return "credential_scope" + return string(enumor.Credential) } // ValidateCreate validate Credential is valid or not when create it. diff --git a/pkg/dal/table/group.go b/pkg/dal/table/group.go index 170062f0b..c3dec5e9b 100644 --- a/pkg/dal/table/group.go +++ b/pkg/dal/table/group.go @@ -59,7 +59,7 @@ func (g Group) ResID() uint32 { // ResType AuditRes interface func (g Group) ResType() string { - return "app" + return string(enumor.Group) } // ValidateCreate validate group is valid or not when create it. diff --git a/pkg/dal/table/hook_revision.go b/pkg/dal/table/hook_revision.go index 594a02fc4..cd9736438 100644 --- a/pkg/dal/table/hook_revision.go +++ b/pkg/dal/table/hook_revision.go @@ -17,6 +17,7 @@ import ( "fmt" "strings" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/validator" "github.com/TencentBlueKing/bk-bscp/pkg/kit" ) @@ -62,7 +63,7 @@ func (r *HookRevision) ResID() uint32 { // ResType AuditRes interface func (r *HookRevision) ResType() string { - return "hook_revisions" + return string(enumor.Hook) } // ValidateCreate validate hook is valid or not when create it. diff --git a/pkg/dal/table/kv.go b/pkg/dal/table/kv.go index c8a5e41e9..7bc723f02 100644 --- a/pkg/dal/table/kv.go +++ b/pkg/dal/table/kv.go @@ -22,6 +22,7 @@ import ( "gopkg.in/yaml.v3" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/validator" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/tools" @@ -72,7 +73,7 @@ func (k *Kv) ResID() uint32 { // ResType KvRes interface func (k *Kv) ResType() string { - return "kv" + return string(enumor.Config) } // ValidateCreate validate kv is valid or not when create it. diff --git a/pkg/dal/table/release.go b/pkg/dal/table/release.go index 703bad816..b64cc8ab3 100644 --- a/pkg/dal/table/release.go +++ b/pkg/dal/table/release.go @@ -59,7 +59,7 @@ func (r *Release) ResID() uint32 { // ResType AuditRes interface func (r *Release) ResType() string { - return "release" + return string(enumor.Release) } // ValidateCreate a release's information diff --git a/pkg/dal/table/strategy.go b/pkg/dal/table/strategy.go index cbaca705e..72cd1dd1b 100644 --- a/pkg/dal/table/strategy.go +++ b/pkg/dal/table/strategy.go @@ -19,6 +19,7 @@ import ( "fmt" "time" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/validator" "github.com/TencentBlueKing/bk-bscp/pkg/kit" "github.com/TencentBlueKing/bk-bscp/pkg/runtime/selector" @@ -82,7 +83,7 @@ func (s *Strategy) ResID() uint32 { // ResType AuditRes interface func (s *Strategy) ResType() string { - return "strategy" + return string(enumor.Release) } // ValidateCreate validate strategy is valid or not when create it. diff --git a/pkg/dal/table/template.go b/pkg/dal/table/template.go index ad34cd571..7cb715d20 100644 --- a/pkg/dal/table/template.go +++ b/pkg/dal/table/template.go @@ -16,6 +16,7 @@ import ( "errors" "fmt" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/validator" "github.com/TencentBlueKing/bk-bscp/pkg/kit" ) @@ -45,7 +46,7 @@ func (t *Template) ResID() uint32 { // ResType AuditRes interface func (t *Template) ResType() string { - return "template" + return string(enumor.Template) } // ValidateCreate validate template is valid or not when create it. diff --git a/pkg/dal/table/template_revision.go b/pkg/dal/table/template_revision.go index ba7e3b288..3c21ecea9 100644 --- a/pkg/dal/table/template_revision.go +++ b/pkg/dal/table/template_revision.go @@ -15,6 +15,7 @@ package table import ( "errors" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/validator" "github.com/TencentBlueKing/bk-bscp/pkg/kit" ) @@ -44,7 +45,7 @@ func (t *TemplateRevision) ResID() uint32 { // ResType AuditRes interface func (t *TemplateRevision) ResType() string { - return "template_revision" + return string(enumor.Template) } // ValidateCreate validate template revision is valid or not when create it. diff --git a/pkg/dal/table/template_set.go b/pkg/dal/table/template_set.go index 556420367..d53239dd4 100644 --- a/pkg/dal/table/template_set.go +++ b/pkg/dal/table/template_set.go @@ -15,6 +15,7 @@ package table import ( "errors" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/validator" "github.com/TencentBlueKing/bk-bscp/pkg/dal/types" "github.com/TencentBlueKing/bk-bscp/pkg/kit" @@ -45,7 +46,7 @@ func (t *TemplateSet) ResID() uint32 { // ResType AuditRes interface func (t *TemplateSet) ResType() string { - return "template_set" + return string(enumor.Template) } // ValidateCreate validate template set is valid or not when create it. diff --git a/pkg/dal/table/template_space.go b/pkg/dal/table/template_space.go index c48764a3f..43a943b7f 100644 --- a/pkg/dal/table/template_space.go +++ b/pkg/dal/table/template_space.go @@ -15,6 +15,7 @@ package table import ( "errors" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/validator" "github.com/TencentBlueKing/bk-bscp/pkg/kit" ) @@ -44,7 +45,7 @@ func (t *TemplateSpace) ResID() uint32 { // ResType AuditRes interface func (t *TemplateSpace) ResType() string { - return "template_space" + return string(enumor.Template) } // ValidateCreate validate template space is valid or not when create it. diff --git a/pkg/dal/table/template_variable.go b/pkg/dal/table/template_variable.go index e94973e43..40c21702b 100644 --- a/pkg/dal/table/template_variable.go +++ b/pkg/dal/table/template_variable.go @@ -15,6 +15,7 @@ package table import ( "errors" + "github.com/TencentBlueKing/bk-bscp/pkg/criteria/enumor" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/errf" "github.com/TencentBlueKing/bk-bscp/pkg/criteria/validator" "github.com/TencentBlueKing/bk-bscp/pkg/i18n" @@ -47,7 +48,7 @@ func (t *TemplateVariable) ResID() uint32 { // ResType AuditRes interface func (t *TemplateVariable) ResType() string { - return "template_variable" + return string(enumor.Variable) } // ValidateCreate validate template variable is valid or not when create it. diff --git a/pkg/types/audit.go b/pkg/types/audit.go index f87b86045..914269a5f 100644 --- a/pkg/types/audit.go +++ b/pkg/types/audit.go @@ -69,6 +69,13 @@ type ListAuditsAppStrategy struct { App AppPart `json:"app" gorm:"embedded"` Audit AuditPart `json:"audit" gorm:"embedded"` Strategy StrategyPart `json:"strategy" gorm:"embedded"` + Client ClientPart `json:"client" gorm:"embedded"` +} + +// ClientPart client field +type ClientPart struct { + ReleaseChangeStatus string `json:"release_change_status" gorm:"column:release_change_status"` + FailedDetailReason string `json:"failed_detail_reason" gorm:"column:failed_detail_reason"` } // AppPart app field @@ -91,6 +98,7 @@ type AuditPart struct { ResInstance string `db:"res_instance" json:"res_instance" gorm:"column:res_instance"` OperateWay string `db:"operate_way" json:"operate_way" gorm:"column:operate_way"` Status string `db:"status" json:"status" gorm:"column:status"` + Detail string `db:"detail" json:"detail" gorm:"column:detail"` IsCompare bool `db:"is_compare" json:"is_compare" gorm:"column:is_compare"` } @@ -116,3 +124,9 @@ type StrategyPart struct { ApproveType string `db:"approve_type" json:"approve_type" gorm:"column:approve_type"` Memo string `db:"memo" json:"memo" gorm:"column:memo"` } + +// TemplateSetSpaceName template space set name +type TemplateSetSpaceName struct { + TemplateSetName string `db:"template_set_name" json:"template_set_name" gorm:"column:template_set_name"` + TemplateSpaceName string `db:"template_space_name" json:"template_space_name" gorm:"column:template_space_name"` +} diff --git a/scripts/gen/main.go b/scripts/gen/main.go index 33947a80d..3d76482fd 100644 --- a/scripts/gen/main.go +++ b/scripts/gen/main.go @@ -21,7 +21,7 @@ import ( func main() { g := gen.NewGenerator(gen.Config{ - OutPath: "./pkg/dal/gen", + OutPath: "../../internal/dal/gen", Mode: gen.WithDefaultQuery | gen.WithQueryInterface, FieldNullable: true, })