From 7a43567969bcbedc154206bc320112f73e52524d Mon Sep 17 00:00:00 2001 From: kv Date: Sat, 11 Jul 2020 10:02:44 +0800 Subject: [PATCH] add: Determine duplicate names api for route & upstream --- api/errno/error.go | 30 +++++++++++---------- api/route/route.go | 35 +++++++++++++++++++++++++ api/route/upstream.go | 58 +++++++++++++++++++++++++++++++++++++++++ api/service/upstream.go | 14 ++++++++++ 4 files changed, 123 insertions(+), 14 deletions(-) diff --git a/api/errno/error.go b/api/errno/error.go index 2c3917dd86..24bb5a3067 100644 --- a/api/errno/error.go +++ b/api/errno/error.go @@ -43,13 +43,14 @@ var ( ConfFilePathError = Message{"010102", "Error loading configuration file: %s"} // BB 02 route module - RouteRequestError = Message{"010201", "Route request parameters are abnormal: %s"} - ApisixRouteCreateError = Message{"010202", "Failed to create APISIX route: %s"} - DBRouteCreateError = Message{"010203", "Route storage failure: %s"} - ApisixRouteUpdateError = Message{"010204", "Update APISIX routing failed: %s"} - ApisixRouteDeleteError = Message{"010205", "Failed to remove APISIX route: %s"} - DBRouteUpdateError = Message{"010206", "Route update failed: %s"} - DBRouteDeleteError = Message{"010207", "Route remove failed: %s"} + RouteRequestError = Message{"010201", "Route request parameters are abnormal: %s"} + ApisixRouteCreateError = Message{"010202", "Failed to create APISIX route: %s"} + DBRouteCreateError = Message{"010203", "Route storage failure: %s"} + ApisixRouteUpdateError = Message{"010204", "Update APISIX routing failed: %s"} + ApisixRouteDeleteError = Message{"010205", "Failed to remove APISIX route: %s"} + DBRouteUpdateError = Message{"010206", "Route update failed: %s"} + DBRouteDeleteError = Message{"010207", "Route remove failed: %s"} + DBRouteReduplicateError = Message{"010208", "Route name is reduplicate : %s"} // 03 plugin module ApisixPluginListError = Message{"010301", "List APISIX plugins failed: %s"} @@ -62,13 +63,14 @@ var ( ApisixSslDeleteError = Message{"010404", "Delete APISIX SSL failed"} // 06 upstream - UpstreamRequestError = Message{"010601", "upstream request parameters are abnormal: %s"} - UpstreamTransError = Message{"010602", "upstream parameter conversion is abnormal: %s"} - DBUpstreamError = Message{"010603", "upstream storage failure: %s"} - ApisixUpstreamCreateError = Message{"010604", "apisix upstream create failure: %s"} - ApisixUpstreamUpdateError = Message{"010605", "apisix upstream update failure: %s"} - ApisixUpstreamDeleteError = Message{"010606", "apisix upstream delete failure: %s"} - DBUpstreamDeleteError = Message{"010607", "upstream delete failure: %s"} + UpstreamRequestError = Message{"010601", "upstream request parameters are abnormal: %s"} + UpstreamTransError = Message{"010602", "upstream parameter conversion is abnormal: %s"} + DBUpstreamError = Message{"010603", "upstream storage failure: %s"} + ApisixUpstreamCreateError = Message{"010604", "apisix upstream create failure: %s"} + ApisixUpstreamUpdateError = Message{"010605", "apisix upstream update failure: %s"} + ApisixUpstreamDeleteError = Message{"010606", "apisix upstream delete failure: %s"} + DBUpstreamDeleteError = Message{"010607", "upstream delete failure: %s"} + DBUpstreamReduplicateError = Message{"010608", "Upstream name is reduplicate : %s"} ApisixConsumerCreateError = Message{"010702", "Create APISIX Consumer failed"} ApisixConsumerUpdateError = Message{"010703", "Update APISIX Consumer failed"} diff --git a/api/route/route.go b/api/route/route.go index 82d5106a4f..98ac001999 100644 --- a/api/route/route.go +++ b/api/route/route.go @@ -34,9 +34,44 @@ func AppendRoute(r *gin.Engine) *gin.Engine { r.GET("/apisix/admin/routes", listRoute) r.PUT("/apisix/admin/routes/:rid", updateRoute) r.DELETE("/apisix/admin/routes/:rid", deleteRoute) + r.GET("/apisix/admin/notexist/routes", isRouteExist) return r } +func isRouteExist(c *gin.Context) { + if name, exist := c.GetQuery("name"); exist { + db := conf.DB() + db = db.Table("routes") + exclude, exist := c.GetQuery("exclude") + if exist { + db = db.Where("name=? and id<>?", name, exclude) + } else { + db = db.Where("name=?", name) + } + var count int + err := db.Count(&count).Error + if err != nil { + e := errno.FromMessage(errno.RouteRequestError, err.Error()) + logger.Error(e.Msg) + c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response()) + return + } else { + if count == 0 { + c.Data(http.StatusOK, service.ContentType, errno.Success()) + return + } else { + e := errno.FromMessage(errno.DBRouteReduplicateError, name) + c.AbortWithStatusJSON(http.StatusBadRequest, e.Response()) + return + } + } + } else { + e := errno.FromMessage(errno.RouteRequestError, "name is needed") + c.AbortWithStatusJSON(http.StatusBadRequest, e.Response()) + return + } +} + func listRoute(c *gin.Context) { db := conf.DB() size, _ := strconv.Atoi(c.Query("size")) diff --git a/api/route/upstream.go b/api/route/upstream.go index 263b8bebdb..17dae490c3 100644 --- a/api/route/upstream.go +++ b/api/route/upstream.go @@ -17,11 +17,69 @@ func AppendUpstream(r *gin.Engine) *gin.Engine { r.POST("/apisix/admin/upstreams", createUpstream) r.GET("/apisix/admin/upstreams/:uid", findUpstream) r.GET("/apisix/admin/upstreams", listUpstream) + r.GET("/apisix/admin/names/upstreams", listUpstreamName) r.PUT("/apisix/admin/upstreams/:uid", updateUpstream) r.DELETE("/apisix/admin/upstreams/:uid", deleteUpstream) + r.GET("/apisix/admin/notexist/upstreams", isUpstreamExist) return r } +func isUpstreamExist(c *gin.Context) { + if name, exist := c.GetQuery("name"); exist { + db := conf.DB() + db = db.Table("upstreams") + exclude, exist := c.GetQuery("exclude") + if exist { + db = db.Where("name=? and id<>?", name, exclude) + } else { + db = db.Where("name=?", name) + } + var count int + if err := db.Count(&count).Error; err != nil { + e := errno.FromMessage(errno.UpstreamRequestError, err.Error()) + logger.Error(e.Msg) + c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response()) + return + } else { + if count == 0 { + c.Data(http.StatusOK, service.ContentType, errno.Success()) + return + } else { + e := errno.FromMessage(errno.DBUpstreamReduplicateError, name) + c.AbortWithStatusJSON(http.StatusBadRequest, e.Response()) + return + } + } + } else { + e := errno.FromMessage(errno.UpstreamRequestError, "name is needed") + c.AbortWithStatusJSON(http.StatusBadRequest, e.Response()) + return + } +} + +func listUpstreamName(c *gin.Context) { + db := conf.DB() + upstreamList := []service.UpstreamDao{} + var count int + if err := db.Order("name").Table("upstreams").Find(&upstreamList).Count(&count).Error; err != nil { + e := errno.FromMessage(errno.UpstreamRequestError, err.Error()) + logger.Error(e.Msg) + c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response()) + return + } else { + responseList := make([]*service.UpstreamNameResponse, 0) + for _, r := range upstreamList { + response, err := r.Parse2NameResponse() + if err == nil { + responseList = append(responseList, response) + } + } + result := &service.ListResponse{Count: count, Data: responseList} + resp, _ := json.Marshal(result) + c.Data(http.StatusOK, service.ContentType, resp) + } +} + func createUpstream(c *gin.Context) { u4 := uuid.NewV4() uid := u4.String() diff --git a/api/service/upstream.go b/api/service/upstream.go index 0302ea9c18..4274ad9300 100644 --- a/api/service/upstream.go +++ b/api/service/upstream.go @@ -72,6 +72,20 @@ type UpstreamResponse struct { Upstream } +type UpstreamNameResponse struct { + ID string `json:"id"` + Name string `json:"name"` +} + +func (u *UpstreamDao) Parse2NameResponse() (*UpstreamNameResponse, error) { + // upstream + unr := &UpstreamNameResponse{ + ID: u.ID.String(), + Name: u.Name, + } + return unr, nil +} + func (u *UpstreamDao) Parse2Response() (*UpstreamResponse, error) { // upstream aur := &ApisixUpstreamResponse{}