github.com/polarismesh/polaris@v1.17.8/config/config_file.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package config 19 20 import ( 21 "context" 22 "strings" 23 "time" 24 25 "github.com/gogo/protobuf/jsonpb" 26 apiconfig "github.com/polarismesh/specification/source/go/api/v1/config_manage" 27 apimodel "github.com/polarismesh/specification/source/go/api/v1/model" 28 "go.uber.org/zap" 29 "google.golang.org/protobuf/types/known/wrapperspb" 30 31 api "github.com/polarismesh/polaris/common/api/v1" 32 "github.com/polarismesh/polaris/common/model" 33 commonstore "github.com/polarismesh/polaris/common/store" 34 "github.com/polarismesh/polaris/common/utils" 35 "github.com/polarismesh/polaris/store" 36 ) 37 38 // CreateConfigFile 创建配置文件 39 func (s *Server) CreateConfigFile(ctx context.Context, req *apiconfig.ConfigFile) *apiconfig.ConfigResponse { 40 if rsp := s.prepareCreateConfigFile(ctx, req); rsp.Code.Value != api.ExecuteSuccess { 41 return rsp 42 } 43 44 tx, err := s.storage.StartTx() 45 if err != nil { 46 log.Error("[Config][File] create config file begin tx.", utils.RequestID(ctx), zap.Error(err)) 47 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 48 } 49 defer func() { 50 _ = tx.Rollback() 51 }() 52 53 resp := s.handleCreateConfigFile(ctx, tx, req) 54 if resp.GetCode().GetValue() != uint32(apimodel.Code_ExecuteSuccess) { 55 return resp 56 } 57 if err := tx.Commit(); err != nil { 58 log.Error("[Config][File] create config file commit tx.", utils.RequestID(ctx), zap.Error(err)) 59 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 60 } 61 resp.ConfigFile = req 62 return resp 63 } 64 65 func (s *Server) handleCreateConfigFile(ctx context.Context, tx store.Tx, 66 req *apiconfig.ConfigFile) *apiconfig.ConfigResponse { 67 68 data, err := s.storage.GetConfigFileTx(tx, req.GetNamespace().GetValue(), req.GetGroup().GetValue(), 69 req.GetName().GetValue()) 70 if err != nil { 71 log.Error("[Config][File] create config file when get save data.", utils.RequestID(ctx), 72 utils.ZapNamespace(req.GetNamespace().GetValue()), utils.ZapGroup(req.GetGroup().GetValue()), 73 utils.ZapFileName(req.GetName().GetValue()), zap.Error(err)) 74 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 75 } 76 if data != nil { 77 return api.NewConfigResponse(apimodel.Code_ExistedResource) 78 } 79 80 savaData := model.ToConfigFileStore(req) 81 if errResp := s.chains.BeforeCreateFile(ctx, savaData); errResp != nil { 82 return errResp 83 } 84 // 创建配置文件 85 if err := s.storage.CreateConfigFileTx(tx, savaData); err != nil { 86 log.Error("[Config][File] create config file error.", utils.RequestID(ctx), 87 utils.ZapNamespace(req.GetNamespace().GetValue()), utils.ZapGroup(req.GetGroup().GetValue()), 88 utils.ZapFileName(req.GetName().GetValue()), zap.Error(err)) 89 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 90 } 91 s.RecordHistory(ctx, configFileRecordEntry(ctx, req, model.OCreate)) 92 return api.NewConfigResponse(apimodel.Code_ExecuteSuccess) 93 } 94 95 // UpdateConfigFile 更新配置文件 96 func (s *Server) UpdateConfigFile(ctx context.Context, req *apiconfig.ConfigFile) *apiconfig.ConfigResponse { 97 if checkRsp := s.checkConfigFileParams(req); checkRsp != nil { 98 return checkRsp 99 } 100 tx, err := s.storage.StartTx() 101 if err != nil { 102 log.Error("[Config][File] update config file begin tx.", utils.RequestID(ctx), zap.Error(err)) 103 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 104 } 105 defer func() { 106 _ = tx.Rollback() 107 }() 108 109 resp := s.handleUpdateConfigFile(ctx, tx, req) 110 if resp.GetCode().GetValue() != uint32(apimodel.Code_ExecuteSuccess) { 111 return resp 112 } 113 if err := tx.Commit(); err != nil { 114 log.Error("[Config][File] update config file commit tx.", utils.RequestID(ctx), zap.Error(err)) 115 return api.NewConfigResponseWithInfo(commonstore.StoreCode2APICode(err), err.Error()) 116 } 117 s.RecordHistory(ctx, configFileRecordEntry(ctx, req, model.OUpdate)) 118 return resp 119 } 120 121 func (s *Server) handleUpdateConfigFile(ctx context.Context, tx store.Tx, 122 req *apiconfig.ConfigFile) *apiconfig.ConfigResponse { 123 124 namespace := req.Namespace.GetValue() 125 group := req.Group.GetValue() 126 name := req.Name.GetValue() 127 128 saveData, err := s.storage.GetConfigFileTx(tx, req.GetNamespace().GetValue(), req.GetGroup().GetValue(), 129 req.GetName().GetValue()) 130 if err != nil { 131 log.Error("[Config][File] update config file when get save data.", utils.RequestID(ctx), zap.Error(err)) 132 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 133 } 134 if saveData == nil { 135 return api.NewConfigResponse(apimodel.Code_NotFoundResource) 136 } 137 updateData, needUpdate := s.updateConfigFileAttribute(saveData, model.ToConfigFileStore(req)) 138 if !needUpdate { 139 return api.NewConfigResponse(apimodel.Code_NoNeedUpdate) 140 } 141 142 if errResp := s.chains.BeforeUpdateFile(ctx, updateData); errResp != nil { 143 return errResp 144 } 145 146 if err := s.storage.UpdateConfigFileTx(tx, updateData); err != nil { 147 log.Error("[Config][File] update config file error.", utils.RequestID(ctx), 148 utils.ZapNamespace(namespace), utils.ZapGroup(group), utils.ZapFileName(name), zap.Error(err)) 149 return api.NewConfigFileResponse(commonstore.StoreCode2APICode(err), req) 150 } 151 return api.NewConfigFileResponse(apimodel.Code_ExecuteSuccess, model.ToConfigFileAPI(updateData)) 152 } 153 154 func (s *Server) updateConfigFileAttribute(saveData, updateData *model.ConfigFile) (*model.ConfigFile, bool) { 155 needUpdate := false 156 oldMetadata := saveData.Metadata 157 oldEncrtptAlgo := saveData.EncryptAlgo 158 if saveData.Comment != updateData.Comment { 159 needUpdate = true 160 saveData.Comment = updateData.Comment 161 } 162 if saveData.Comment != updateData.Content { 163 needUpdate = true 164 saveData.Content = updateData.Content 165 } 166 if saveData.Format != updateData.Format { 167 needUpdate = true 168 saveData.Format = updateData.Format 169 } 170 if utils.IsNotEqualMap(updateData.Metadata, saveData.Metadata) { 171 needUpdate = true 172 saveData.Metadata = updateData.Metadata 173 } 174 if saveData.Encrypt != updateData.Encrypt { 175 needUpdate = true 176 saveData.Encrypt = updateData.Encrypt 177 } 178 if saveData.EncryptAlgo != updateData.EncryptAlgo { 179 needUpdate = true 180 saveData.EncryptAlgo = updateData.EncryptAlgo 181 } 182 // 填充加密所需要的 Metadata Key 数据 183 if saveData.Encrypt && saveData.EncryptAlgo == oldEncrtptAlgo { 184 if len(saveData.Metadata) == 0 { 185 saveData.Metadata = map[string]string{} 186 } 187 saveData.Metadata[utils.ConfigFileTagKeyDataKey] = oldMetadata[utils.ConfigFileTagKeyDataKey] 188 saveData.Metadata[utils.ConfigFileTagKeyEncryptAlgo] = oldMetadata[utils.ConfigFileTagKeyEncryptAlgo] 189 } 190 191 return saveData, needUpdate 192 } 193 194 func (s *Server) prepareCreateConfigFile(ctx context.Context, 195 configFile *apiconfig.ConfigFile) *apiconfig.ConfigResponse { 196 197 configFile.CreateBy = utils.NewStringValue(utils.ParseUserName(ctx)) 198 configFile.ModifyBy = utils.NewStringValue(utils.ParseUserName(ctx)) 199 200 // 如果配置文件组不存在则自动创建 201 createGroupRsp := s.createConfigFileGroupIfAbsent(ctx, &apiconfig.ConfigFileGroup{ 202 Namespace: configFile.Namespace, 203 Name: configFile.Group, 204 CreateBy: configFile.CreateBy, 205 Comment: utils.NewStringValue("auto created"), 206 }) 207 208 if createGroupRsp.Code.GetValue() != uint32(apimodel.Code_ExecuteSuccess) { 209 return api.NewConfigFileResponse(apimodel.Code(createGroupRsp.Code.GetValue()), configFile) 210 } 211 return api.NewConfigResponse(apimodel.Code_ExecuteSuccess) 212 } 213 214 // BatchDeleteConfigFile 批量删除配置文件 215 func (s *Server) BatchDeleteConfigFile(ctx context.Context, req []*apiconfig.ConfigFile) *apiconfig.ConfigResponse { 216 if len(req) == 0 { 217 api.NewConfigFileResponse(apimodel.Code_ExecuteSuccess, nil) 218 } 219 for _, configFile := range req { 220 rsp := s.DeleteConfigFile(ctx, configFile) 221 if rsp.Code.GetValue() != uint32(apimodel.Code_ExecuteSuccess) { 222 return rsp 223 } 224 } 225 return api.NewConfigFileResponse(apimodel.Code_ExecuteSuccess, nil) 226 } 227 228 // DeleteConfigFile 删除配置文件,删除配置文件同时会通知客户端 Not_Found 229 func (s *Server) DeleteConfigFile(ctx context.Context, req *apiconfig.ConfigFile) *apiconfig.ConfigResponse { 230 if errResp := checkReadFileParameter(req); errResp != nil { 231 return errResp 232 } 233 234 namespace := req.GetNamespace().GetValue() 235 group := req.GetGroup().GetValue() 236 fileName := req.GetName().GetValue() 237 238 tx, err := s.storage.StartTx() 239 if err != nil { 240 log.Error("[Config][File] delete config file begin tx.", utils.RequestID(ctx), zap.Error(err)) 241 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 242 } 243 defer func() { _ = tx.Rollback() }() 244 245 file, err := s.storage.LockConfigFile(tx, &model.ConfigFileKey{ 246 Namespace: namespace, 247 Group: group, 248 Name: fileName, 249 }) 250 if err != nil { 251 log.Error("[Config][File] delete config file when lock.", utils.RequestID(ctx), 252 utils.ZapNamespace(namespace), utils.ZapGroup(group), utils.ZapFileName(fileName), zap.Error(err)) 253 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 254 } 255 if file == nil { 256 return api.NewConfigResponse(apimodel.Code_ExecuteSuccess) 257 } 258 // 1. 删除配置文件发布内容 259 if errResp := s.cleanConfigFileReleases(ctx, tx, file); errResp != nil { 260 return errResp 261 } 262 // 2. 删除配置文件 263 if err = s.storage.DeleteConfigFileTx(tx, namespace, group, fileName); err != nil { 264 log.Error("[Config][File] delete config file error.", utils.RequestID(ctx), 265 utils.ZapNamespace(namespace), utils.ZapGroup(group), utils.ZapFileName(fileName), zap.Error(err)) 266 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 267 } 268 if err := tx.Commit(); err != nil { 269 log.Error("[Config][File] delete config file when commit tx.", utils.RequestID(ctx), 270 utils.ZapNamespace(namespace), utils.ZapGroup(group), utils.ZapFileName(fileName), zap.Error(err)) 271 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 272 } 273 s.RecordHistory(ctx, configFileRecordEntry(ctx, &apiconfig.ConfigFile{ 274 Namespace: utils.NewStringValue(namespace), 275 Group: utils.NewStringValue(group), 276 Name: utils.NewStringValue(fileName), 277 }, model.ODelete)) 278 return api.NewConfigResponse(apimodel.Code_ExecuteSuccess) 279 } 280 281 // GetConfigFileRichInfo 获取单个配置文件基础信息,包含发布状态等信息 282 func (s *Server) GetConfigFileRichInfo(ctx context.Context, req *apiconfig.ConfigFile) *apiconfig.ConfigResponse { 283 if errResp := checkReadFileParameter(req); errResp != nil { 284 return errResp 285 } 286 287 namespace := req.GetNamespace().GetValue() 288 group := req.GetGroup().GetValue() 289 fileName := req.GetName().GetValue() 290 291 file, err := s.storage.GetConfigFile(namespace, group, fileName) 292 if err != nil { 293 log.Error("[Config][File] get config file error.", utils.RequestID(ctx), 294 utils.ZapNamespace(namespace), utils.ZapGroup(group), utils.ZapFileName(fileName), zap.Error(err)) 295 return api.NewConfigResponse(commonstore.StoreCode2APICode(err)) 296 } 297 if file == nil { 298 return api.NewConfigResponse(apimodel.Code_NotFoundResource) 299 } 300 301 // 填充发布信息、标签信息等 302 richFile, err := s.chains.AfterGetFile(ctx, file) 303 if err != nil { 304 return api.NewConfigResponseWithInfo(apimodel.Code_ExecuteException, err.Error()) 305 } 306 ret := model.ToConfigFileAPI(richFile) 307 return api.NewConfigFileResponse(apimodel.Code_ExecuteSuccess, ret) 308 } 309 310 // SearchConfigFile 查询配置文件 311 func (s *Server) SearchConfigFile(ctx context.Context, filter map[string]string) *apiconfig.ConfigBatchQueryResponse { 312 offset, limit, err := utils.ParseOffsetAndLimit(filter) 313 if err != nil { 314 out := api.NewConfigBatchQueryResponse(apimodel.Code_BadRequest) 315 out.Info = utils.NewStringValue(err.Error()) 316 return out 317 } 318 searchFilters := map[string]string{} 319 for k, v := range filter { 320 // 无效查询参数自动忽略 321 if v == "" { 322 continue 323 } 324 if _, ok := availableSearch["config_file"][k]; ok { 325 searchFilters[k] = v 326 } 327 } 328 count, files, err := s.storage.QueryConfigFiles(searchFilters, offset, limit) 329 if err != nil { 330 log.Error("[Config][File] search config files.", utils.RequestID(ctx), zap.Error(err)) 331 out := api.NewConfigBatchQueryResponse(commonstore.StoreCode2APICode(err)) 332 return out 333 } 334 335 if len(files) == 0 { 336 out := api.NewConfigBatchQueryResponse(apimodel.Code_ExecuteSuccess) 337 out.Total = utils.NewUInt32Value(count) 338 return out 339 } 340 341 ret := make([]*apiconfig.ConfigFile, 0, len(files)) 342 for _, file := range files { 343 file, err := s.chains.AfterGetFile(ctx, file) 344 if err != nil { 345 log.Error("[Config][File] search files run chain after-get file.", utils.RequestID(ctx), 346 zap.Error(err)) 347 return api.NewConfigBatchQueryResponse(apimodel.Code_ExecuteException) 348 } 349 ret = append(ret, model.ToConfigFileAPI(file)) 350 } 351 out := api.NewConfigBatchQueryResponse(apimodel.Code_ExecuteSuccess) 352 out.Total = utils.NewUInt32Value(count) 353 out.ConfigFiles = ret 354 return out 355 } 356 357 // ExportConfigFile 导出配置文件 358 func (s *Server) ExportConfigFile(ctx context.Context, 359 configFileExport *apiconfig.ConfigFileExportRequest) *apiconfig.ConfigExportResponse { 360 namespace := configFileExport.Namespace.GetValue() 361 var groups []string 362 for _, group := range configFileExport.Groups { 363 groups = append(groups, group.GetValue()) 364 } 365 var names []string 366 for _, name := range configFileExport.Names { 367 names = append(names, name.GetValue()) 368 } 369 // 检查参数 370 if err := CheckResourceName(configFileExport.Namespace); err != nil { 371 return api.NewConfigFileExportResponse(apimodel.Code_InvalidNamespaceName, nil) 372 } 373 var ( 374 isExportGroup bool 375 configFiles []*model.ConfigFile 376 ) 377 if len(groups) >= 1 && len(names) == 0 { 378 // 导出配置组 379 isExportGroup = true 380 for _, group := range groups { 381 files, err := s.getGroupAllConfigFiles(namespace, group) 382 if err != nil { 383 log.Error("[Config][File] get config file by group error.", utils.RequestID(ctx), 384 utils.ZapNamespace(namespace), utils.ZapGroup(group), zap.Error(err)) 385 return api.NewConfigFileExportResponse(commonstore.StoreCode2APICode(err), nil) 386 } 387 configFiles = append(configFiles, files...) 388 } 389 } else if len(groups) == 1 && len(names) > 0 { 390 // 导出配置文件 391 for _, name := range names { 392 file, err := s.storage.GetConfigFile(namespace, groups[0], name) 393 if err != nil { 394 log.Error("[Config][File] get config file error.", utils.RequestID(ctx), 395 utils.ZapNamespace(namespace), utils.ZapGroup(groups[0]), utils.ZapFileName(name), 396 zap.Error(err)) 397 return api.NewConfigFileExportResponse(commonstore.StoreCode2APICode(err), nil) 398 } 399 configFiles = append(configFiles, file) 400 } 401 } else { 402 log.Error("[Config][File] export config file error.", utils.RequestID(ctx), 403 utils.ZapNamespace(namespace), zap.String("groups", strings.Join(groups, ",")), 404 zap.String("names", strings.Join(names, ","))) 405 return api.NewConfigFileExportResponse(apimodel.Code_InvalidParameter, nil) 406 } 407 if len(configFiles) == 0 { 408 return api.NewConfigFileExportResponse(apimodel.Code_NotFoundResourceConfigFile, nil) 409 } 410 // 查询配置文件的标签 411 fileID2Tags := make(map[uint64][]*model.ConfigFileTag) 412 for _, file := range configFiles { 413 filterTags := make([]*model.ConfigFileTag, 0, len(file.Metadata)) 414 for tagKey, tagVal := range file.Metadata { 415 filterTags = append(filterTags, &model.ConfigFileTag{ 416 Key: tagKey, 417 Value: tagVal, 418 }) 419 } 420 fileID2Tags[file.Id] = filterTags 421 } 422 // 生成ZIP文件 423 buf, err := CompressConfigFiles(configFiles, fileID2Tags, isExportGroup) 424 if err != nil { 425 log.Error("[Config][Servie]export config files compress to zip error.", zap.Error(err)) 426 } 427 return api.NewConfigFileExportResponse(apimodel.Code_ExecuteSuccess, buf.Bytes()) 428 } 429 430 // ImportConfigFile 导入配置文件 431 func (s *Server) ImportConfigFile(ctx context.Context, 432 configFiles []*apiconfig.ConfigFile, conflictHandling string) *apiconfig.ConfigImportResponse { 433 // 预创建命名空间和分组 434 for _, configFile := range configFiles { 435 if checkRsp := s.checkConfigFileParams(configFile); checkRsp != nil { 436 return api.NewConfigFileImportResponse(apimodel.Code(checkRsp.Code.GetValue()), nil, nil, nil) 437 } 438 if rsp := s.prepareCreateConfigFile(ctx, configFile); rsp.Code.Value != api.ExecuteSuccess { 439 return api.NewConfigFileImportResponse(apimodel.Code(rsp.Code.GetValue()), nil, nil, nil) 440 } 441 } 442 443 // 开启事务 444 tx, err := s.storage.StartTx() 445 if err != nil { 446 return api.NewConfigFileImportResponse(commonstore.StoreCode2APICode(err), nil, nil, nil) 447 } 448 defer func() { _ = tx.Rollback() }() 449 450 // 记录创建,跳过,覆盖的配置文件 451 var ( 452 createConfigFiles []*apiconfig.ConfigFile 453 skipConfigFiles []*apiconfig.ConfigFile 454 overwriteConfigFiles []*apiconfig.ConfigFile 455 ) 456 for _, configFile := range configFiles { 457 namespace := configFile.Namespace.GetValue() 458 group := configFile.Group.GetValue() 459 name := configFile.Name.GetValue() 460 461 managedFile, err := s.storage.GetConfigFileTx(tx, namespace, group, name) 462 if err != nil { 463 log.Error("[Config][File] get config file error.", utils.RequestID(ctx), 464 utils.ZapNamespace(namespace), utils.ZapGroup(group), utils.ZapFileName(name), zap.Error(err)) 465 return api.NewConfigFileImportResponse(commonstore.StoreCode2APICode(err), nil, nil, nil) 466 } 467 // 如果配置文件存在 468 if managedFile != nil { 469 if conflictHandling == utils.ConfigFileImportConflictSkip { 470 skipConfigFiles = append(skipConfigFiles, configFile) 471 continue 472 } else if conflictHandling == utils.ConfigFileImportConflictOverwrite { 473 resp := s.handleUpdateConfigFile(ctx, tx, configFile) 474 if resp.GetCode().GetValue() != uint32(apimodel.Code_ExecuteSuccess) { 475 log.Error("[Config][File] update config file error.", utils.RequestID(ctx), 476 utils.ZapNamespace(namespace), utils.ZapGroup(group), utils.ZapFileName(name), zap.Error(err)) 477 return api.NewConfigFileImportResponse(commonstore.StoreCode2APICode(err), nil, nil, nil) 478 } 479 overwriteConfigFiles = append(overwriteConfigFiles, configFile) 480 s.RecordHistory(ctx, configFileRecordEntry(ctx, configFile, model.OUpdate)) 481 } 482 } else { 483 // 配置文件不存在则创建 484 resp := s.handleCreateConfigFile(ctx, tx, configFile) 485 if resp.GetCode().GetValue() != uint32(apimodel.Code_ExecuteSuccess) { 486 log.Error("[Config][File] create config file error.", utils.RequestID(ctx), 487 utils.ZapNamespace(namespace), utils.ZapGroup(group), utils.ZapFileName(name), zap.Error(err)) 488 return api.NewConfigFileImportResponse(commonstore.StoreCode2APICode(err), nil, nil, nil) 489 } 490 createConfigFiles = append(createConfigFiles, configFile) 491 s.RecordHistory(ctx, configFileRecordEntry(ctx, configFile, model.OCreate)) 492 } 493 } 494 495 if err := tx.Commit(); err != nil { 496 log.Error("[Config][File] commit import config file tx error.", utils.RequestID(ctx), zap.Error(err)) 497 return api.NewConfigFileImportResponse(commonstore.StoreCode2APICode(err), nil, nil, nil) 498 } 499 500 return api.NewConfigFileImportResponse(apimodel.Code_ExecuteSuccess, 501 createConfigFiles, skipConfigFiles, overwriteConfigFiles) 502 } 503 504 func (s *Server) getGroupAllConfigFiles(namespace, group string) ([]*model.ConfigFile, error) { 505 var configFiles []*model.ConfigFile 506 offset := uint32(0) 507 limit := uint32(100) 508 for { 509 _, files, err := s.storage.QueryConfigFiles(map[string]string{ 510 "namespace": namespace, 511 "group": group, 512 }, offset, limit) 513 if err != nil { 514 return nil, err 515 } 516 if len(files) == 0 { 517 break 518 } 519 configFiles = append(configFiles, files...) 520 offset += uint32(len(files)) 521 } 522 return configFiles, nil 523 } 524 525 func (s *Server) checkConfigFileParams(configFile *apiconfig.ConfigFile) *apiconfig.ConfigResponse { 526 if configFile == nil { 527 return api.NewConfigFileResponse(apimodel.Code_InvalidParameter, configFile) 528 } 529 if err := CheckFileName(configFile.Name); err != nil { 530 return api.NewConfigFileResponse(apimodel.Code_InvalidConfigFileName, configFile) 531 } 532 if err := CheckResourceName(configFile.Namespace); err != nil { 533 return api.NewConfigFileResponse(apimodel.Code_InvalidNamespaceName, configFile) 534 } 535 if err := CheckContentLength(configFile.Content.GetValue(), int(s.cfg.ContentMaxLength)); err != nil { 536 return api.NewConfigResponseWithInfo(apimodel.Code_InvalidConfigFileContentLength, err.Error()) 537 } 538 if len(configFile.Tags) > 0 { 539 for _, tag := range configFile.Tags { 540 if tag.Key.GetValue() == "" || tag.Value.GetValue() == "" { 541 return api.NewConfigFileResponse(apimodel.Code_InvalidConfigFileTags, configFile) 542 } 543 } 544 } 545 return nil 546 } 547 548 // GetAllConfigEncryptAlgorithms 获取配置加密算法 549 func (s *Server) GetAllConfigEncryptAlgorithms(ctx context.Context) *apiconfig.ConfigEncryptAlgorithmResponse { 550 if s.cryptoManager == nil { 551 return api.NewConfigEncryptAlgorithmResponse(apimodel.Code_ExecuteSuccess, nil) 552 } 553 var algorithms []*wrapperspb.StringValue 554 for _, name := range s.cryptoManager.GetCryptoAlgoNames() { 555 algorithms = append(algorithms, utils.NewStringValue(name)) 556 } 557 return api.NewConfigEncryptAlgorithmResponse(apimodel.Code_ExecuteSuccess, algorithms) 558 } 559 560 // configFileRecordEntry 生成服务的记录entry 561 func configFileRecordEntry(ctx context.Context, req *apiconfig.ConfigFile, 562 operationType model.OperationType) *model.RecordEntry { 563 564 marshaler := jsonpb.Marshaler{} 565 detail, _ := marshaler.MarshalToString(req) 566 567 entry := &model.RecordEntry{ 568 ResourceType: model.RConfigFile, 569 ResourceName: req.GetName().GetValue(), 570 Namespace: req.GetNamespace().GetValue(), 571 OperationType: operationType, 572 Operator: utils.ParseOperator(ctx), 573 Detail: detail, 574 HappenTime: time.Now(), 575 } 576 577 return entry 578 } 579 580 func checkReadFileParameter(req *apiconfig.ConfigFile) *apiconfig.ConfigResponse { 581 if req.GetNamespace().GetValue() == "" { 582 return api.NewConfigResponse(apimodel.Code_InvalidNamespaceName) 583 } 584 if req.GetGroup().GetValue() == "" { 585 return api.NewConfigResponse(apimodel.Code_InvalidConfigFileGroupName) 586 } 587 if req.GetName().GetValue() == "" { 588 return api.NewConfigResponse(apimodel.Code_InvalidConfigFileName) 589 } 590 return nil 591 }