github.com/polarismesh/polaris@v1.17.8/apiserver/httpserver/config/console_access.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  	"net/http"
    22  	"strings"
    23  
    24  	"github.com/emicklei/go-restful/v3"
    25  	"github.com/golang/protobuf/proto"
    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  
    30  	httpcommon "github.com/polarismesh/polaris/apiserver/httpserver/utils"
    31  	api "github.com/polarismesh/polaris/common/api/v1"
    32  	"github.com/polarismesh/polaris/common/utils"
    33  )
    34  
    35  // CreateConfigFileGroup 创建配置文件组
    36  func (h *HTTPServer) CreateConfigFileGroup(req *restful.Request, rsp *restful.Response) {
    37  	handler := &httpcommon.Handler{
    38  		Request:  req,
    39  		Response: rsp,
    40  	}
    41  
    42  	configFileGroup := &apiconfig.ConfigFileGroup{}
    43  	ctx, err := handler.Parse(configFileGroup)
    44  	requestId := ctx.Value(utils.StringContext("request-id"))
    45  
    46  	if err != nil {
    47  		configLog.Error("[Config][HttpServer] parse config file group from request error.",
    48  			zap.String("requestId", requestId.(string)),
    49  			zap.String("error", err.Error()))
    50  		handler.WriteHeaderAndProto(api.NewConfigFileGroupResponseWithMessage(apimodel.Code_ParseException, err.Error()))
    51  		return
    52  	}
    53  
    54  	handler.WriteHeaderAndProto(h.configServer.CreateConfigFileGroup(ctx, configFileGroup))
    55  }
    56  
    57  // QueryConfigFileGroups 查询配置文件组,group 模糊搜索
    58  func (h *HTTPServer) QueryConfigFileGroups(req *restful.Request, rsp *restful.Response) {
    59  	handler := &httpcommon.Handler{
    60  		Request:  req,
    61  		Response: rsp,
    62  	}
    63  
    64  	filter := httpcommon.ParseQueryParams(req)
    65  	response := h.configServer.QueryConfigFileGroups(handler.ParseHeaderContext(), filter)
    66  
    67  	handler.WriteHeaderAndProto(response)
    68  }
    69  
    70  // DeleteConfigFileGroup 删除配置文件组
    71  func (h *HTTPServer) DeleteConfigFileGroup(req *restful.Request, rsp *restful.Response) {
    72  	handler := &httpcommon.Handler{
    73  		Request:  req,
    74  		Response: rsp,
    75  	}
    76  
    77  	namespace := handler.Request.QueryParameter("namespace")
    78  	group := handler.Request.QueryParameter("group")
    79  
    80  	response := h.configServer.DeleteConfigFileGroup(handler.ParseHeaderContext(), namespace, group)
    81  	handler.WriteHeaderAndProto(response)
    82  }
    83  
    84  // UpdateConfigFileGroup 更新配置文件组,只能更新 comment
    85  func (h *HTTPServer) UpdateConfigFileGroup(req *restful.Request, rsp *restful.Response) {
    86  	handler := &httpcommon.Handler{
    87  		Request:  req,
    88  		Response: rsp,
    89  	}
    90  
    91  	configFileGroup := &apiconfig.ConfigFileGroup{}
    92  	ctx, err := handler.Parse(configFileGroup)
    93  	if err != nil {
    94  		configLog.Error("[Config][HttpServer] parse config file group from request error.",
    95  			utils.RequestID(ctx), zap.Error(err))
    96  		handler.WriteHeaderAndProto(api.NewConfigResponseWithInfo(apimodel.Code_ParseException, err.Error()))
    97  		return
    98  	}
    99  
   100  	handler.WriteHeaderAndProto(h.configServer.UpdateConfigFileGroup(ctx, configFileGroup))
   101  }
   102  
   103  // CreateConfigFile 创建配置文件
   104  func (h *HTTPServer) CreateConfigFile(req *restful.Request, rsp *restful.Response) {
   105  	handler := &httpcommon.Handler{
   106  		Request:  req,
   107  		Response: rsp,
   108  	}
   109  
   110  	configFile := &apiconfig.ConfigFile{}
   111  	ctx, err := handler.Parse(configFile)
   112  	if err != nil {
   113  		configLog.Error("[Config][HttpServer] parse config file from request error.",
   114  			utils.RequestID(ctx), zap.Error(err))
   115  		handler.WriteHeaderAndProto(api.NewConfigResponseWithInfo(apimodel.Code_ParseException, err.Error()))
   116  		return
   117  	}
   118  
   119  	handler.WriteHeaderAndProto(h.configServer.CreateConfigFile(ctx, configFile))
   120  }
   121  
   122  // GetConfigFile 获取单个配置文件
   123  func (h *HTTPServer) GetConfigFile(req *restful.Request, rsp *restful.Response) {
   124  	handler := &httpcommon.Handler{
   125  		Request:  req,
   126  		Response: rsp,
   127  	}
   128  
   129  	namespace := handler.Request.QueryParameter("namespace")
   130  	group := handler.Request.QueryParameter("group")
   131  	name := handler.Request.QueryParameter("name")
   132  
   133  	fileReq := &apiconfig.ConfigFile{
   134  		Namespace: utils.NewStringValue(namespace),
   135  		Group:     utils.NewStringValue(group),
   136  		Name:      utils.NewStringValue(name),
   137  	}
   138  
   139  	response := h.configServer.GetConfigFileRichInfo(handler.ParseHeaderContext(), fileReq)
   140  	handler.WriteHeaderAndProto(response)
   141  }
   142  
   143  // SearchConfigFile 按照 group 和 name 模糊搜索配置文件,按照 tag 搜索,多个tag之间或的关系
   144  func (h *HTTPServer) SearchConfigFile(req *restful.Request, rsp *restful.Response) {
   145  	handler := &httpcommon.Handler{
   146  		Request:  req,
   147  		Response: rsp,
   148  	}
   149  
   150  	filters := httpcommon.ParseQueryParams(req)
   151  	response := h.configServer.SearchConfigFile(handler.ParseHeaderContext(), filters)
   152  
   153  	handler.WriteHeaderAndProto(response)
   154  }
   155  
   156  // UpdateConfigFile 更新配置文件
   157  func (h *HTTPServer) UpdateConfigFile(req *restful.Request, rsp *restful.Response) {
   158  	handler := &httpcommon.Handler{
   159  		Request:  req,
   160  		Response: rsp,
   161  	}
   162  
   163  	configFile := &apiconfig.ConfigFile{}
   164  	ctx, err := handler.Parse(configFile)
   165  	if err != nil {
   166  		configLog.Error("[Config][HttpServer] parse config file from request error.",
   167  			utils.RequestID(ctx), zap.Error(err))
   168  		handler.WriteHeaderAndProto(api.NewConfigResponseWithInfo(apimodel.Code_ParseException, err.Error()))
   169  		return
   170  	}
   171  
   172  	handler.WriteHeaderAndProto(h.configServer.UpdateConfigFile(ctx, configFile))
   173  }
   174  
   175  // DeleteConfigFile 删除单个配置文件,删除配置文件也会删除配置文件发布内容,客户端将获取不到配置文件
   176  func (h *HTTPServer) DeleteConfigFile(req *restful.Request, rsp *restful.Response) {
   177  	handler := &httpcommon.Handler{
   178  		Request:  req,
   179  		Response: rsp,
   180  	}
   181  
   182  	namespace := handler.Request.QueryParameter("namespace")
   183  	group := handler.Request.QueryParameter("group")
   184  	name := handler.Request.QueryParameter("name")
   185  
   186  	fileReq := &apiconfig.ConfigFile{
   187  		Namespace: utils.NewStringValue(namespace),
   188  		Group:     utils.NewStringValue(group),
   189  		Name:      utils.NewStringValue(name),
   190  	}
   191  
   192  	response := h.configServer.DeleteConfigFile(handler.ParseHeaderContext(), fileReq)
   193  	handler.WriteHeaderAndProto(response)
   194  }
   195  
   196  // BatchDeleteConfigFile 批量删除配置文件
   197  func (h *HTTPServer) BatchDeleteConfigFile(req *restful.Request, rsp *restful.Response) {
   198  	handler := &httpcommon.Handler{
   199  		Request:  req,
   200  		Response: rsp,
   201  	}
   202  
   203  	var configFiles ConfigFileArr
   204  	ctx, err := handler.ParseArray(func() proto.Message {
   205  		msg := &apiconfig.ConfigFile{}
   206  		configFiles = append(configFiles, msg)
   207  		return msg
   208  	})
   209  	if err != nil {
   210  		handler.WriteHeaderAndProto(api.NewBatchWriteResponseWithMsg(apimodel.Code_ParseException, err.Error()))
   211  		return
   212  	}
   213  
   214  	response := h.configServer.BatchDeleteConfigFile(ctx, configFiles)
   215  	handler.WriteHeaderAndProto(response)
   216  }
   217  
   218  // ExportConfigFile 导出配置文件
   219  func (h *HTTPServer) ExportConfigFile(req *restful.Request, rsp *restful.Response) {
   220  	handler := &httpcommon.Handler{
   221  		Request:  req,
   222  		Response: rsp,
   223  	}
   224  
   225  	configFileExport := &apiconfig.ConfigFileExportRequest{}
   226  	ctx, err := handler.Parse(configFileExport)
   227  	if err != nil {
   228  		handler.WriteHeaderAndProto(api.NewBatchWriteResponseWithMsg(apimodel.Code_ParseException, err.Error()))
   229  		return
   230  	}
   231  	response := h.configServer.ExportConfigFile(ctx, configFileExport)
   232  	if response.Code.Value != api.ExecuteSuccess {
   233  		handler.WriteHeaderAndProto(response)
   234  	} else {
   235  		handler.WriteHeader(api.ExecuteSuccess, http.StatusOK)
   236  		handler.Response.AddHeader("Content-Type", "application/zip")
   237  		handler.Response.AddHeader("Content-Disposition", "attachment; filename=config.zip")
   238  		if _, err := handler.Response.ResponseWriter.Write(response.Data.Value); err != nil {
   239  			configLog.Error("[Config][HttpServer] response write error.",
   240  				utils.RequestID(ctx),
   241  				zap.String("error", err.Error()))
   242  		}
   243  	}
   244  }
   245  
   246  // ImportConfigFile 导入配置文件
   247  func (h *HTTPServer) ImportConfigFile(req *restful.Request, rsp *restful.Response) {
   248  	handler := &httpcommon.Handler{
   249  		Request:  req,
   250  		Response: rsp,
   251  	}
   252  
   253  	ctx := handler.ParseHeaderContext()
   254  	configFiles, err := handler.ParseFile()
   255  	if err != nil {
   256  		handler.WriteHeaderAndProto(api.NewResponseWithMsg(apimodel.Code_ParseException, err.Error()))
   257  		return
   258  	}
   259  	namespace := handler.Request.QueryParameter("namespace")
   260  	group := handler.Request.QueryParameter("group")
   261  	conflictHandling := handler.Request.QueryParameter("conflict_handling")
   262  
   263  	for _, file := range configFiles {
   264  		file.Namespace = utils.NewStringValue(namespace)
   265  		if group != "" {
   266  			file.Group = utils.NewStringValue(group)
   267  		}
   268  	}
   269  
   270  	var filenames []string
   271  	for _, file := range configFiles {
   272  		filenames = append(filenames, file.String())
   273  	}
   274  	configLog.Info("[Config][HttpServer]import config file",
   275  		zap.String("namespace", namespace),
   276  		zap.String("group", group),
   277  		zap.String("conflict_handling", conflictHandling),
   278  		zap.String("files", strings.Join(filenames, ",")),
   279  	)
   280  
   281  	response := h.configServer.ImportConfigFile(ctx, configFiles, conflictHandling)
   282  	handler.WriteHeaderAndProto(response)
   283  }
   284  
   285  // PublishConfigFile 发布配置文件
   286  func (h *HTTPServer) PublishConfigFile(req *restful.Request, rsp *restful.Response) {
   287  	handler := &httpcommon.Handler{
   288  		Request:  req,
   289  		Response: rsp,
   290  	}
   291  
   292  	configFile := &apiconfig.ConfigFileRelease{}
   293  	ctx, err := handler.Parse(configFile)
   294  	requestId := ctx.Value(utils.StringContext("request-id"))
   295  
   296  	if err != nil {
   297  		configLog.Error("[Config][HttpServer] parse config file release from request error.",
   298  			zap.String("requestId", requestId.(string)),
   299  			zap.String("error", err.Error()))
   300  		handler.WriteHeaderAndProto(api.NewConfigFileReleaseResponseWithMessage(apimodel.Code_ParseException, err.Error()))
   301  		return
   302  	}
   303  
   304  	handler.WriteHeaderAndProto(h.configServer.PublishConfigFile(ctx, configFile))
   305  }
   306  
   307  // RollbackConfigFileReleases 获取配置文件最后一次发布内容
   308  func (h *HTTPServer) RollbackConfigFileReleases(req *restful.Request, rsp *restful.Response) {
   309  	handler := &httpcommon.Handler{
   310  		Request:  req,
   311  		Response: rsp,
   312  	}
   313  
   314  	var releases []*apiconfig.ConfigFileRelease
   315  	ctx, err := handler.ParseArray(func() proto.Message {
   316  		msg := &apiconfig.ConfigFileRelease{}
   317  		releases = append(releases, msg)
   318  		return msg
   319  	})
   320  	if err != nil {
   321  		handler.WriteHeaderAndProto(api.NewBatchWriteResponseWithMsg(apimodel.Code_ParseException, err.Error()))
   322  		return
   323  	}
   324  	response := h.configServer.RollbackConfigFileReleases(ctx, releases)
   325  
   326  	handler.WriteHeaderAndProto(response)
   327  }
   328  
   329  // DeleteConfigFileReleases
   330  func (h *HTTPServer) DeleteConfigFileReleases(req *restful.Request, rsp *restful.Response) {
   331  	handler := &httpcommon.Handler{
   332  		Request:  req,
   333  		Response: rsp,
   334  	}
   335  
   336  	var releases []*apiconfig.ConfigFileRelease
   337  	ctx, err := handler.ParseArray(func() proto.Message {
   338  		msg := &apiconfig.ConfigFileRelease{}
   339  		releases = append(releases, msg)
   340  		return msg
   341  	})
   342  	if err != nil {
   343  		handler.WriteHeaderAndProto(api.NewBatchWriteResponseWithMsg(apimodel.Code_ParseException, err.Error()))
   344  		return
   345  	}
   346  
   347  	response := h.configServer.DeleteConfigFileReleases(ctx, releases)
   348  	handler.WriteHeaderAndProto(response)
   349  }
   350  
   351  // GetConfigFileReleaseVersions 获取配置文件最后一次发布内容
   352  func (h *HTTPServer) GetConfigFileReleaseVersions(req *restful.Request, rsp *restful.Response) {
   353  	handler := &httpcommon.Handler{
   354  		Request:  req,
   355  		Response: rsp,
   356  	}
   357  
   358  	queryParams := httpcommon.ParseQueryParams(req)
   359  	response := h.configServer.GetConfigFileReleaseVersions(handler.ParseHeaderContext(), queryParams)
   360  
   361  	handler.WriteHeaderAndProto(response)
   362  }
   363  
   364  // GetConfigFileReleases 获取配置文件最后一次发布内容
   365  func (h *HTTPServer) GetConfigFileReleases(req *restful.Request, rsp *restful.Response) {
   366  	handler := &httpcommon.Handler{
   367  		Request:  req,
   368  		Response: rsp,
   369  	}
   370  
   371  	queryParams := httpcommon.ParseQueryParams(req)
   372  	response := h.configServer.GetConfigFileReleases(handler.ParseHeaderContext(), queryParams)
   373  
   374  	handler.WriteHeaderAndProto(response)
   375  }
   376  
   377  // GetConfigFileRelease 获取配置文件最后一次发布内容
   378  func (h *HTTPServer) GetConfigFileRelease(req *restful.Request, rsp *restful.Response) {
   379  	handler := &httpcommon.Handler{
   380  		Request:  req,
   381  		Response: rsp,
   382  	}
   383  
   384  	namespace := handler.Request.QueryParameter("namespace")
   385  	group := handler.Request.QueryParameter("group")
   386  	fileName := handler.Request.QueryParameter("file_name")
   387  	name := handler.Request.QueryParameter("release_name")
   388  	// 兼容旧的查询参数
   389  	if fileName == "" {
   390  		fileName = handler.Request.QueryParameter("name")
   391  	}
   392  
   393  	fileReq := &apiconfig.ConfigFileRelease{
   394  		Namespace: utils.NewStringValue(namespace),
   395  		Group:     utils.NewStringValue(group),
   396  		FileName:  utils.NewStringValue(fileName),
   397  		Name:      utils.NewStringValue(name),
   398  	}
   399  
   400  	response := h.configServer.GetConfigFileRelease(handler.ParseHeaderContext(), fileReq)
   401  	handler.WriteHeaderAndProto(response)
   402  }
   403  
   404  // GetConfigFileReleaseHistory 获取配置文件发布历史,按照发布时间倒序排序
   405  func (h *HTTPServer) GetConfigFileReleaseHistory(req *restful.Request, rsp *restful.Response) {
   406  	handler := &httpcommon.Handler{
   407  		Request:  req,
   408  		Response: rsp,
   409  	}
   410  
   411  	filters := httpcommon.ParseQueryParams(req)
   412  	response := h.configServer.GetConfigFileReleaseHistories(handler.ParseHeaderContext(), filters)
   413  
   414  	handler.WriteHeaderAndProto(response)
   415  }
   416  
   417  // GetAllConfigFileTemplates get all config file template
   418  func (h *HTTPServer) GetAllConfigFileTemplates(req *restful.Request, rsp *restful.Response) {
   419  	handler := &httpcommon.Handler{
   420  		Request:  req,
   421  		Response: rsp,
   422  	}
   423  
   424  	response := h.configServer.GetAllConfigFileTemplates(handler.ParseHeaderContext())
   425  
   426  	handler.WriteHeaderAndProto(response)
   427  }
   428  
   429  // CreateConfigFileTemplate create config file template
   430  func (h *HTTPServer) CreateConfigFileTemplate(req *restful.Request, rsp *restful.Response) {
   431  	handler := &httpcommon.Handler{
   432  		Request:  req,
   433  		Response: rsp,
   434  	}
   435  
   436  	configFileTemplate := &apiconfig.ConfigFileTemplate{}
   437  	ctx, err := handler.Parse(configFileTemplate)
   438  	requestId := ctx.Value(utils.StringContext("request-id"))
   439  
   440  	if err != nil {
   441  		configLog.Error("[Config][HttpServer] parse config file template from request error.",
   442  			zap.String("requestId", requestId.(string)),
   443  			zap.String("error", err.Error()))
   444  		handler.WriteHeaderAndProto(api.NewConfigFileTemplateResponseWithMessage(apimodel.Code_ParseException, err.Error()))
   445  		return
   446  	}
   447  
   448  	handler.WriteHeaderAndProto(h.configServer.CreateConfigFileTemplate(ctx, configFileTemplate))
   449  }
   450  
   451  // GetAllConfigEncryptAlgorithm get all config encrypt algorithm
   452  func (h *HTTPServer) GetAllConfigEncryptAlgorithms(req *restful.Request, rsp *restful.Response) {
   453  	handler := &httpcommon.Handler{
   454  		Request:  req,
   455  		Response: rsp,
   456  	}
   457  	response := h.configServer.GetAllConfigEncryptAlgorithms(handler.ParseHeaderContext())
   458  	configLog.Info("response",
   459  		zap.Uint32("code", response.GetCode().GetValue()),
   460  	)
   461  	handler.WriteHeaderAndProto(response)
   462  }
   463  
   464  // UpsertAndReleaseConfigFile
   465  func (h *HTTPServer) UpsertAndReleaseConfigFile(req *restful.Request, rsp *restful.Response) {
   466  	handler := &httpcommon.Handler{
   467  		Request:  req,
   468  		Response: rsp,
   469  	}
   470  
   471  	configFile := &apiconfig.ConfigFilePublishInfo{}
   472  	ctx, err := handler.Parse(configFile)
   473  	if err != nil {
   474  		configLog.Error("[Config][HttpServer] parse config file from request error.",
   475  			utils.RequestID(ctx), zap.String("error", err.Error()))
   476  		handler.WriteHeaderAndProto(api.NewConfigResponseWithInfo(apimodel.Code_ParseException, err.Error()))
   477  		return
   478  	}
   479  
   480  	handler.WriteHeaderAndProto(h.configServer.UpsertAndReleaseConfigFile(ctx, configFile))
   481  }