diff --git a/bcs-services/bcs-user-manager/app/app.go b/bcs-services/bcs-user-manager/app/app.go index fd6e0ab885..8eeee8e83b 100644 --- a/bcs-services/bcs-user-manager/app/app.go +++ b/bcs-services/bcs-user-manager/app/app.go @@ -104,6 +104,7 @@ func parseConfig(op *options.UserManagerOptions) (*config.UserMgrConfig, error) userMgrConfig.CommunityEdition = op.CommunityEdition userMgrConfig.BcsAPI = &op.BcsAPI userMgrConfig.Encrypt = op.Encrypt + userMgrConfig.Activity = op.Activity config.Tke = op.TKE secretID, err := encrypt.DesDecryptFromBase([]byte(config.Tke.SecretID)) diff --git a/bcs-services/bcs-user-manager/app/user-manager/job/activity/activity.go b/bcs-services/bcs-user-manager/app/user-manager/job/activity/activity.go new file mode 100644 index 0000000000..86194140ac --- /dev/null +++ b/bcs-services/bcs-user-manager/app/user-manager/job/activity/activity.go @@ -0,0 +1,65 @@ +/* + * 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 activity job +package activity + +import ( + "context" + "time" + + "github.com/Tencent/bk-bcs/bcs-common/common/blog" + + "github.com/Tencent/bk-bcs/bcs-services/bcs-user-manager/app/user-manager/storages/sqlstore" + "github.com/Tencent/bk-bcs/bcs-services/bcs-user-manager/config" +) + +// IntervalDeleteActivity 定时清理操作记录 +func IntervalDeleteActivity(ctx context.Context) (err error) { + // 间隔时间,默认一天 + intervalTime := time.Hour * 24 + if config.GetGlobalConfig().Activity.Interval != "" { + // 从配置文件里面解析间隔时间 + intervalTime, err = time.ParseDuration(config.GetGlobalConfig().Activity.Interval) + if err != nil { + return err + } + } + timer := time.NewTicker(intervalTime) + defer timer.Stop() + for { + select { + case <-ctx.Done(): + return nil + case <-timer.C: + // 未配置清理天数及清理资源类型则忽略 + if config.GetGlobalConfig().Activity.Duration == "" || + len(config.GetGlobalConfig().Activity.ResourceType) == 0 { + blog.Info("user not configured, ignoring") + continue + } + // 解析配置文件的配置时间,如1s、1m、1h + duration, err := time.ParseDuration(config.GetGlobalConfig().Activity.Duration) + if err != nil { + blog.Errorf("ParseDuration failed: %v", err) + continue + } + // 当前时间减去配置的天数,如:30天前 + createdAt := time.Now().Add(-duration) + // 批量删除记录 + err = sqlstore.BatchDeleteActivity(config.GetGlobalConfig().Activity.ResourceType, createdAt) + if err != nil { + blog.Errorf("BatchDeleteActivity failed: %v", err) + } + } + } +} diff --git a/bcs-services/bcs-user-manager/app/user-manager/storages/sqlstore/activity.go b/bcs-services/bcs-user-manager/app/user-manager/storages/sqlstore/activity.go index 22a9ac5a6f..cf75740613 100644 --- a/bcs-services/bcs-user-manager/app/user-manager/storages/sqlstore/activity.go +++ b/bcs-services/bcs-user-manager/app/user-manager/storages/sqlstore/activity.go @@ -64,3 +64,26 @@ func CreateActivity(activity []*models.Activity) error { } return nil } + +// BatchDeleteActivity 通过配置的天数,资源类型删除操作记录 +func BatchDeleteActivity(resourceType []string, createdAt time.Time) error { + // stopFlag 循环删除的标志 + stopFlag := true + // batchSize 一次删除的条数 + batchSize := 1000 + for stopFlag { + // 清理配置的天数之前的数据,资源类型为配置需要清理的类型 + result := GCoreDB.Limit(batchSize).Where("resource_type in (?) and created_at < ?", + resourceType, createdAt).Delete(&models.Activity{}) + if result.Error != nil { + return result.Error + } + + // 删除的数据少于batchSize的时候说明数据没超过batchSize + if result.RowsAffected != int64(batchSize) { + stopFlag = false + } + } + + return nil +} diff --git a/bcs-services/bcs-user-manager/app/user-manager/user-manager.go b/bcs-services/bcs-user-manager/app/user-manager/user-manager.go index 432370d1cb..bd9f9ef36e 100644 --- a/bcs-services/bcs-user-manager/app/user-manager/user-manager.go +++ b/bcs-services/bcs-user-manager/app/user-manager/user-manager.go @@ -14,6 +14,7 @@ package usermanager import ( "bytes" + "context" "crypto/tls" "embed" "errors" @@ -38,6 +39,7 @@ import ( "go-micro.dev/v4/registry" i18n2 "github.com/Tencent/bk-bcs/bcs-services/bcs-user-manager/app/pkg/i18n" + "github.com/Tencent/bk-bcs/bcs-services/bcs-user-manager/app/user-manager/job/activity" "github.com/Tencent/bk-bcs/bcs-services/bcs-user-manager/app/user-manager/storages/cache" "github.com/Tencent/bk-bcs/bcs-services/bcs-user-manager/app/user-manager/storages/sqlstore" "github.com/Tencent/bk-bcs/bcs-services/bcs-user-manager/app/user-manager/v1http" @@ -92,6 +94,14 @@ func (u *UserManager) Start() error { return err } + // 定时清理操作记录 + go func() { + err := activity.IntervalDeleteActivity(context.Background()) + if err != nil { + blog.Errorf("IntervalDeleteActivity failed: %v", err) + } + }() + // init usermanager role and cache permission go permission.InitCache() time.Sleep(1 * time.Second) diff --git a/bcs-services/bcs-user-manager/config/config.go b/bcs-services/bcs-user-manager/config/config.go index 19b214deeb..ee35be43d8 100644 --- a/bcs-services/bcs-user-manager/config/config.go +++ b/bcs-services/bcs-user-manager/config/config.go @@ -98,6 +98,9 @@ type UserMgrConfig struct { // Encrypt Encrypt options.Encrypt + + // 操作记录清理 + Activity options.Activity } var ( diff --git a/bcs-services/bcs-user-manager/options/options.go b/bcs-services/bcs-user-manager/options/options.go index 38900721fe..f206ebe0ff 100644 --- a/bcs-services/bcs-user-manager/options/options.go +++ b/bcs-services/bcs-user-manager/options/options.go @@ -50,6 +50,7 @@ type UserManagerOptions struct { TracingConf TracingConf `json:"tracing_conf"` BcsAPI BcsAPI `json:"bcs_api"` Encrypt Encrypt `json:"encrypt" yaml:"encrypt"` + Activity Activity `json:"activity" yaml:"activity"` } // TracingConf tracing config @@ -147,3 +148,10 @@ type EncryptSecret struct { Key string `json:"key" yaml:"key"` Secret string `json:"secret" yaml:"secret"` } + +// Activity 操作记录清理 +type Activity struct { + Duration string `json:"duration" yaml:"duration" usage:"cleaning time"` + Interval string `json:"interval" yaml:"interval" usage:"timed tasks"` + ResourceType []string `json:"resource_type" yaml:"resource_type"` +} diff --git a/bcs-services/cluster-resources/pkg/resource/formatter/common.go b/bcs-services/cluster-resources/pkg/resource/formatter/common.go index 59016df0f0..64f221c5c3 100644 --- a/bcs-services/cluster-resources/pkg/resource/formatter/common.go +++ b/bcs-services/cluster-resources/pkg/resource/formatter/common.go @@ -29,8 +29,9 @@ func CommonFormatRes(manifest map[string]interface{}) map[string]interface{} { "editMode": mapx.Get( manifest, []string{"metadata", "annotations", resCsts.EditModeAnnoKey}, resCsts.EditModeYaml, ), - "creator": mapx.GetStr(manifest, []string{"metadata", "annotations", resCsts.CreatorAnnoKey}), - "updater": mapx.GetStr(manifest, []string{"metadata", "annotations", resCsts.UpdaterAnnoKey}), + "creator": mapx.GetStr(manifest, []string{"metadata", "annotations", resCsts.CreatorAnnoKey}), + "updater": mapx.GetStr(manifest, []string{"metadata", "annotations", resCsts.UpdaterAnnoKey}), + "immutable": parseLabelsHelm(manifest), } return ret } @@ -81,3 +82,9 @@ func FormatPodManifestRes(kind string, manifest map[string]interface{}) map[stri } return newManifest } + +// 解析labels是否包含helm发布 +func parseLabelsHelm(manifest map[string]interface{}) bool { + labels := mapx.GetMap(manifest, "metadata.labels") + return mapx.GetStr(labels, []string{"app.kubernetes.io/managed-by"}) == "Helm" +}