You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by ju...@apache.org on 2020/10/15 02:04:35 UTC
[apisix-dashboard] branch refactor updated: feature: refactor
plugin api and auth api (#556)
This is an automated email from the ASF dual-hosted git repository.
juzhiyuan pushed a commit to branch refactor
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
The following commit(s) were added to refs/heads/refactor by this push:
new 03d39f8 feature: refactor plugin api and auth api (#556)
03d39f8 is described below
commit 03d39f8490adb3e6762c567e9733152fa1c68752
Author: nic-chen <33...@users.noreply.github.com>
AuthorDate: Thu Oct 15 10:04:27 2020 +0800
feature: refactor plugin api and auth api (#556)
* feat: refactor plugin and healthy api
* feat: refactor authentication api
* fix: remove useless files
* chore: update json schema
* test: add login test
* test: add test for plugin
* fix: license
---
api/conf/conf.go | 40 +-
api/conf/schema.json | 2 +-
api/errno/error.go | 170 ------
api/filter/authentication.go | 24 +-
api/filter/logging.go | 5 +-
.../handler/authentication/authentication.go | 78 +++
.../handler/authentication/authentication_test.go | 67 +++
api/internal/handler/handler.go | 4 +-
api/{route => internal/handler/healthz}/healthz.go | 28 +-
api/internal/handler/plugin/plugin.go | 65 +++
.../handler/plugin/plugin_test.go} | 70 +--
api/{route/base.go => internal/route.go} | 18 +-
api/main.go | 8 +-
api/route/authentication.go | 68 ---
api/route/authentication_test.go | 52 --
api/route/consumer.go | 143 -----
api/route/consumer_test.go | 88 ---
api/route/plugin.go | 59 --
api/route/route.go | 572 ------------------
api/route/route_group.go | 233 --------
api/route/route_test.go | 195 -------
api/route/ssl.go | 197 -------
api/route/ssl_test.go | 65 ---
api/route/upstream.go | 384 ------------
api/script/db/schema.sql | 71 ---
api/service/base.go | 49 --
api/service/consumer.go | 349 -----------
api/service/plugin.go | 62 --
api/service/route.go | 647 ---------------------
api/service/route_group.go | 155 -----
api/service/ssl.go | 589 -------------------
api/service/upstream.go | 271 ---------
api/utils/copy.go | 41 --
api/utils/http.go | 114 ----
34 files changed, 319 insertions(+), 4664 deletions(-)
diff --git a/api/conf/conf.go b/api/conf/conf.go
index bda5bdb..66079b5 100644
--- a/api/conf/conf.go
+++ b/api/conf/conf.go
@@ -19,6 +19,7 @@ package conf
import (
"fmt"
"io/ioutil"
+ "math/rand"
"os"
"path/filepath"
"runtime"
@@ -137,23 +138,36 @@ func initApisix() {
}
}
+func randomString(n int) string {
+ var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
+ b := make([]rune, n)
+ for i := range b {
+ b[i] = letters[rand.Intn(len(letters))]
+ }
+ return string(b)
+}
+
func initAuthentication() {
filePath := configurationPath()
- if configurationContent, err := ioutil.ReadFile(filePath); err != nil {
+ configurationContent, err := ioutil.ReadFile(filePath)
+ if err != nil {
panic(fmt.Sprintf("fail to read configuration: %s", filePath))
- } else {
- configuration := gjson.ParseBytes(configurationContent)
- userList := configuration.Get("authentication.user").Array()
-
- // create user list
- for _, item := range userList {
- username := item.Map()["username"].String()
- password := item.Map()["password"].String()
- UserList[item.Map()["username"].String()] = user{Username: username, Password: password}
- }
- AuthenticationConfig.Session.Secret = configuration.Get("authentication.session.secret").String()
- AuthenticationConfig.Session.ExpireTime = configuration.Get("authentication.session.expireTime").Uint()
}
+
+ configuration := gjson.ParseBytes(configurationContent)
+ userList := configuration.Get("authentication.user").Array()
+ // create user list
+ for _, item := range userList {
+ username := item.Map()["username"].String()
+ password := item.Map()["password"].String()
+ UserList[item.Map()["username"].String()] = user{Username: username, Password: password}
+ }
+ AuthenticationConfig.Session.Secret = configuration.Get("authentication.session.secret").String()
+ if "secret" == AuthenticationConfig.Session.Secret {
+ AuthenticationConfig.Session.Secret = randomString(10)
+ }
+
+ AuthenticationConfig.Session.ExpireTime = configuration.Get("authentication.session.expireTime").Uint()
}
func initSchema() {
diff --git a/api/conf/schema.json b/api/conf/schema.json
index bf606b5..087cf4c 100644
--- a/api/conf/schema.json
+++ b/api/conf/schema.json
@@ -1 +1 @@
-{"plugins":{"serverless-post-function":{"type":"object","properties":{"phase":{"type":"string","enum":["rewrite","access","header_filter","body_filter","log","balancer"]},"functions":{"type":"array","items":{"type":"string"},"minItems":1}},"required":["functions"]},"prometheus":{"type":"object","additionalProperties":false},"syslog":{"type":"object","properties":{"port":{"type":"integer"},"flush_limit":{"type":"integer","default":4096,"minimum":1},"name":{"type":"string","default":"sys l [...]
+{"main":{"upstream_hash_header_schema":{"type":"string","pattern":"^[a-zA-Z0-9-_]+$"},"stream_route":{"type":"object","properties":{"plugins":{"type":"object"},"id":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9-_]+$"},{"type":"integer","minimum":1}]},"remote_addr":{"type":"string","anyOf":[{"title":"IPv4","type":"string","pattern":"^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"},{"title":"IPv4/CIDR","type":"string","pattern":"^[0-9]{1,3}.[0-9]{1,3}.[0-9]{ [...]
diff --git a/api/errno/error.go b/api/errno/error.go
deleted file mode 100644
index 0c18dec..0000000
--- a/api/errno/error.go
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 errno
-
-import (
- "encoding/json"
- "fmt"
-)
-
-type Message struct {
- Code string
- Msg string `json:"message"`
- Status int `json:"-"`
-}
-
-var (
- //AA 01 api-manager-api
- //BB 00 system
- SystemSuccess = Message{"010000", "success", 200}
- SystemError = Message{"010001", "system error", 500}
- BadRequestError = Message{"010002", "Request format error", 400}
- NotFoundError = Message{"010003", "No resources found", 404}
- InvalidParam = Message{"010004", "Request parameter error", 400}
- DBWriteError = Message{"010005", "Database save failed", 500}
- DBReadError = Message{"010006", "Database query failed", 500}
- DBDeleteError = Message{"010007", "Database delete failed", 500}
- RecordNotExist = Message{"010009", "Record does not exist", 404}
- InvalidParamDetail = Message{"010010", "Invalid request parameter: %s", 400}
- AdminApiSaveError = Message{"010011", "Data save failed", 500}
- SchemaCheckFailed = Message{"010012", "%s", 400}
- ForbiddenError = Message{"010013", "Request Unauthorized", 401}
-
- //BB 01 configuration
- ConfEnvError = Message{"010101", "Environment variable not found: %s", 500}
- ConfFilePathError = Message{"010102", "Error loading configuration file: %s", 500}
-
- // BB 02 route
- RouteRequestError = Message{"010201", "Route request parameters are abnormal: %s", 400}
- ApisixRouteCreateError = Message{"010202", "Failed to create APISIX route: %s", 500}
- DBRouteCreateError = Message{"010203", "Route storage failure: %s", 500}
- ApisixRouteUpdateError = Message{"010204", "Update APISIX routing failed: %s", 500}
- ApisixRouteDeleteError = Message{"010205", "Failed to delete APISIX route: %s", 500}
- DBRouteUpdateError = Message{"010206", "Route update failed: %s", 500}
- DBRouteDeleteError = Message{"010207", "Route deletion failed: %s", 500}
- DBRouteReduplicateError = Message{"010208", "Route name is reduplicate : %s", 400}
- SetRouteUngroupError = Message{"010209", "Set route ungroup err", 500}
- RoutePublishError = Message{"010209", "Route publish error", 400}
-
- // 03 plugins
- ApisixPluginListError = Message{"010301", "find APISIX plugin list failed: %s", 500}
- ApisixPluginSchemaError = Message{"010301", "find APISIX plugin schema failed: %s", 500}
-
- // 04 ssl
- SslParseError = Message{"010401", "Certificate resolution failed: %s", 400}
- ApisixSslCreateError = Message{"010402", "Failed to create APISIX SSL", 500}
- ApisixSslUpdateError = Message{"010403", "Failed to update APISIX SSL", 500}
- ApisixSslDeleteError = Message{"010404", "Failed to delete APISIX SSL", 500}
- SslForSniNotExists = Message{"010407", "Ssl for sni not exists:%s", 400}
- DuplicateSslCert = Message{"010408", "Duplicate ssl cert", 400}
-
- // 06 upstream
- UpstreamRequestError = Message{"010601", "upstream request parameters exception: %s", 400}
- UpstreamTransError = Message{"010602", "Abnormal upstream parameter conversion: %s", 400}
- DBUpstreamError = Message{"010603", "upstream storage failure: %s", 500}
- ApisixUpstreamCreateError = Message{"010604", "apisix upstream create failed: %s", 500}
- ApisixUpstreamUpdateError = Message{"010605", "apisix upstream update failed: %s", 500}
- ApisixUpstreamDeleteError = Message{"010606", "apisix upstream delete failed: %s", 500}
- DBUpstreamDeleteError = Message{"010607", "upstream storage delete failed: %s", 500}
- DBUpstreamReduplicateError = Message{"010608", "Upstream name is reduplicate : %s", 500}
-
- // 07 consumer
- ApisixConsumerCreateError = Message{"010702", "APISIX Consumer create failed", 500}
- ApisixConsumerUpdateError = Message{"010703", "APISIX Consumer update failed", 500}
- ApisixConsumerDeleteError = Message{"010704", "APISIX Consumer delete failed", 500}
- DuplicateUserName = Message{"010705", "Duplicate consumer username", 400}
-
- // 08 routeGroup
- RouteGroupRequestError = Message{"010801", "RouteGroup request parameters exception: %s", 400}
- DBRouteGroupError = Message{"010802", "RouteGroup storage failure: %s", 500}
- DBRouteGroupDeleteError = Message{"010803", "RouteGroup storage delete failed: %s", 500}
- RouteGroupHasRoutesError = Message{"010804", "Route exist in this route group ", 500}
- RouteGroupSelectRoutesError = Message{"010805", "RouteGroup select routes failed : %s", 500}
- DuplicateRouteGroupName = Message{"010806", "RouteGroup name is duplicate : %s", 500}
-
- // 99 authentication
- AuthenticationUserError = Message{"019901", "username or password error", 401}
-)
-
-type ManagerError struct {
- TraceId string
- Code string
- Status int
- Msg string
- Data interface{}
- Detail string
-}
-
-// toString
-func (e *ManagerError) Error() string {
- return e.Msg
-}
-
-func (e *ManagerError) ErrorDetail() string {
- return fmt.Sprintf("TraceId: %s, Code: %s, Msg: %s, Detail: %s", e.TraceId, e.Code, e.Msg, e.Detail)
-}
-
-func FromMessage(m Message, args ...interface{}) *ManagerError {
- return &ManagerError{TraceId: "", Code: m.Code, Status: m.Status, Msg: fmt.Sprintf(m.Msg, args...)}
-}
-
-func New(m Message, args ...interface{}) *ManagerError {
- return &ManagerError{TraceId: "", Code: m.Code, Msg: m.Msg, Status: m.Status, Detail: fmt.Sprintf("%s", args...)}
-}
-
-func (e *ManagerError) Response() map[string]interface{} {
- return map[string]interface{}{
- "code": e.Code,
- "message": e.Msg,
- }
-}
-
-func (e *ManagerError) ItemResponse(data interface{}) map[string]interface{} {
- return map[string]interface{}{
- "code": e.Code,
- "message": e.Msg,
- "data": data,
- }
-}
-
-func (e *ManagerError) ListResponse(count, list interface{}) map[string]interface{} {
- return map[string]interface{}{
- "code": e.Code,
- "message": e.Msg,
- "count": count,
- "list": list,
- }
-}
-
-func Success() []byte {
- w := FromMessage(SystemSuccess).Response()
- result, _ := json.Marshal(w)
- return result
-}
-
-func Succeed() map[string]interface{} {
- return FromMessage(SystemSuccess).Response()
-}
-
-type HttpError struct {
- Code int
- Msg Message
-}
-
-func (e *HttpError) Error() string {
- return e.Msg.Msg
-}
diff --git a/api/filter/authentication.go b/api/filter/authentication.go
index ad794af..caebd9a 100644
--- a/api/filter/authentication.go
+++ b/api/filter/authentication.go
@@ -17,12 +17,13 @@
package filter
import (
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/dgrijalva/jwt-go"
- "github.com/gin-gonic/gin"
"net/http"
"strings"
+
+ "github.com/dgrijalva/jwt-go"
+ "github.com/gin-gonic/gin"
+
+ "github.com/apisix/manager-api/conf"
)
func Authentication() gin.HandlerFunc {
@@ -35,29 +36,34 @@ func Authentication() gin.HandlerFunc {
return []byte(conf.AuthenticationConfig.Session.Secret), nil
})
+ errResp := gin.H{
+ "code": 010013,
+ "message": "Request Unauthorized",
+ }
+
if err != nil {
- c.AbortWithStatusJSON(http.StatusUnauthorized, errno.FromMessage(errno.ForbiddenError).Response())
+ c.AbortWithStatusJSON(http.StatusUnauthorized, errResp)
return
}
claims, ok := token.Claims.(*jwt.StandardClaims)
if !ok {
- c.AbortWithStatusJSON(http.StatusUnauthorized, errno.FromMessage(errno.ForbiddenError).Response())
+ c.AbortWithStatusJSON(http.StatusUnauthorized, errResp)
return
}
if err := token.Claims.Valid(); err != nil {
- c.AbortWithStatusJSON(http.StatusUnauthorized, errno.FromMessage(errno.ForbiddenError).Response())
+ c.AbortWithStatusJSON(http.StatusUnauthorized, errResp)
return
}
if claims.Subject == "" {
- c.AbortWithStatusJSON(http.StatusUnauthorized, errno.FromMessage(errno.ForbiddenError).Response())
+ c.AbortWithStatusJSON(http.StatusUnauthorized, errResp)
return
}
if _, ok := conf.UserList[claims.Subject]; !ok {
- c.AbortWithStatusJSON(http.StatusUnauthorized, errno.FromMessage(errno.ForbiddenError).Response())
+ c.AbortWithStatusJSON(http.StatusUnauthorized, errResp)
return
}
}
diff --git a/api/filter/logging.go b/api/filter/logging.go
index 6318d52..badf234 100644
--- a/api/filter/logging.go
+++ b/api/filter/logging.go
@@ -21,7 +21,6 @@ import (
"io/ioutil"
"time"
- "github.com/apisix/manager-api/errno"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
@@ -60,9 +59,7 @@ func RequestLogHandler() gin.HandlerFunc {
}
var errs []string
for _, err := range c.Errors {
- if e, ok := err.Err.(*errno.ManagerError); ok {
- errs = append(errs, e.Error())
- }
+ errs = append(errs, err.Error())
}
logger.WithFields(logrus.Fields{
"requestId": uuid,
diff --git a/api/internal/handler/authentication/authentication.go b/api/internal/handler/authentication/authentication.go
new file mode 100644
index 0000000..5f3a83b
--- /dev/null
+++ b/api/internal/handler/authentication/authentication.go
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 authentication
+
+import (
+ "fmt"
+ "reflect"
+ "time"
+
+ "github.com/dgrijalva/jwt-go"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/wrapper"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/conf"
+ "github.com/apisix/manager-api/internal/handler"
+)
+
+type Handler struct {
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{}, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/user/login", wgin.Wraps(h.userLogin,
+ wrapper.InputType(reflect.TypeOf(LoginInput{}))))
+}
+
+type UserSession struct {
+ Token string `json:"token"`
+}
+
+type LoginInput struct {
+ Username string `json:"username" validate:"required"`
+ Password string `json:"password" validate:"required"`
+}
+
+func (h *Handler) userLogin(c droplet.Context) (interface{}, error) {
+ input := c.Input().(*LoginInput)
+ username := input.Username
+ password := input.Password
+
+ user := conf.UserList[username]
+ if username != user.Username || password != user.Password {
+ return nil, fmt.Errorf("username or password error")
+ }
+
+ // create JWT for session
+ claims := jwt.StandardClaims{
+ Subject: username,
+ IssuedAt: time.Now().Unix(),
+ ExpiresAt: time.Now().Add(time.Second * time.Duration(conf.AuthenticationConfig.Session.ExpireTime)).Unix(),
+ }
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+ signedToken, _ := token.SignedString([]byte(conf.AuthenticationConfig.Session.Secret))
+
+ // output token
+ return &UserSession{
+ Token: signedToken,
+ }, nil
+}
diff --git a/api/internal/handler/authentication/authentication_test.go b/api/internal/handler/authentication/authentication_test.go
new file mode 100644
index 0000000..01241a9
--- /dev/null
+++ b/api/internal/handler/authentication/authentication_test.go
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 authentication
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/shiningrush/droplet"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAuthentication(t *testing.T) {
+ // init
+ handler := &Handler{}
+ assert.NotNil(t, handler)
+
+ //login
+ input := &LoginInput{}
+ ctx := droplet.NewContext()
+ reqBody := `{
+ "username": "admin",
+ "password": "admin"
+ }`
+ json.Unmarshal([]byte(reqBody), input)
+ ctx.SetInput(input)
+ _, err := handler.userLogin(ctx)
+ assert.Nil(t, err)
+
+ //username error
+ input2 := &LoginInput{}
+ reqBody = `{
+ "username": "sdfasdf",
+ "password": "admin"
+ }`
+ json.Unmarshal([]byte(reqBody), input2)
+ ctx.SetInput(input2)
+ _, err = handler.userLogin(ctx)
+ assert.EqualError(t, err, "username or password error")
+
+ //password error
+ input3 := &LoginInput{}
+ reqBody = `{
+ "username": "admin",
+ "password": "admin9384938"
+ }`
+ json.Unmarshal([]byte(reqBody), input3)
+ ctx.SetInput(input3)
+ _, err = handler.userLogin(ctx)
+ assert.EqualError(t, err, "username or password error")
+
+}
diff --git a/api/internal/handler/handler.go b/api/internal/handler/handler.go
index 2736700..f1d653d 100644
--- a/api/internal/handler/handler.go
+++ b/api/internal/handler/handler.go
@@ -16,7 +16,9 @@
*/
package handler
-import "github.com/gin-gonic/gin"
+import (
+ "github.com/gin-gonic/gin"
+)
type RegisterFactory func() (RouteRegister, error)
diff --git a/api/route/healthz.go b/api/internal/handler/healthz/healthz.go
similarity index 65%
rename from api/route/healthz.go
rename to api/internal/handler/healthz/healthz.go
index 243ba5f..c35c860 100644
--- a/api/route/healthz.go
+++ b/api/internal/handler/healthz/healthz.go
@@ -14,25 +14,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package route
+package healthz
import (
- "net/http"
-
- "github.com/apisix/manager-api/log"
"github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/internal/handler"
)
-var logger = log.GetLogger()
+type Handler struct {
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{}, nil
+}
-func healthzHandler() gin.HandlerFunc {
- return func(c *gin.Context) {
- c.Copy()
- c.String(http.StatusOK, "pong")
- }
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.GET("/ping", wgin.Wraps(h.healthZHandler))
}
-func AppendHealthCheck(r *gin.Engine) *gin.Engine {
- r.GET("/ping", healthzHandler())
- return r
+func (h *Handler) healthZHandler(c droplet.Context) (interface{}, error) {
+ return "pong", nil
}
diff --git a/api/internal/handler/plugin/plugin.go b/api/internal/handler/plugin/plugin.go
new file mode 100644
index 0000000..354c562
--- /dev/null
+++ b/api/internal/handler/plugin/plugin.go
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 plugin
+
+import (
+ "reflect"
+
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/wrapper"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/conf"
+ "github.com/apisix/manager-api/internal/handler"
+)
+
+type Handler struct {
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{}, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.GET("/apisix/admin/plugins", wgin.Wraps(h.Plugins))
+ r.GET("/apisix/admin/schema/plugins/:name", wgin.Wraps(h.Schema,
+ wrapper.InputType(reflect.TypeOf(GetInput{}))))
+}
+
+type GetInput struct {
+ Name string `auto_read:"name,path" validate:"required"`
+}
+
+func (h *Handler) Schema(c droplet.Context) (interface{}, error) {
+ input := c.Input().(*GetInput)
+ ret := conf.Schema.Get("plugins." + input.Name).Value()
+ return ret, nil
+}
+
+func (h *Handler) Plugins(c droplet.Context) (interface{}, error) {
+ list := conf.Schema.Get("plugins").Map()
+
+ var ret []string
+ for pluginName, _ := range list {
+ if pluginName != "serverless-post-function" && pluginName != "serverless-pre-function" {
+ ret = append(ret, pluginName)
+ }
+ }
+
+ return ret, nil
+}
diff --git a/api/route/base_test.go b/api/internal/handler/plugin/plugin_test.go
similarity index 52%
rename from api/route/base_test.go
rename to api/internal/handler/plugin/plugin_test.go
index 838f4b7..d962a6a 100644
--- a/api/route/base_test.go
+++ b/api/internal/handler/plugin/plugin_test.go
@@ -14,43 +14,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package route
-import (
- "strings"
-
- "github.com/api7/apitest"
- dlog "github.com/shiningrush/droplet/log"
- "github.com/spf13/viper"
+package plugin
- "github.com/apisix/manager-api/internal/core/storage"
- "github.com/apisix/manager-api/internal/core/store"
- "github.com/apisix/manager-api/log"
-)
-
-var testHandler *apitest.APITest
+import (
+ "encoding/json"
+ "testing"
-var (
- uriPrefix = "/apisix/admin"
+ "github.com/shiningrush/droplet"
+ "github.com/stretchr/testify/assert"
)
-func init() {
- //init etcd
- viper.SetEnvPrefix("APIX")
- viper.AutomaticEnv()
- dlog.DefLogger = log.DefLogger{}
-
- if err := storage.InitETCDClient(strings.Split(viper.GetString("etcd_endpoints"), ",")); err != nil {
- panic(err)
- }
-
- if err := store.InitStores(); err != nil {
- panic(err)
- }
-
- r := SetUpRouter()
-
- testHandler = apitest.
- New().
- Handler(r)
+func TestPlugin(t *testing.T) {
+ // init
+ handler := &Handler{}
+ assert.NotNil(t, handler)
+
+ //plugin list
+ ctx := droplet.NewContext()
+ list, err := handler.Plugins(ctx)
+ assert.Nil(t, err)
+ assert.Contains(t, list.([]string), "limit-count")
+
+ //schema
+ input := &GetInput{}
+ reqBody := `{
+ "name": "limit-count"
+ }`
+ json.Unmarshal([]byte(reqBody), input)
+ ctx.SetInput(input)
+ val, _ := handler.Schema(ctx)
+ assert.NotNil(t, val)
+
+ //not exists
+ input2 := &GetInput{}
+ reqBody = `{
+ "name": "not-exists"
+ }`
+ json.Unmarshal([]byte(reqBody), input2)
+ ctx.SetInput(input2)
+ val, _ = handler.Schema(ctx)
+ assert.Nil(t, val)
}
diff --git a/api/route/base.go b/api/internal/route.go
similarity index 88%
rename from api/route/base.go
rename to api/internal/route.go
index 979e750..9814620 100644
--- a/api/route/base.go
+++ b/api/internal/route.go
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package route
+package internal
import (
"github.com/gin-contrib/pprof"
@@ -25,7 +25,10 @@ import (
"github.com/apisix/manager-api/conf"
"github.com/apisix/manager-api/filter"
"github.com/apisix/manager-api/internal/handler"
+ "github.com/apisix/manager-api/internal/handler/authentication"
"github.com/apisix/manager-api/internal/handler/consumer"
+ "github.com/apisix/manager-api/internal/handler/healthz"
+ "github.com/apisix/manager-api/internal/handler/plugin"
"github.com/apisix/manager-api/internal/handler/route"
"github.com/apisix/manager-api/internal/handler/service"
"github.com/apisix/manager-api/internal/handler/ssl"
@@ -43,22 +46,17 @@ func SetUpRouter() *gin.Engine {
r.Use(sessions.Sessions("session", store))
r.Use(filter.CORS(), filter.Authentication(), filter.RequestId(), filter.RecoverHandler())
- AppendHealthCheck(r)
- AppendAuthentication(r)
- //AppendRoute(r)
- //AppendSsl(r)
- AppendPlugin(r)
- //AppendUpstream(r)
- //AppendConsumer(r)
- AppendRouteGroup(r)
-
factories := []handler.RegisterFactory{
route.NewHandler,
ssl.NewHandler,
consumer.NewHandler,
upstream.NewHandler,
service.NewHandler,
+ plugin.NewHandler,
+ healthz.NewHandler,
+ authentication.NewHandler,
}
+
for i := range factories {
h, err := factories[i]()
if err != nil {
diff --git a/api/main.go b/api/main.go
index 937243e..74b3a12 100644
--- a/api/main.go
+++ b/api/main.go
@@ -18,19 +18,19 @@ package main
import (
"fmt"
- "github.com/spf13/viper"
"net/http"
"strings"
"time"
dlog "github.com/shiningrush/droplet/log"
+ "github.com/spf13/viper"
"github.com/apisix/manager-api/conf"
+ "github.com/apisix/manager-api/internal"
"github.com/apisix/manager-api/internal/core/storage"
"github.com/apisix/manager-api/internal/core/store"
"github.com/apisix/manager-api/internal/utils"
"github.com/apisix/manager-api/log"
- "github.com/apisix/manager-api/route"
)
var logger = log.GetLogger()
@@ -47,10 +47,8 @@ func main() {
panic(err)
}
- // init
- //conf.InitializeMysql()
// routes
- r := route.SetUpRouter()
+ r := internal.SetUpRouter()
addr := fmt.Sprintf(":%d", conf.ServerPort)
s := &http.Server{
Addr: addr,
diff --git a/api/route/authentication.go b/api/route/authentication.go
deleted file mode 100644
index 9284dc1..0000000
--- a/api/route/authentication.go
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- jwt "github.com/dgrijalva/jwt-go"
- "github.com/gin-gonic/gin"
- "net/http"
- "time"
-)
-
-type UserSession struct {
- Token string `json:"token"`
-}
-
-func AppendAuthentication(r *gin.Engine) *gin.Engine {
- r.POST("/apisix/admin/user/login", userLogin)
- return r
-}
-
-func userLogin(c *gin.Context) {
- username := c.PostForm("username")
- password := c.PostForm("password")
-
- if username == "" {
- c.AbortWithStatusJSON(http.StatusBadRequest, errno.FromMessage(errno.InvalidParamDetail, "username is needed").Response())
- return
- }
- if password == "" {
- c.AbortWithStatusJSON(http.StatusBadRequest, errno.FromMessage(errno.InvalidParamDetail, "password is needed").Response())
- return
- }
-
- user := conf.UserList[username]
- if username != user.Username || password != user.Password {
- c.AbortWithStatusJSON(http.StatusUnauthorized, errno.FromMessage(errno.AuthenticationUserError).Response())
- } else {
- // create JWT for session
- claims := jwt.StandardClaims{
- Subject: username,
- IssuedAt: time.Now().Unix(),
- ExpiresAt: time.Now().Add(time.Second * time.Duration(conf.AuthenticationConfig.Session.ExpireTime)).Unix(),
- }
- token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
- signedToken, _ := token.SignedString([]byte(conf.AuthenticationConfig.Session.Secret))
-
- // output token
- c.AbortWithStatusJSON(http.StatusOK, errno.FromMessage(errno.SystemSuccess).ItemResponse(&UserSession{
- Token: signedToken,
- }))
- }
-}
diff --git a/api/route/authentication_test.go b/api/route/authentication_test.go
deleted file mode 100644
index 952a689..0000000
--- a/api/route/authentication_test.go
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "bytes"
- "net/http"
- "strings"
- "testing"
-)
-
-var token string
-
-func TestUserLogin(t *testing.T) {
- // password error
- testHandler.
- Post("/apisix/admin/user/login").
- Header("Content-Type", "application/x-www-form-urlencoded").
- Body("username=admin&password=admin1").
- Expect(t).
- Status(http.StatusUnauthorized).
- End()
-
- // login success
- sessionResponse := testHandler.
- Post("/apisix/admin/user/login").
- Header("Content-Type", "application/x-www-form-urlencoded").
- Body("username=admin&password=admin").
- Expect(t).
- Status(http.StatusOK).
- End().Response.Body
-
- buf := new(bytes.Buffer)
- buf.ReadFrom(sessionResponse)
- data := buf.String()
- tokenArr := strings.Split(data, "\"token\":\"")
- token = strings.Split(tokenArr[1], "\"}")[0]
-}
diff --git a/api/route/consumer.go b/api/route/consumer.go
deleted file mode 100644
index 3f0bfa1..0000000
--- a/api/route/consumer.go
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "net/http"
- "strconv"
-
- "github.com/gin-gonic/gin"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/service"
- uuid "github.com/satori/go.uuid"
-)
-
-func AppendConsumer(r *gin.Engine) *gin.Engine {
-
- r.GET("/apisix/admin/consumers", consumerList)
- r.POST("/apisix/admin/consumers", consumerCreate)
- r.GET("/apisix/admin/consumers/:id", consumerItem)
- r.PUT("/apisix/admin/consumers/:id", consumerUpdate)
- r.DELETE("/apisix/admin/consumers/:id", consumerDelete)
-
- return r
-}
-
-func handleServiceError(c *gin.Context, requestId interface{}, err error) {
- if httpError, ok := err.(*errno.HttpError); ok {
- logger.WithField(conf.RequestId, requestId).Error(err)
- c.AbortWithStatusJSON(httpError.Code, httpError.Msg)
- return
- }
-
- e := err.(*errno.ManagerError)
- status := http.StatusInternalServerError
- if e.Status > 0 {
- status = e.Status
- }
- logger.WithField(conf.RequestId, requestId).Error(e.ErrorDetail())
- c.AbortWithStatusJSON(status, e.Response())
-}
-
-func consumerList(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- size, _ := strconv.Atoi(c.DefaultQuery("size", "10"))
- page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
-
- search := c.DefaultQuery("search", "")
-
- count, list, err := service.ConsumerList(page, size, search)
-
- if err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- resp := errno.FromMessage(errno.SystemSuccess).ListResponse(count, list)
-
- c.JSON(http.StatusOK, resp)
-}
-
-func consumerItem(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- id := c.Param("id")
-
- consumer, err := service.ConsumerItem(id)
-
- if err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.FromMessage(errno.SystemSuccess).ItemResponse(consumer))
-}
-
-func consumerCreate(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- param, exist := c.Get("requestBody")
-
- u4 := uuid.NewV4()
-
- if !exist || len(param.([]byte)) < 1 {
- err := errno.New(errno.InvalidParam)
- logger.WithField(conf.RequestId, requestId).Error(err.ErrorDetail())
- c.AbortWithStatusJSON(http.StatusBadRequest, err.Response())
- return
- }
-
- if err := service.ConsumerCreate(param, u4.String()); err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.Succeed())
-}
-
-func consumerUpdate(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- param, exist := c.Get("requestBody")
-
- id := c.Param("id")
-
- if !exist || len(param.([]byte)) < 1 {
- err := errno.New(errno.InvalidParam)
- logger.WithField(conf.RequestId, requestId).Error(err.ErrorDetail())
- c.AbortWithStatusJSON(http.StatusBadRequest, err.Response())
- return
- }
-
- if err := service.ConsumerUpdate(param, id); err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.Succeed())
-}
-
-func consumerDelete(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- id := c.Param("id")
-
- if err := service.ConsumerDelete(id); err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.Succeed())
-}
diff --git a/api/route/consumer_test.go b/api/route/consumer_test.go
deleted file mode 100644
index 3793804..0000000
--- a/api/route/consumer_test.go
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "net/http"
- "testing"
-)
-
-func TestConsumer(t *testing.T) {
- // create ok
- username1 := "e2e_test_consumer1"
- testHandler.
- Post(uriPrefix+"/consumers").
- Header("Authorization", token).
- JSON(`{
- "username": "` + username1 + `",
- "plugins": {
- "limit-count": {
- "count": 2,
- "time_window": 60,
- "rejected_code": 503,
- "key": "remote_addr"
- },
- "basic-auth": {
- "username": "foo",
- "password": "bar"
- }
- },
- "desc": "test description"
- }`).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //update ok
- testHandler.
- Put(uriPrefix + "/consumers/" + username1).
- JSON(`{
- "username": "e2e_test_consumer1",
- "plugins": {
- "limit-count": {
- "count": 2,
- "time_window": 60,
- "rejected_code": 503,
- "key": "remote_addr"
- },
- "basic-auth": {
- "username": "foo",
- "password": "bar"
- }
- },
- "desc": "test desc"
- }`).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //list
- testHandler.
- Get(uriPrefix + "/consumers").
- Headers(map[string]string{"Authorization": token}).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //delete
- testHandler.
- Delete(uriPrefix + "/consumers/" + username1).
- Expect(t).
- Status(http.StatusOK).
- End()
-
-}
diff --git a/api/route/plugin.go b/api/route/plugin.go
deleted file mode 100644
index dad545d..0000000
--- a/api/route/plugin.go
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "encoding/json"
- "net/http"
-
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/service"
- "github.com/gin-gonic/gin"
-)
-
-func AppendPlugin(r *gin.Engine) *gin.Engine {
- r.GET("/apisix/admin/plugins", listPlugin)
- r.GET("/apisix/admin/schema/plugins/:name", findSchema)
- return r
-}
-
-func findSchema(c *gin.Context) {
- name := c.Param("name")
- request := &service.ApisixPluginRequest{Name: name}
- if result, err := request.Schema(); err != nil {
- e := errno.FromMessage(errno.ApisixPluginSchemaError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- } else {
- resp, _ := json.Marshal(result)
- c.Data(http.StatusOK, service.ContentType, resp)
- }
-}
-
-func listPlugin(c *gin.Context) {
- request := &service.ApisixPluginRequest{}
- if result, err := request.List(); err != nil {
- e := errno.FromMessage(errno.ApisixPluginListError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- } else {
- resp, _ := json.Marshal(result)
- c.Data(http.StatusOK, service.ContentType, resp)
- }
-}
diff --git a/api/route/route.go b/api/route/route.go
deleted file mode 100644
index 48f89fd..0000000
--- a/api/route/route.go
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "encoding/json"
- "net/http"
- "strconv"
- "strings"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/service"
- "github.com/gin-gonic/gin"
- uuid "github.com/satori/go.uuid"
-)
-
-func AppendRoute(r *gin.Engine) *gin.Engine {
- r.POST("/apisix/admin/routes", createRoute)
- r.GET("/apisix/admin/routes/:rid", findRoute)
- r.GET("/apisix/admin/routes", listRoute)
- r.PUT("/apisix/admin/routes/:rid", updateRoute)
- r.PUT("/apisix/admin/routes/:rid/publish", publishRoute)
- r.DELETE("/apisix/admin/routes/:rid", deleteRoute)
- r.GET("/apisix/admin/notexist/routes", isRouteExist)
- r.PUT("/apisix/admin/routes/:rid/offline", offlineRoute)
- return r
-}
-
-func publishRoute(c *gin.Context) {
- rid := c.Param("rid")
- r := &service.Route{}
- tx := conf.DB().Begin()
- if err := tx.Model(&service.Route{}).Where("id = ?", rid).Update("status", true).Find(&r).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.RoutePublishError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- routeRequest := &service.RouteRequest{}
- if err := json.Unmarshal([]byte(r.Content), routeRequest); err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.RoutePublishError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- routeRequest.Status = true
- }
- if content, err := json.Marshal(routeRequest); err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.RoutePublishError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- r.Content = string(content)
- }
- arr := service.ToApisixRequest(routeRequest)
- var resp *service.ApisixRouteResponse
- if resp, err = arr.Create(rid); err != nil {
- tx.Rollback()
- if httpError, ok := err.(*errno.HttpError); ok {
- c.AbortWithStatusJSON(httpError.Code, httpError.Msg)
- return
- } else {
- e := errno.FromMessage(errno.ApisixRouteCreateError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- } else {
- resp.Node.Value.Name = r.Name
- resp.Node.Value.Status = r.Status
- if respStr, err := json.Marshal(resp); err != nil {
- e := errno.FromMessage(errno.RoutePublishError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- r.ContentAdminApi = string(respStr)
- }
- }
- if err := tx.Commit().Error; err == nil {
- // update content_admin_api
- if err := conf.DB().Model(&service.Route{}).Update(r).Error; err != nil {
- e := errno.FromMessage(errno.DBRouteUpdateError, err.Error())
- logger.Error(e.Msg)
- }
- }
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
-
-func offlineRoute(c *gin.Context) {
- rid := c.Param("rid")
- db := conf.DB()
- tx := db.Begin()
- route := &service.Route{}
- if err := tx.Model(&service.Route{}).Where("id = ?", rid).Update(map[string]interface{}{"status": 0, "content_admin_api": ""}).First(&route).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.RoutePublishError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- routeRequest := &service.RouteRequest{}
- if err := json.Unmarshal([]byte(route.Content), routeRequest); err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.RoutePublishError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- routeRequest.Status = false
- }
- if content, err := json.Marshal(routeRequest); err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.RoutePublishError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- route.Content = string(content)
- }
- request := &service.ApisixRouteRequest{}
- if _, err := request.Delete(rid); err != nil {
- tx.Rollback()
- if httpError, ok := err.(*errno.HttpError); ok {
- c.AbortWithStatusJSON(httpError.Code, httpError.Msg)
- return
- } else {
- e := errno.FromMessage(errno.ApisixRouteDeleteError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- if err := tx.Model(&service.Route{}).Update(route).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.DBRouteUpdateError, err.Error())
- logger.Error(e.Msg)
- return
- }
- }
- if err := tx.Commit().Error; err != nil {
- e := errno.FromMessage(errno.ApisixRouteDeleteError, err.Error())
- logger.Error(e.Msg)
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
-
-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"))
- page, _ := strconv.Atoi(c.Query("page"))
- if size == 0 {
- size = 10
- }
- db = db.Table("routes")
- isSearch := true
- if name, exist := c.GetQuery("name"); exist {
- db = db.Where("name like ? ", "%"+name+"%")
- isSearch = false
- }
- if description, exist := c.GetQuery("description"); exist {
- db = db.Where("description like ? ", "%"+description+"%")
- isSearch = false
- }
- if host, exist := c.GetQuery("host"); exist {
- db = db.Where("hosts like ? ", "%"+host+"%")
- isSearch = false
- }
- if uri, exist := c.GetQuery("uri"); exist {
- db = db.Where("uris like ? ", "%"+uri+"%")
- isSearch = false
- }
- if ip, exist := c.GetQuery("ip"); exist {
- db = db.Where("upstream_nodes like ? ", "%"+ip+"%")
- isSearch = false
- }
- if rgid, exist := c.GetQuery("route_group_id"); exist {
- db = db.Where("route_group_id = ?", rgid)
- isSearch = false
- }
- if rgName, exist := c.GetQuery("route_group_name"); exist {
- db = db.Where("route_group_name like ?", "%"+rgName+"%")
- isSearch = false
- }
- // search
- if isSearch {
- if search, exist := c.GetQuery("search"); exist {
- s := "%" + search + "%"
- db = db.Where("name like ? or description like ? or hosts like ? or uris like ? or upstream_nodes like ? or route_group_id = ? or route_group_name like ?", s, s, s, s, s, search, s)
- }
- }
- // mysql
- routeList := []service.Route{}
- var count int
- if err := db.Order("priority, update_time desc").Table("routes").Offset((page - 1) * size).Limit(size).Find(&routeList).Error; err != nil {
- e := errno.FromMessage(errno.RouteRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- } else {
- responseList := make([]service.RouteResponse, 0)
- for _, r := range routeList {
- response := &service.RouteResponse{}
- response.Parse(&r)
- responseList = append(responseList, *response)
- }
- if err := db.Count(&count).Error; err != nil {
- e := errno.FromMessage(errno.RouteRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- result := &service.ListResponse{Count: count, Data: responseList}
- resp, _ := json.Marshal(result)
- c.Data(http.StatusOK, service.ContentType, resp)
- }
-}
-
-func deleteRoute(c *gin.Context) {
- rid := c.Param("rid")
- db := conf.DB()
- tx := db.Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
- // delete from mysql
- rd := &service.Route{}
- rd.ID = uuid.FromStringOrNil(rid)
- if err := db.Table("routes").Where("id=?", rid).First(&rd).Error; err != nil {
- e := errno.FromMessage(errno.RouteRequestError, err.Error()+" route ID: "+rid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- if err := conf.DB().Delete(rd).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.DBRouteDeleteError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else if rd.Status {
- request := &service.ApisixRouteRequest{}
- if _, err := request.Delete(rid); err != nil {
- tx.Rollback()
- if httpError, ok := err.(*errno.HttpError); ok {
- c.AbortWithStatusJSON(httpError.Code, httpError.Msg)
- return
- } else {
- e := errno.FromMessage(errno.ApisixRouteDeleteError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- }
- if err := tx.Commit().Error; err != nil {
- e := errno.FromMessage(errno.ApisixRouteDeleteError, err.Error())
- logger.Error(e.Msg)
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
-func updateRoute(c *gin.Context) {
- rid := c.Param("rid")
- param, exist := c.Get("requestBody")
- if !exist || len(param.([]byte)) < 1 {
- e := errno.FromMessage(errno.RouteRequestError, "route create with no post data")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- routeRequest := &service.RouteRequest{}
- if err := routeRequest.Parse(param); err != nil {
- e := errno.FromMessage(errno.RouteRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- routeGroup := &service.RouteGroupDao{}
- isCreateGroup := false
- isUngroup := false
- if len(strings.Trim(routeRequest.RouteGroupId, "")) == 0 {
- if len(strings.Trim(routeRequest.RouteGroupName, "")) > 0 {
- isCreateGroup = true
- routeGroup.ID = uuid.NewV4()
- // create route group
- routeGroup.Name = routeRequest.RouteGroupName
- routeRequest.RouteGroupId = routeGroup.ID.String()
- } else {
- isUngroup = true
- }
- }
- logger.Info(routeRequest.Plugins)
- db := conf.DB()
- arr := service.ToApisixRequest(routeRequest)
- var resp *service.ApisixRouteResponse
- var r *service.Route
- if rd, err := service.ToRoute(routeRequest, arr, uuid.FromStringOrNil(rid), nil); err != nil {
- c.AbortWithStatusJSON(http.StatusInternalServerError, err.Response())
- return
- } else {
- r = rd
- tx := db.Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
- logger.Info(rd)
- if isCreateGroup {
- if err := tx.Model(&service.RouteGroupDao{}).Create(routeGroup).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.DuplicateRouteGroupName, routeGroup.Name)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- if err := tx.Model(&service.Route{}).Update(rd).Error; err != nil {
- // rollback
- tx.Rollback()
- e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else if rd.Status {
- if resp, err = arr.Update(rid); err != nil {
- tx.Rollback()
- if httpError, ok := err.(*errno.HttpError); ok {
- c.AbortWithStatusJSON(httpError.Code, httpError.Msg)
- return
- } else {
- e := errno.FromMessage(errno.ApisixRouteCreateError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- }
- if isUngroup {
- if err := tx.Model(&service.Route{}).Where("id = ?", rid).Update(map[string]interface{}{"route_group_id": "", "route_group_name": ""}).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.SetRouteUngroupError)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- if err := tx.Commit().Error; err == nil && r.Status {
- // update content_admin_api
- if rd, err := service.ToRoute(routeRequest, arr, uuid.FromStringOrNil(rid), resp); err != nil {
- e := errno.FromMessage(errno.DBRouteUpdateError, err.Error())
- logger.Error(e.Msg)
- } else {
- if err := conf.DB().Model(&service.Route{}).Update(rd).Error; err != nil {
- e := errno.FromMessage(errno.DBRouteUpdateError, err.Error())
- logger.Error(e.Msg)
- }
- }
- }
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
-
-func findRoute(c *gin.Context) {
- rid := c.Param("rid")
- route := &service.Route{}
- var count int
- if err := conf.DB().Table("routes").Where("id=?", rid).Count(&count).First(&route).Error; err != nil {
- e := errno.FromMessage(errno.RouteRequestError, err.Error()+" route ID: "+rid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- if count < 1 {
- e := errno.FromMessage(errno.RouteRequestError, " route ID: "+rid+" not exist")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(e.Status, e.Response())
- return
- }
- }
- if !route.Status {
- routeRequest := &service.RouteRequest{}
- if err := json.Unmarshal([]byte(route.Content), &routeRequest); err != nil {
- e := errno.FromMessage(errno.RouteRequestError, " route ID: "+rid+" not exist")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(e.Status, e.Response())
- return
- } else {
- routeRequest.Name = route.Name
- resp, _ := json.Marshal(routeRequest)
- c.Data(http.StatusOK, service.ContentType, resp)
- }
- } else {
- // find from apisix
- request := &service.ApisixRouteRequest{}
- if response, err := request.FindById(rid); err != nil {
- e := errno.FromMessage(errno.RouteRequestError, err.Error()+" route ID: "+rid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- } else {
- // transfer response to dashboard struct
- if result, err := response.Parse(); err != nil {
- e := errno.FromMessage(errno.RouteRequestError, err.Error()+" route ID: "+rid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- } else {
- // need to find name from mysql temporary
- result.Name = route.Name
- var script map[string]interface{}
- if err = json.Unmarshal([]byte(route.Script), &script); err != nil {
- script = map[string]interface{}{}
- }
- result.Script = script
-
- result.RouteGroupId = route.RouteGroupId
- result.RouteGroupName = route.RouteGroupName
- result.Status = true
- resp, _ := json.Marshal(result)
- c.Data(http.StatusOK, service.ContentType, resp)
- }
- }
- }
-}
-
-func createRoute(c *gin.Context) {
- u4 := uuid.NewV4()
- rid := u4.String()
- param, exist := c.Get("requestBody")
- if !exist || len(param.([]byte)) < 1 {
- e := errno.FromMessage(errno.RouteRequestError, "route create with no post data")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- routeRequest := &service.RouteRequest{}
- if err := routeRequest.Parse(param); err != nil {
- e := errno.FromMessage(errno.RouteRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- routeGroup := &service.RouteGroupDao{}
- isCreateGroup := false
- if len(strings.Trim(routeRequest.RouteGroupId, "")) == 0 {
- // create route group
- if len(strings.Trim(routeRequest.RouteGroupName, "")) > 0 {
- isCreateGroup = true
- routeGroup.ID = uuid.NewV4()
- routeGroup.Name = routeRequest.RouteGroupName
- routeRequest.RouteGroupId = routeGroup.ID.String()
- }
- }
- logger.Info(routeRequest.Plugins)
- db := conf.DB()
- arr := service.ToApisixRequest(routeRequest)
- var resp *service.ApisixRouteResponse
- var r *service.Route
- if rd, err := service.ToRoute(routeRequest, arr, u4, nil); err != nil {
- c.AbortWithStatusJSON(http.StatusInternalServerError, err.Response())
- return
- } else {
- r = rd
- tx := db.Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
- logger.Info(rd)
- if isCreateGroup {
- if err := tx.Model(&service.RouteGroupDao{}).Create(routeGroup).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.DuplicateRouteGroupName, routeGroup.Name)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- if err := tx.Model(&service.Route{}).Create(rd).Error; err != nil {
- // rollback
- tx.Rollback()
- e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else if rd.Status {
- if resp, err = arr.Create(rid); err != nil {
- tx.Rollback()
- if httpError, ok := err.(*errno.HttpError); ok {
- c.AbortWithStatusJSON(httpError.Code, httpError.Msg)
- return
- } else {
- e := errno.FromMessage(errno.ApisixRouteCreateError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- }
- if err := tx.Commit().Error; err == nil && r.Status {
- // update content_admin_api
- if rd, err := service.ToRoute(routeRequest, arr, u4, resp); err != nil {
- e := errno.FromMessage(errno.DBRouteUpdateError, err.Error())
- logger.Error(e.Msg)
- } else {
- if err := conf.DB().Model(&service.Route{}).Update(rd).Error; err != nil {
- e := errno.FromMessage(errno.DBRouteUpdateError, err.Error())
- logger.Error(e.Msg)
- }
- }
- }
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
diff --git a/api/route/route_group.go b/api/route/route_group.go
deleted file mode 100644
index 7be8538..0000000
--- a/api/route/route_group.go
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "encoding/json"
- "fmt"
- "net/http"
- "strconv"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/service"
- "github.com/gin-gonic/gin"
- uuid "github.com/satori/go.uuid"
-)
-
-func AppendRouteGroup(r *gin.Engine) *gin.Engine {
- r.POST("/apisix/admin/routegroups", createRouteGroup)
- r.GET("/apisix/admin/routegroups/:gid", findRouteGroup)
- r.GET("/apisix/admin/routegroups", listRouteGroup)
- r.GET("/apisix/admin/names/routegroups", listRouteGroupName)
- r.PUT("/apisix/admin/routegroups/:gid", updateRouteGroup)
- r.DELETE("/apisix/admin/routegroups/:gid", deleteRouteGroup)
- r.GET("/apisix/admin/notexist/routegroups", isRouteGroupExist)
- return r
-}
-
-func isRouteGroupExist(c *gin.Context) {
- if name, exist := c.GetQuery("name"); exist {
- db := conf.DB()
- db = db.Table("route_group")
- 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.RouteGroupRequestError, 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.DuplicateRouteGroupName, name)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- }
- } else {
- e := errno.FromMessage(errno.RouteGroupRequestError, "name is needed")
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
-}
-
-func createRouteGroup(c *gin.Context) {
- u4 := uuid.NewV4()
- gid := u4.String()
- // todo 参数校验
- param, exist := c.Get("requestBody")
- if !exist || len(param.([]byte)) < 1 {
- e := errno.FromMessage(errno.RouteRequestError, "route_group create with no post data")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- // trans params
- rr := &service.RouteGroupRequest{}
- if err := rr.Parse(param); err != nil {
- e := errno.FromMessage(errno.RouteGroupRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- rr.Id = gid
- fmt.Println(rr)
- // mysql
- if rd, err := service.Trans2RouteGroupDao(rr); err != nil {
- c.AbortWithStatusJSON(http.StatusInternalServerError, err.Response())
- return
- } else {
- if err := rd.CreateRouteGroup(); err != nil {
- e := errno.FromMessage(errno.DBRouteGroupError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
-
-func findRouteGroup(c *gin.Context) {
- gid := c.Param("gid")
- routeGroup := &service.RouteGroupDao{}
- if err, count := routeGroup.FindRouteGroup(gid); err != nil {
- e := errno.FromMessage(errno.RouteGroupRequestError, err.Error()+"route_group ID:"+gid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- } else {
- if count < 1 {
- e := errno.FromMessage(errno.RouteRequestError, " route_group ID: "+gid+" not exist")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(e.Status, e.Response())
- return
- }
- }
- resp, _ := json.Marshal(routeGroup)
- c.Data(http.StatusOK, service.ContentType, resp)
-}
-
-func listRouteGroup(c *gin.Context) {
- size, _ := strconv.Atoi(c.Query("size"))
- page, _ := strconv.Atoi(c.Query("page"))
- if size == 0 {
- size = 10
- }
- var s string
-
- rd := &service.RouteGroupDao{}
- routeGroupList := []service.RouteGroupDao{}
- if search, exist := c.GetQuery("search"); exist && len(search) > 0 {
- s = "%" + search + "%"
- }
- if err, count := rd.GetRouteGroupList(&routeGroupList, s, page, size); err != nil {
- e := errno.FromMessage(errno.RouteGroupRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- result := &service.ListResponse{Count: count, Data: routeGroupList}
- resp, _ := json.Marshal(result)
- c.Data(http.StatusOK, service.ContentType, resp)
- }
-}
-
-func listRouteGroupName(c *gin.Context) {
- db := conf.DB()
- routeGroupList := []service.RouteGroupDao{}
- var count int
- if err := db.Order("name").Table("route_group").Find(&routeGroupList).Count(&count).Error; err != nil {
- e := errno.FromMessage(errno.RouteGroupRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- responseList := make([]*service.RouteGroupNameResponse, 0)
- for _, r := range routeGroupList {
- 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 updateRouteGroup(c *gin.Context) {
- // get params
- gid := c.Param("gid")
- param, exist := c.Get("requestBody")
- if !exist || len(param.([]byte)) < 1 {
- e := errno.FromMessage(errno.RouteRequestError, "route_group update with no post data")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- // trans params
- rr := &service.RouteGroupRequest{}
- if err := rr.Parse(param); err != nil {
- e := errno.FromMessage(errno.RouteGroupRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- rr.Id = gid
- if ud, err := service.Trans2RouteGroupDao(rr); err != nil {
- c.AbortWithStatusJSON(http.StatusInternalServerError, err.Response())
- return
- } else {
- // mysql
- if err2 := ud.UpdateRouteGroup(); err2 != nil {
- e := errno.FromMessage(errno.DBRouteGroupError, err2.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
-
-func deleteRouteGroup(c *gin.Context) {
- gid := c.Param("gid")
- // 参数校验
- routeGroup := &service.RouteGroupDao{}
- if err := conf.DB().Table("route_group").Where("id=?", gid).First(&routeGroup).Error; err != nil {
- e := errno.FromMessage(errno.RouteGroupRequestError, err.Error()+" route_group ID: "+gid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- // delete from mysql
- routeGroup.ID = uuid.FromStringOrNil(gid)
- if err := routeGroup.DeleteRouteGroup(); err != nil {
- e := errno.FromMessage(errno.DBRouteGroupDeleteError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
diff --git a/api/route/route_test.go b/api/route/route_test.go
deleted file mode 100644
index 5b66679..0000000
--- a/api/route/route_test.go
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "net/http"
- "testing"
-)
-
-func TestRoute(t *testing.T) {
- // create ok
-
- testHandler.
- Post(uriPrefix + "/routes").
- JSON(`{
- "id": "11",
- "name": "e2e-test-route1",
- "desc": "route created by java sdk",
- "priority": 0,
- "methods": [
- "GET"
- ],
- "uris": [
- "/helloworld",
- "/hello2*"
- ],
- "hosts": [
- "s.com"
- ],
- "protocols": [
- "http",
- "https",
- "websocket"
- ],
- "redirect":{
- "code": 302,
- "uri": "/hello"
- },
- "vars": [
- ["arg_name", "==", "json"],
- ["arg_age", ">", "18"],
- ["arg_address", "~~", "China.*"]
- ],
- "upstream": {
- "type": "roundrobin",
- "nodes": {
- "39.97.63.215:80": 100
- },
- "timeout": {
- "connect":15,
- "send":15,
- "read":15
- }
- },
- "upstream_protocol": "keep",
- "upstream_path": {
- "type" : "static",
- "from": "",
- "to": "/hello"
- },
- "upstream_header": {
- "header_name1": "header_value1",
- "header_name2": "header_value2"
- },
- "plugins": {
- "limit-count": {
- "count": 2,
- "time_window": 60,
- "rejected_code": 503,
- "key": "remote_addr"
- },
- "prometheus": {}
- }
- }`).
- Headers(map[string]string{"Authorization": token}).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //update ok
- testHandler.
- Put(uriPrefix + "/routes/11").
- JSON(`{
- "id": "11",
- "name": "e2e-test-route1",
- "desc": "route created by java sdk",
- "priority": 0,
- "methods": [
- "GET"
- ],
- "uris": [
- "/helloworld",
- "/hello2*"
- ],
- "hosts": [
- "s.com"
- ],
- "protocols": [
- "http",
- "https",
- "websocket"
- ],
- "redirect":{
- "code": 302,
- "uri": "/hello"
- },
- "vars": [
- ["arg_name", "==", "json"],
- ["arg_age", ">", "18"],
- ["arg_address", "~~", "China.*"]
- ],
- "upstream": {
- "type": "roundrobin",
- "nodes": {
- "39.97.63.215:80": 100
- },
- "timeout": {
- "connect":15,
- "send":15,
- "read":15
- }
- },
- "upstream_protocol": "keep",
- "upstream_path": {
- "type" : "static",
- "from": "",
- "to": "/hello"
- },
- "upstream_header": {
- "header_name1": "header_value1",
- "header_name2": "header_value2"
- },
- "plugins": {
- "limit-count": {
- "count": 2,
- "time_window": 60,
- "rejected_code": 503,
- "key": "remote_addr"
- },
- "prometheus": {}
- }
- }`).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //list
- testHandler.
- Get(uriPrefix + "/routes").
- Headers(map[string]string{"Authorization": token}).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //not exist
- testHandler.
- Get(uriPrefix + "/notexist/routes").
- //Query("name", "notexists").
- QueryCollection(map[string][]string{"name": {"notexists"}}).
- Headers(map[string]string{"Authorization": token}).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //existed todo: fix bug
- //testHandler.
- // Get(uriPrefix + "/notexist/routes").
- // QueryCollection(map[string][]string{"name": {""}}).
- // Headers(map[string]string{"Authorization": token}).
- // Expect(t).
- // Status(http.StatusBadRequest).
- // End()
-
- //delete
- testHandler.
- Delete(uriPrefix + "/routes/11").
- Expect(t).
- Status(http.StatusOK).
- End()
-
-}
diff --git a/api/route/ssl.go b/api/route/ssl.go
deleted file mode 100644
index d962be8..0000000
--- a/api/route/ssl.go
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "net/http"
- "strconv"
-
- "github.com/gin-gonic/gin"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/service"
- uuid "github.com/satori/go.uuid"
-)
-
-func AppendSsl(r *gin.Engine) *gin.Engine {
- r.POST("/apisix/admin/check_ssl_cert", sslCheck)
- r.POST("/apisix/admin/check_ssl_exists", hostCheck)
-
- r.GET("/apisix/admin/ssls", sslList)
- r.POST("/apisix/admin/ssls", sslCreate)
- r.GET("/apisix/admin/ssls/:id", sslItem)
- r.PUT("/apisix/admin/ssls/:id", sslUpdate)
- r.DELETE("/apisix/admin/ssls/:id", sslDelete)
- r.PATCH("/apisix/admin/ssls/:id", sslPatch)
-
- return r
-}
-
-func sslList(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- size, _ := strconv.Atoi(c.DefaultQuery("size", "10"))
- page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
- status, _ := strconv.Atoi(c.DefaultQuery("status", "-1"))
- expireStart, _ := strconv.Atoi(c.DefaultQuery("expire_start", "-1"))
- expireEnd, _ := strconv.Atoi(c.DefaultQuery("expire_end", "-1"))
- sortType := c.DefaultQuery("sort_type", "desc")
-
- sni := c.DefaultQuery("sni", "")
-
- count, list, err := service.SslList(page, size, status, expireStart, expireEnd, sni, sortType)
-
- if err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- resp := errno.FromMessage(errno.SystemSuccess).ListResponse(count, list)
-
- c.JSON(http.StatusOK, resp)
-}
-
-func sslItem(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- id := c.Param("id")
-
- ssl, err := service.SslItem(id)
-
- if err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.FromMessage(errno.SystemSuccess).ItemResponse(ssl))
-}
-
-func sslCheck(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- param, exist := c.Get("requestBody")
-
- if !exist || len(param.([]byte)) < 1 {
- err := errno.New(errno.InvalidParam)
- logger.WithField(conf.RequestId, requestId).Error(err.ErrorDetail())
- c.AbortWithStatusJSON(http.StatusBadRequest, err.Response())
- return
- }
-
- ssl, err := service.SslCheck(param)
- if err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- resp := errno.FromMessage(errno.SystemSuccess).ItemResponse(ssl)
-
- c.JSON(http.StatusOK, resp)
-}
-
-func sslCreate(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- param, exist := c.Get("requestBody")
-
- u4 := uuid.NewV4()
-
- if !exist || len(param.([]byte)) < 1 {
- err := errno.New(errno.InvalidParam)
- logger.WithField(conf.RequestId, requestId).Error(err.ErrorDetail())
- c.AbortWithStatusJSON(http.StatusBadRequest, err.Response())
- return
- }
-
- if err := service.SslCreate(param, u4.String()); err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.Succeed())
-}
-
-func sslUpdate(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- param, exist := c.Get("requestBody")
- id := c.Param("id")
-
- if !exist || len(param.([]byte)) < 1 {
- err := errno.New(errno.InvalidParam)
- logger.WithField(conf.RequestId, requestId).Error(err.ErrorDetail())
- c.AbortWithStatusJSON(http.StatusBadRequest, err.Response())
- return
- }
-
- if err := service.SslUpdate(param, id); err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.Succeed())
-}
-
-func sslPatch(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- param, exist := c.Get("requestBody")
-
- id := c.Param("id")
-
- if !exist || len(param.([]byte)) < 1 {
- err := errno.New(errno.InvalidParam)
- logger.WithField(conf.RequestId, requestId).Error(err.ErrorDetail())
- c.AbortWithStatusJSON(http.StatusBadRequest, err.Response())
- return
- }
-
- if err := service.SslPatch(param, id); err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.Succeed())
-}
-
-func sslDelete(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- id := c.Param("id")
-
- if err := service.SslDelete(id); err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.Succeed())
-}
-
-func hostCheck(c *gin.Context) {
- requestId, _ := c.Get("X-Request-Id")
- param, exist := c.Get("requestBody")
-
- if !exist || len(param.([]byte)) < 1 {
- err := errno.New(errno.InvalidParam)
- logger.WithField(conf.RequestId, requestId).Error(err.ErrorDetail())
- c.AbortWithStatusJSON(http.StatusBadRequest, err.Response())
- return
- }
-
- err := service.CheckSniExists(param)
- if err != nil {
- handleServiceError(c, requestId, err)
- return
- }
-
- c.JSON(http.StatusOK, errno.Succeed())
-
-}
diff --git a/api/route/ssl_test.go b/api/route/ssl_test.go
deleted file mode 100644
index 8c85ff3..0000000
--- a/api/route/ssl_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "net/http"
- "testing"
-)
-
-func TestSslCreate(t *testing.T) {
- sslId := "ssl_id"
- // ok
- testHandler.
- Post(uriPrefix + "/ssl").
- JSON(`{
- "id": "` + sslId + `"
- "key": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDGO0J9xrOcmvgh\npkqHIYHCw35FTfIT5uXOSzdF49M2ZAKBQwFG0ovYT8bc0glNLB+hpDhJPL531qSP\nl1ZOe0W1ofP1u0T5Zzc9Rub/kn7RMPq0BsSC6J3rF+rQEwh1PM8qUuD8DxZ7jaOL\niMNL6SyuZIPsS1kPPBtsioukdo666tbjNMixhQbI9Wpg55abdXRFh3i7Zu/9siF1\njCGcsskjOaUOY4sYQ3i5WU/HIIRhA82XuIL+Sxd32P8bKi2UT1sqFXRjAVR7KRWo\nIVvkmSLoZb9ucV6MsccDrRYBf6rLbI1tFj9l2rY6GTFlT+6z7K/ZI60DGi/hsBfl\nDeEQ5WuxAgMBAAECggEAVHQQyucpxHGdfzCKlfGnh+Oj20Du/p2jkHUp [...]
- "cert": "-----BEGIN CERTIFICATE-----\nMIIEVzCCAr+gAwIBAgIQITiNM7xmudhg3pK85KDwLDANBgkqhkiG9w0BAQsFADB/\nMR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExKjAoBgNVBAsMIWp1bnh1\nY2hlbkBqdW54dWRlQWlyIChqdW54dSBjaGVuKTExMC8GA1UEAwwobWtjZXJ0IGp1\nbnh1Y2hlbkBqdW54dWRlQWlyIChqdW54dSBjaGVuKTAeFw0xOTA2MDEwMDAwMDBa\nFw0zMDA3MDgwNzQ4MDJaMFUxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBj\nZXJ0aWZpY2F0ZTEqMCgGA1UECwwhanVueHVjaGVuQGp1bnh1ZGVBaXIgKGp1bnh1\nIGNoZW4pMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjt [...]
- }`).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //update ok
- testHandler.
- Put(uriPrefix + "/consumers/" + sslId).
- JSON(`{
- "id": "` + sslId + `"
- "key": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDGO0J9xrOcmvgh\npkqHIYHCw35FTfIT5uXOSzdF49M2ZAKBQwFG0ovYT8bc0glNLB+hpDhJPL531qSP\nl1ZOe0W1ofP1u0T5Zzc9Rub/kn7RMPq0BsSC6J3rF+rQEwh1PM8qUuD8DxZ7jaOL\niMNL6SyuZIPsS1kPPBtsioukdo666tbjNMixhQbI9Wpg55abdXRFh3i7Zu/9siF1\njCGcsskjOaUOY4sYQ3i5WU/HIIRhA82XuIL+Sxd32P8bKi2UT1sqFXRjAVR7KRWo\nIVvkmSLoZb9ucV6MsccDrRYBf6rLbI1tFj9l2rY6GTFlT+6z7K/ZI60DGi/hsBfl\nDeEQ5WuxAgMBAAECggEAVHQQyucpxHGdfzCKlfGnh+Oj20Du/p2jkHUp [...]
- "cert": "-----BEGIN CERTIFICATE-----\nMIIEVzCCAr+gAwIBAgIQITiNM7xmudhg3pK85KDwLDANBgkqhkiG9w0BAQsFADB/\nMR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExKjAoBgNVBAsMIWp1bnh1\nY2hlbkBqdW54dWRlQWlyIChqdW54dSBjaGVuKTExMC8GA1UEAwwobWtjZXJ0IGp1\nbnh1Y2hlbkBqdW54dWRlQWlyIChqdW54dSBjaGVuKTAeFw0xOTA2MDEwMDAwMDBa\nFw0zMDA3MDgwNzQ4MDJaMFUxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBj\nZXJ0aWZpY2F0ZTEqMCgGA1UECwwhanVueHVjaGVuQGp1bnh1ZGVBaXIgKGp1bnh1\nIGNoZW4pMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjt [...]
- }`).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //list
- testHandler.
- Get(uriPrefix + "/ssl").
- Headers(map[string]string{"Authorization": token}).
- Expect(t).
- Status(http.StatusOK).
- End()
-
- //delete
- testHandler.
- Delete(uriPrefix + "/consumers/" + sslId).
- Expect(t).
- Status(http.StatusOK).
- End()
-
-}
diff --git a/api/route/upstream.go b/api/route/upstream.go
deleted file mode 100644
index 0135a85..0000000
--- a/api/route/upstream.go
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 route
-
-import (
- "encoding/json"
- "fmt"
- "net/http"
- "strconv"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/service"
- "github.com/gin-gonic/gin"
- uuid "github.com/satori/go.uuid"
-)
-
-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) {
- size, _ := strconv.Atoi(c.Query("size"))
- page, _ := strconv.Atoi(c.Query("page"))
- db := conf.DB()
- upstreamList := []service.UpstreamDao{}
- var count int
- if size == 0 || page == 0 {
- db = db.Order("name").Table("upstreams")
- } else {
- db = db.Order("name").Table("upstreams").Offset((page - 1) * size).Limit(size)
- }
- if err := db.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()
- // todo 参数校验
- param, exist := c.Get("requestBody")
- if !exist || len(param.([]byte)) < 1 {
- e := errno.FromMessage(errno.RouteRequestError, "upstream create with no post data")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- // trans params
- ur := &service.UpstreamRequest{}
- if err := ur.Parse(param); err != nil {
- e := errno.FromMessage(errno.UpstreamRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- ur.Id = uid
- fmt.Println(ur)
- // mysql
- if ud, err := service.Trans2UpstreamDao(nil, ur); err != nil {
- c.AbortWithStatusJSON(http.StatusInternalServerError, err.Response())
- return
- } else {
- // transaction
- db := conf.DB()
- tx := db.Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
- if err := tx.Create(ud).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.DBUpstreamError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- // apisix
- if aur, err := ur.Parse2Apisix(); err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.UpstreamTransError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- } else {
- if resp, err := aur.Create(); err != nil {
- tx.Rollback()
- if httpError, ok := err.(*errno.HttpError); ok {
- c.AbortWithStatusJSON(httpError.Code, httpError.Msg)
- return
- } else {
- e := errno.FromMessage(errno.ApisixUpstreamCreateError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- } else {
- if err := tx.Commit().Error; err == nil {
- if ud, err := service.Trans2UpstreamDao(resp, ur); err != nil {
- e := errno.FromMessage(errno.DBUpstreamError, err.Error())
- logger.Error(e.Msg)
- } else {
- if err := conf.DB().Model(&service.UpstreamDao{}).Update(ud).Error; err != nil {
- e := errno.FromMessage(errno.DBUpstreamError, err.Error())
- logger.Error(e.Msg)
- }
- }
- }
- }
- }
- }
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
-
-func findUpstream(c *gin.Context) {
- uid := c.Param("uid")
- upstream := &service.UpstreamDao{}
- var count int
- if err := conf.DB().Table("upstreams").Where("id=?", uid).Count(&count).Error; err != nil {
- e := errno.FromMessage(errno.UpstreamRequestError, err.Error()+" upstream ID: "+uid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- } else {
- if count < 1 {
- e := errno.FromMessage(errno.UpstreamRequestError, " upstream ID: "+uid+" not exist")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(e.Status, e.Response())
- return
- }
- }
- conf.DB().Table("upstreams").Where("id=?", uid).First(&upstream)
- // find from apisix
- aur := &service.ApisixUpstreamRequest{Id: uid}
- if resp, err := aur.FindById(); err != nil {
- e := errno.FromMessage(errno.UpstreamRequestError, err.Error()+" upstream ID: "+uid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- if result, err := resp.Parse2Request(); err != nil {
- e := errno.FromMessage(errno.UpstreamRequestError, err.Error()+" upstream ID: "+uid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- resp, _ := json.Marshal(result)
- c.Data(http.StatusOK, service.ContentType, resp)
- }
- }
-}
-
-func listUpstream(c *gin.Context) {
- size, _ := strconv.Atoi(c.Query("size"))
- page, _ := strconv.Atoi(c.Query("page"))
- if size == 0 {
- size = 10
- }
- db := conf.DB()
- db = db.Table("upstreams")
- if search, exist := c.GetQuery("search"); exist {
- s := "%" + search + "%"
- db = db.Where("name like ? or description like ? or nodes like ? ", s, s, s)
- }
- upstreamList := []service.UpstreamDao{}
- var count int
- if err := db.Order("update_time desc").Offset((page - 1) * size).Limit(size).Find(&upstreamList).Error; err != nil {
- e := errno.FromMessage(errno.RouteRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- responseList := make([]*service.UpstreamResponse, 0)
- for _, r := range upstreamList {
- response, err := r.Parse2Response()
- if err == nil {
- responseList = append(responseList, response)
- }
- }
- 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
- }
- result := &service.ListResponse{Count: count, Data: responseList}
- resp, _ := json.Marshal(result)
- c.Data(http.StatusOK, service.ContentType, resp)
- }
-}
-func updateUpstream(c *gin.Context) {
- uid := c.Param("uid")
- param, exist := c.Get("requestBody")
- if !exist || len(param.([]byte)) < 1 {
- e := errno.FromMessage(errno.RouteRequestError, "upstream update with no post data")
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- // trans params
- ur := &service.UpstreamRequest{}
- if err := ur.Parse(param); err != nil {
- e := errno.FromMessage(errno.UpstreamRequestError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- ur.Id = uid
- // mysql
- if ud, err := service.Trans2UpstreamDao(nil, ur); err != nil {
- c.AbortWithStatusJSON(http.StatusInternalServerError, err.Response())
- return
- } else {
- // transaction
- db := conf.DB()
- tx := db.Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
- if err := tx.Model(&service.UpstreamDao{}).Update(ud).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.DBUpstreamError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- // apisix
- if aur, err := ur.Parse2Apisix(); err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.UpstreamTransError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- } else {
- if resp, err := aur.Update(); err != nil {
- tx.Rollback()
- if httpError, ok := err.(*errno.HttpError); ok {
- c.AbortWithStatusJSON(httpError.Code, httpError.Msg)
- return
- } else {
- e := errno.FromMessage(errno.ApisixUpstreamUpdateError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- } else {
- if err := tx.Commit().Error; err == nil {
- if ud, err := service.Trans2UpstreamDao(resp, ur); err != nil {
- e := errno.FromMessage(errno.DBUpstreamError, err.Error())
- logger.Error(e.Msg)
- } else {
- if err := conf.DB().Model(&service.UpstreamDao{}).Update(ud).Error; err != nil {
- e := errno.FromMessage(errno.DBUpstreamError, err.Error())
- logger.Error(e.Msg)
- }
- }
- }
- }
- }
- }
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
-
-func deleteUpstream(c *gin.Context) {
- uid := c.Param("uid")
- // 参数校验
- upstream := &service.UpstreamDao{}
- if err := conf.DB().Table("upstreams").Where("id=?", uid).First(&upstream).Error; err != nil {
- e := errno.FromMessage(errno.UpstreamRequestError, err.Error()+" upstream ID: "+uid)
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusBadRequest, e.Response())
- return
- }
- db := conf.DB()
- tx := db.Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
- // delete from mysql
- rd := &service.UpstreamDao{}
- rd.ID = uuid.FromStringOrNil(uid)
- if err := tx.Delete(rd).Error; err != nil {
- tx.Rollback()
- e := errno.FromMessage(errno.DBUpstreamDeleteError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- } else {
- // delete from apisix
- request := &service.ApisixUpstreamRequest{Id: uid}
- if _, err := request.Delete(); err != nil {
- tx.Rollback()
- if httpError, ok := err.(*errno.HttpError); ok {
- c.AbortWithStatusJSON(httpError.Code, httpError.Msg)
- return
- } else {
- e := errno.FromMessage(errno.ApisixUpstreamDeleteError, err.Error())
- logger.Error(e.Msg)
- c.AbortWithStatusJSON(http.StatusInternalServerError, e.Response())
- return
- }
- }
- }
- if err := tx.Commit().Error; err != nil {
- e := errno.FromMessage(errno.ApisixUpstreamDeleteError, err.Error())
- logger.Error(e.Msg)
- }
- c.Data(http.StatusOK, service.ContentType, errno.Success())
-}
diff --git a/api/script/db/schema.sql b/api/script/db/schema.sql
deleted file mode 100644
index 8c476c3..0000000
--- a/api/script/db/schema.sql
+++ /dev/null
@@ -1,71 +0,0 @@
--- this is a db script for init
-CREATE DATABASE `manager`;
-use `manager`;
-CREATE TABLE `routes` (
- `id` varchar(64) NOT NULL unique,
- `name` varchar(200) NOT NULL unique, -- not support yet
- `description` varchar(200) DEFAULT NULL,
- `hosts` text,
- `uris` text,
- `upstream_nodes` text,
- `upstream_id` varchar(64) , -- fk
- `priority` int NOT NULL DEFAULT 0,
- `state` int NOT NULL DEFAULT 1, -- 1-normal 0-disable
- `content` text,
- `script` text,
- `content_admin_api` text,
- `create_time` bigint(20),
- `update_time` bigint(20),
- `route_group_id` varchar(64) NOT NULL,
- `route_group_name` varchar(64) NOT NULL,
- `status` tinyint(1),
- PRIMARY KEY (`id`)
-) DEFAULT CHARSET=utf8;
-
-CREATE TABLE `ssls` (
- `id` char(36) NOT NULL DEFAULT '',
- `public_key` text NOT NULL,
- `snis` text NOT NULL,
- `validity_start` bigint(20) unsigned NOT NULL,
- `validity_end` bigint(20) unsigned NOT NULL,
- `status` tinyint(1) unsigned NOT NULL DEFAULT '1',
- `create_time` bigint(20) unsigned NOT NULL,
- `update_time` bigint(20) unsigned NOT NULL,
- `public_key_hash` varchar(64) NOT NULL DEFAULT '',
- PRIMARY KEY (`id`),
- UNIQUE KEY `uni_public_key_hash` (`public_key_hash`)
-) DEFAULT CHARSET=utf8;
-
--- upstream
-CREATE TABLE `upstreams` (
- `id` varchar(64) NOT NULL unique,
- `name` varchar(200) NOT NULL unique, -- not support
- `description` varchar(200) DEFAULT NULL,
- `nodes` text,
- `content` text,
- `content_admin_api` text,
- `create_time` bigint(20),
- `update_time` bigint(20),
- PRIMARY KEY (`id`)
-) DEFAULT CHARSET=utf8;
-
-CREATE TABLE `consumers` (
- `id` char(36) NOT NULL DEFAULT '',
- `username` varchar(100) DEFAULT '',
- `plugins` text,
- `desc` varchar(200) DEFAULT '',
- `create_time` int(10) unsigned NOT NULL,
- `update_time` int(10) unsigned NOT NULL,
- PRIMARY KEY (`id`),
- UNIQUE KEY `uni_username` (`username`)
-) DEFAULT CHARSET=utf8;
--- route_group
-CREATE TABLE `route_group` (
- `id` varchar(64) NOT NULL unique,
- `name` varchar(200) NOT NULL unique,
- `description` varchar(200) DEFAULT NULL,
- `create_time` bigint(20),
- `update_time` bigint(20),
-
- PRIMARY KEY (`id`)
-) DEFAULT CHARSET=utf8;
diff --git a/api/service/base.go b/api/service/base.go
deleted file mode 100644
index 8ed5f5c..0000000
--- a/api/service/base.go
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 service
-
-import (
- "time"
-
- "github.com/jinzhu/gorm"
- uuid "github.com/satori/go.uuid"
-)
-
-// Base contains common columns for all tables.
-type Base struct {
- ID uuid.UUID `json:"id",sql:"type:uuid;primary_key;"`
- CreateTime int64 `json:"create_time"`
- UpdateTime int64 `json:"update_time"`
-}
-
-// BeforeCreate will set a UUID rather than numeric ID.
-func (base *Base) BeforeCreate(scope *gorm.Scope) error {
- timestamp := time.Now().Unix()
- err := scope.SetColumn("UpdateTime", timestamp)
- err = scope.SetColumn("CreateTime", timestamp)
- if len(base.ID) == 0 {
- uuid := uuid.NewV4()
- err = scope.SetColumn("ID", uuid)
- return err
- }
- return err
-}
-
-func (base *Base) BeforeSave(scope *gorm.Scope) error {
- err := scope.SetColumn("UpdateTime", time.Now().Unix())
- return err
-}
diff --git a/api/service/consumer.go b/api/service/consumer.go
deleted file mode 100644
index 98dee45..0000000
--- a/api/service/consumer.go
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 service
-
-import (
- "encoding/json"
- "fmt"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/utils"
- uuid "github.com/satori/go.uuid"
-)
-
-type Consumer struct {
- Base
- Username string `json:"username"`
- Desc string `json:"desc"`
- Plugins string `json:"plugins"`
-}
-
-type ConsumerDto struct {
- Base
- Username string `json:"username"`
- Desc string `json:"desc"`
- Plugins map[string]interface{} `json:"plugins"`
-}
-
-type ApisixConsumer struct {
- Username string `json:"username"`
- Desc string `json:"desc"`
- Plugins map[string]interface{} `json:"plugins"`
-}
-
-func (apisixConsumer *ApisixConsumer) Transfer(consumer *ConsumerDto) error {
- apisixConsumer.Username = consumer.Username
- apisixConsumer.Desc = consumer.Desc
- apisixConsumer.Plugins = consumer.Plugins
-
- return nil
-}
-
-func (consumer *Consumer) Transfer(req *ConsumerDto) error {
- consumer.ID = req.ID
- consumer.Desc = req.Desc
- consumer.Username = req.Username
-
- plugins, _ := json.Marshal(req.Plugins)
- consumer.Plugins = string(plugins)
-
- return nil
-}
-
-func (dto *ConsumerDto) Transfer(consumer *Consumer) error {
- dto.ID = consumer.ID
- dto.Desc = consumer.Desc
- dto.Username = consumer.Username
- dto.CreateTime = consumer.CreateTime
- dto.UpdateTime = consumer.UpdateTime
-
- var plugins map[string]interface{}
- _ = json.Unmarshal([]byte(consumer.Plugins), &plugins)
- dto.Plugins = plugins
-
- return nil
-}
-
-// ApisixConsumerResponse is response from apisix admin api
-type ApisixConsumerResponse struct {
- Action string `json:"action"`
- Node *ConsumerNode `json:"node"`
-}
-
-type ConsumerNode struct {
- Value ApisixConsumer `json:"value"`
- ModifiedIndex uint64 `json:"modifiedIndex"`
-}
-
-func (req *ConsumerDto) Parse(body interface{}) {
- if err := json.Unmarshal(body.([]byte), req); err != nil {
- req = nil
- }
-}
-
-func ConsumerList(page, size int, search string) (int, []ConsumerDto, error) {
- var count int
- consumerList := []Consumer{}
- db := conf.DB().Table("consumers")
-
- if search != "" {
- db = db.Where("username like ? ", "%"+search+"%").
- Or("`desc` like ? ", "%"+search+"%")
- }
-
- if err := db.Order("create_time desc").Offset((page - 1) * size).Limit(size).Find(&consumerList).Error; err != nil {
- e := errno.New(errno.DBReadError, err.Error())
- return 0, nil, e
- }
- if err := db.Count(&count).Error; err != nil {
- e := errno.New(errno.DBReadError, err.Error())
- return 0, nil, e
- }
-
- dtoList := []ConsumerDto{}
-
- for _, consumer := range consumerList {
- dto := ConsumerDto{}
- dto.Transfer(&consumer)
-
- dtoList = append(dtoList, dto)
- }
-
- return count, dtoList, nil
-}
-
-func ConsumerItem(id string) (*ConsumerDto, error) {
- if id == "" {
- return nil, errno.New(errno.InvalidParam)
- }
-
- consumer := &Consumer{}
- if err := conf.DB().Table("consumers").Where("id = ?", id).First(consumer).Error; err != nil {
- e := errno.New(errno.DBReadError, err.Error())
- return nil, e
- }
-
- dto := &ConsumerDto{}
- dto.Transfer(consumer)
-
- return dto, nil
-}
-
-func ConsumerCreate(param interface{}, id string) error {
- req := &ConsumerDto{}
- req.Parse(param)
-
- if req.Username == "" {
- return errno.New(errno.InvalidParamDetail, "username is required")
- }
-
- if len(req.Desc) > 200 {
- return errno.New(errno.InvalidParamDetail, "description is too long")
- }
-
- exists := Consumer{}
- conf.DB().Table("consumers").Where("username = ?", req.Username).First(&exists)
- if exists != (Consumer{}) {
- e := errno.New(errno.DuplicateUserName)
- return e
- }
-
- // trans
- tx := conf.DB().Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
-
- consumer := &Consumer{}
- consumer.Transfer(req)
-
- // update mysql
- consumer.ID = uuid.FromStringOrNil(id)
- if err := tx.Create(consumer).Error; err != nil {
- tx.Rollback()
- return errno.New(errno.DBWriteError, err.Error())
- }
-
- apisixConsumer := &ApisixConsumer{}
- apisixConsumer.Transfer(req)
-
- if _, err := apisixConsumer.PutConsumerToApisix(req.Username); err != nil {
- tx.Rollback()
- if _, ok := err.(*errno.HttpError); ok {
- return err
- }
- e := errno.New(errno.ApisixSslCreateError, err.Error())
- return e
- }
-
- tx.Commit()
-
- return nil
-}
-
-func ConsumerUpdate(param interface{}, id string) error {
- if id == "" {
- return errno.New(errno.InvalidParam)
- }
-
- req := &ConsumerDto{}
- req.Parse(param)
- if req == nil {
- return errno.New(errno.InvalidParam)
- }
-
- req.ID = uuid.FromStringOrNil(id)
- if req.Username != "" {
- exists := Consumer{}
- conf.DB().Table("consumers").Where("username = ?", req.Username).First(&exists)
- if exists != (Consumer{}) && exists.ID != req.ID {
- e := errno.New(errno.DuplicateUserName)
- return e
- }
- }
- // trans
- tx := conf.DB().Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
-
- // update mysql
- consumer := &Consumer{}
- consumer.Transfer(req)
- data := Consumer{Desc: consumer.Desc, Plugins: consumer.Plugins}
- if req.Username != "" {
- data.Username = req.Username
- }
- if err := tx.Model(&consumer).Updates(data).Error; err != nil {
- tx.Rollback()
- return errno.New(errno.DBWriteError, err.Error())
- }
-
- apisixConsumer := &ApisixConsumer{}
- apisixConsumer.Transfer(req)
-
- if _, err := apisixConsumer.PutConsumerToApisix(req.Username); err != nil {
- tx.Rollback()
- if _, ok := err.(*errno.HttpError); ok {
- return err
- }
- e := errno.New(errno.ApisixConsumerUpdateError, err.Error())
- return e
- }
-
- tx.Commit()
-
- return nil
-}
-
-func ConsumerDelete(id string) error {
- if id == "" {
- return errno.New(errno.InvalidParam)
- }
- //
- consumer := &Consumer{}
- if err := conf.DB().Table("consumers").Where("id = ?", id).First(consumer).Error; err != nil {
- e := errno.New(errno.RecordNotExist, err.Error())
- return e
- }
-
- // trans
- tx := conf.DB().Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
-
- // delete from mysql
- if err := conf.DB().Delete(consumer).Error; err != nil {
- tx.Rollback()
- return errno.New(errno.DBDeleteError, err.Error())
- }
-
- //delete from apisix
- if _, err := consumer.DeleteConsumerFromApisix(); err != nil {
- tx.Rollback()
- if _, ok := err.(*errno.HttpError); ok {
- return err
- }
- e := errno.New(errno.ApisixConsumerDeleteError, err.Error())
- return e
- }
-
- tx.Commit()
-
- return nil
-}
-
-func (req *ApisixConsumer) PutConsumerToApisix(rid string) (*ApisixConsumerResponse, error) {
- url := fmt.Sprintf("%s/consumers/%s", conf.BaseUrl, rid)
- if data, err := json.Marshal(req); err != nil {
- return nil, err
- } else {
- if resp, err := utils.Put(url, data); err != nil {
- logger.Error(url)
- logger.Error(string(data))
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixConsumerResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error(), resp)
- return nil, err
- } else {
- return &arresp, nil
- }
- }
- }
-}
-
-func (req *Consumer) DeleteConsumerFromApisix() (*ApisixConsumerResponse, error) {
- id := req.Username
- url := fmt.Sprintf("%s/consumers/%s", conf.BaseUrl, id)
-
- if resp, err := utils.Delete(url); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixConsumerResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
-}
-
-func GetConsumerByUserName(name string) (*Consumer, error) {
- if name == "" {
- return nil, errno.New(errno.InvalidParam)
- }
- consumer := &Consumer{}
- if err := conf.DB().Table("consumers").Where("username = ?", name).First(consumer).Error; err != nil {
- e := errno.New(errno.NotFoundError, err.Error())
- return nil, e
- }
-
- return consumer, nil
-}
diff --git a/api/service/plugin.go b/api/service/plugin.go
deleted file mode 100644
index 9ad7958..0000000
--- a/api/service/plugin.go
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 service
-
-import (
- "encoding/json"
- "fmt"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/utils"
-)
-
-type ApisixPluginRequest struct {
- Name string `json:"name"`
-}
-
-func (apr *ApisixPluginRequest) Schema() (map[string]interface{}, error) {
- url := fmt.Sprintf("%s/schema/plugins/%s", conf.BaseUrl, apr.Name)
- if resp, err := utils.Get(url); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- arresp := make(map[string]interface{})
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return arresp, nil
- }
- }
-}
-
-func (apr *ApisixPluginRequest) List() ([]string, error) {
-
- url := fmt.Sprintf("%s/plugins/list", conf.BaseUrl)
- if resp, err := utils.Get(url); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp []string
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return arresp, nil
- }
- }
-}
diff --git a/api/service/route.go b/api/service/route.go
deleted file mode 100644
index edea8e2..0000000
--- a/api/service/route.go
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 service
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os/exec"
- "strings"
- "time"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/log"
- "github.com/apisix/manager-api/utils"
- uuid "github.com/satori/go.uuid"
-)
-
-const (
- ContentType = "application/json"
- HTTP = "http"
- HTTPS = "https"
- SCHEME = "scheme"
- WEBSOCKET = "websocket"
- REDIRECT = "redirect"
- PROXY_REWRIETE = "proxy-rewrite"
- UPATHTYPE_STATIC = "static"
- UPATHTYPE_REGX = "regx"
- UPATHTYPE_KEEP = "keep"
-)
-
-var logger = log.GetLogger()
-
-func (r *RouteRequest) Parse(body interface{}) error {
- if err := json.Unmarshal(body.([]byte), r); err != nil {
- r = nil
- return err
- } else {
- if r.Uris == nil || len(r.Uris) < 1 {
- r.Uris = []string{"/*"}
- }
- if len(strings.Trim(r.RouteGroupId, "")) > 0 {
- routeGroup := &RouteGroupDao{}
- if err, _ := routeGroup.FindRouteGroup(r.RouteGroupId); err != nil {
- return err
- }
- r.RouteGroupName = routeGroup.Name
- }
- }
- return nil
-}
-
-func (arr *ApisixRouteRequest) Parse(r *RouteRequest) {
- arr.Desc = r.Desc
- arr.Priority = r.Priority
- arr.Methods = r.Methods
- arr.Uris = r.Uris
- arr.Hosts = r.Hosts
- arr.Vars = r.Vars
- arr.Upstream = r.Upstream
- arr.Plugins = r.Plugins
-}
-
-func (rd *Route) Parse(r *RouteRequest, arr *ApisixRouteRequest) error {
- //rd.Name = arr.Name
- rd.Description = arr.Desc
- rd.UpstreamId = r.UpstreamId
- rd.RouteGroupId = r.RouteGroupId
- rd.RouteGroupName = r.RouteGroupName
- rd.Status = r.Status
- if content, err := json.Marshal(r); err != nil {
- return err
- } else {
- rd.Content = string(content)
- }
- if script, err := json.Marshal(r.Script); err != nil {
- return err
- } else {
- rd.Script = string(script)
- }
- timestamp := time.Now().Unix()
- rd.CreateTime = timestamp
- rd.Priority = r.Priority
- return nil
-}
-
-func (arr *ApisixRouteRequest) FindById(rid string) (*ApisixRouteResponse, error) {
- url := fmt.Sprintf("%s/routes/%s", conf.BaseUrl, rid)
- if resp, err := utils.Get(url); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixRouteResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
-}
-
-func (arr *ApisixRouteRequest) Update(rid string) (*ApisixRouteResponse, error) {
- url := fmt.Sprintf("%s/routes/%s", conf.BaseUrl, rid)
- if b, err := json.Marshal(arr); err != nil {
- return nil, err
- } else {
- fmt.Println(string(b))
- if resp, err := utils.Put(url, b); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixRouteResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
- }
-}
-
-func (arr *ApisixRouteRequest) Create(rid string) (*ApisixRouteResponse, error) {
- url := fmt.Sprintf("%s/routes/%s", conf.BaseUrl, rid)
- if b, err := json.Marshal(arr); err != nil {
- return nil, err
- } else {
- fmt.Println(string(b))
- if resp, err := utils.Put(url, b); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixRouteResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
- }
-}
-
-func (arr *ApisixRouteRequest) Delete(rid string) (*ApisixRouteResponse, error) {
- url := fmt.Sprintf("%s/routes/%s", conf.BaseUrl, rid)
- if resp, err := utils.Delete(url); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixRouteResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
-}
-
-type RouteRequest struct {
- ID string `json:"id,omitempty"`
- Name string `json:"name"`
- Desc string `json:"desc,omitempty"`
- Priority int64 `json:"priority,omitempty"`
- Methods []string `json:"methods,omitempty"`
- Uris []string `json:"uris"`
- Hosts []string `json:"hosts,omitempty"`
- Protocols []string `json:"protocols,omitempty"`
- Redirect *Redirect `json:"redirect,omitempty"`
- Vars [][]string `json:"vars,omitempty"`
- Upstream *Upstream `json:"upstream,omitempty"`
- UpstreamId string `json:"upstream_id,omitempty"`
- UpstreamProtocol string `json:"upstream_protocol,omitempty"`
- UpstreamPath *UpstreamPath `json:"upstream_path,omitempty"`
- UpstreamHeader map[string]string `json:"upstream_header,omitempty"`
- Plugins map[string]interface{} `json:"plugins"`
- Script map[string]interface{} `json:"script"`
- RouteGroupId string `json:"route_group_id"`
- RouteGroupName string `json:"route_group_name"`
- Status bool `json:"status"`
-}
-
-func (r *ApisixRouteResponse) Parse() (*RouteRequest, error) {
- o := r.Node.Value
-
- //Protocols from vars and upstream
- protocols := make([]string, 0)
- if o.Upstream != nil && o.Upstream.EnableWebsocket {
- protocols = append(protocols, WEBSOCKET)
- }
- if o.UpstreamId != "" {
- protocols = append(protocols, WEBSOCKET)
- }
- flag := true
- for _, t := range o.Vars {
- if t[0] == SCHEME {
- flag = false
- protocols = append(protocols, t[2])
- }
- }
- if flag {
- protocols = append(protocols, HTTP)
- protocols = append(protocols, HTTPS)
- }
- //Redirect from plugins
- redirect := &Redirect{}
- upstreamProtocol := UPATHTYPE_KEEP
- upstreamHeader := make(map[string]string)
- upstreamPath := &UpstreamPath{}
- for k, v := range o.Plugins {
- if k == REDIRECT {
- if bytes, err := json.Marshal(v); err != nil {
- return nil, err
- } else {
- if err := json.Unmarshal(bytes, redirect); err != nil {
- return nil, err
- }
- }
-
- }
- if k == PROXY_REWRIETE {
- pr := &ProxyRewrite{}
- if bytes, err := json.Marshal(v); err != nil {
- return nil, err
- } else {
- if err := json.Unmarshal(bytes, pr); err != nil {
- return nil, err
- } else {
- if pr.Scheme != "" {
- upstreamProtocol = pr.Scheme
- }
- upstreamHeader = pr.Headers
- if (pr.RegexUri == nil || len(pr.RegexUri) < 2) && pr.Uri == "" {
- upstreamPath = nil
- } else if pr.RegexUri == nil || len(pr.RegexUri) < 2 {
- upstreamPath.UPathType = UPATHTYPE_STATIC
- upstreamPath.To = pr.Uri
- } else {
- upstreamPath.UPathType = UPATHTYPE_REGX
- upstreamPath.From = pr.RegexUri[0]
- upstreamPath.To = pr.RegexUri[1]
- }
- }
- }
- }
- }
- //Vars
- requestVars := make([][]string, 0)
- for _, t := range o.Vars {
- if t[0] != SCHEME {
- requestVars = append(requestVars, t)
- }
- }
- //Plugins
- requestPlugins := utils.CopyMap(o.Plugins)
- delete(requestPlugins, REDIRECT)
- delete(requestPlugins, PROXY_REWRIETE)
-
- // check if upstream is not exist
- if o.Upstream == nil && o.UpstreamId == "" {
- upstreamProtocol = ""
- upstreamHeader = nil
- upstreamPath = nil
- }
- if upstreamPath != nil && upstreamPath.UPathType == "" {
- upstreamPath = nil
- }
- result := &RouteRequest{
- ID: o.Id,
- Desc: o.Desc,
- Priority: o.Priority,
- Methods: o.Methods,
- Uris: o.Uris,
- Hosts: o.Hosts,
- Redirect: redirect,
- Upstream: o.Upstream,
- UpstreamId: o.UpstreamId,
- RouteGroupId: o.RouteGroupId,
- UpstreamProtocol: upstreamProtocol,
- UpstreamPath: upstreamPath,
- UpstreamHeader: upstreamHeader,
- Protocols: protocols,
- Vars: requestVars,
- Plugins: requestPlugins,
- }
- return result, nil
-}
-
-type Redirect struct {
- HttpToHttps bool `json:"http_to_https,omitempty"`
- Code int64 `json:"code,omitempty"`
- Uri string `json:"uri,omitempty"`
-}
-
-type ProxyRewrite struct {
- Uri string `json:"uri"`
- RegexUri []string `json:"regex_uri"`
- Scheme string `json:"scheme"`
- Host string `json:"host"`
- Headers map[string]string `json:"headers"`
-}
-
-func (r ProxyRewrite) MarshalJSON() ([]byte, error) {
- m := make(map[string]interface{})
- if r.RegexUri != nil {
- m["regex_uri"] = r.RegexUri
- }
- if r.Uri != "" {
- m["uri"] = r.Uri
- }
- if r.Scheme != UPATHTYPE_KEEP && r.Scheme != "" {
- m["scheme"] = r.Scheme
- }
- if r.Host != "" {
- m["host"] = r.Host
- }
- if r.Headers != nil && len(r.Headers) > 0 {
- m["headers"] = r.Headers
- }
- if result, err := json.Marshal(m); err != nil {
- return nil, err
- } else {
- return result, nil
- }
-}
-
-func (r Redirect) MarshalJSON() ([]byte, error) {
- m := make(map[string]interface{})
- if r.HttpToHttps {
- m["http_to_https"] = true
- } else if r.Uri != "" {
- m["code"] = r.Code
- m["uri"] = r.Uri
- }
- if result, err := json.Marshal(m); err != nil {
- return nil, err
- } else {
- return result, nil
- }
-}
-
-type Upstream struct {
- UType string `json:"type"`
- Nodes map[string]int64 `json:"nodes"`
- Timeout UpstreamTimeout `json:"timeout"`
- EnableWebsocket bool `json:"enable_websocket"`
- Checks map[string]interface{} `json:"checks,omitempty"`
- HashOn string `json:"hash_on,omitempty"`
- Key string `json:"key,omitempty"`
-}
-
-type UpstreamTimeout struct {
- Connect int64 `json:"connect"`
- Send int64 `json:"send"`
- Read int64 `json:"read"`
-}
-
-type UpstreamPath struct {
- UPathType string `json:"type"`
- From string `json:"from"`
- To string `json:"to"`
-}
-
-type ApisixRouteRequest struct {
- Desc string `json:"desc,omitempty"`
- Priority int64 `json:"priority"`
- Methods []string `json:"methods,omitempty"`
- Uris []string `json:"uris,omitempty"`
- Hosts []string `json:"hosts,omitempty"`
- Vars [][]string `json:"vars,omitempty"`
- Upstream *Upstream `json:"upstream,omitempty"`
- UpstreamId string `json:"upstream_id,omitempty"`
- Plugins map[string]interface{} `json:"plugins,omitempty"`
- Script string `json:"script,omitempty"`
- //Name string `json:"name"`
-}
-
-// ApisixRouteResponse is response from apisix admin api
-type ApisixRouteResponse struct {
- Action string `json:"action"`
- Node *Node `json:"node"`
-}
-
-type Node struct {
- Value Value `json:"value"`
- ModifiedIndex uint64 `json:"modifiedIndex"`
-}
-
-type Value struct {
- Id string `json:"id"`
- Name string `json:"name"`
- Desc string `json:"desc,omitempty"`
- Priority int64 `json:"priority"`
- Methods []string `json:"methods"`
- Uris []string `json:"uris"`
- Hosts []string `json:"hosts"`
- Vars [][]string `json:"vars"`
- Upstream *Upstream `json:"upstream,omitempty"`
- UpstreamId string `json:"upstream_id,omitempty"`
- Plugins map[string]interface{} `json:"plugins"`
- RouteGroupId string `json:"route_group_id"`
- RouteGroupName string `json:"route_group_name"`
- Status bool `json:"status"`
-}
-
-type Route struct {
- Base
- Name string `json:"name"`
- Description string `json:"description,omitempty"`
- Hosts string `json:"hosts"`
- Uris string `json:"uris"`
- UpstreamNodes string `json:"upstream_nodes"`
- UpstreamId string `json:"upstream_id"`
- Priority int64 `json:"priority"`
- Content string `json:"content"`
- Script string `json:"script"`
- ContentAdminApi string `json:"content_admin_api"`
- RouteGroupId string `json:"route_group_id"`
- RouteGroupName string `json:"route_group_name"`
- Status bool `json:"status"`
-}
-
-type RouteResponse struct {
- Base
- Name string `json:"name"`
- Description string `json:"description,omitempty"`
- Hosts []string `json:"hosts,omitempty"`
- Uris []string `json:"uris,omitempty"`
- Upstream *Upstream `json:"upstream,omitempty"`
- UpstreamId string `json:"upstream_id,omitempty"`
- Priority int64 `json:"priority"`
- RouteGroupId string `json:"route_group_id"`
- RouteGroupName string `json:"route_group_name"`
- Status bool `json:"status"`
-}
-
-type ListResponse struct {
- Count int `json:"count"`
- Data interface{} `json:"data"`
-}
-
-func (rr *RouteResponse) Parse(r *Route) {
- rr.Base = r.Base
- rr.Name = r.Name
- rr.Description = r.Description
- rr.UpstreamId = r.UpstreamId
- rr.Priority = r.Priority
- rr.RouteGroupId = r.RouteGroupId
- rr.RouteGroupName = r.RouteGroupName
- rr.Status = r.Status
- // hosts
- if len(r.Hosts) > 0 {
- var hosts []string
- if err := json.Unmarshal([]byte(r.Hosts), &hosts); err == nil {
- rr.Hosts = hosts
- } else {
- logger.Error(err.Error())
- }
- }
-
- // uris
- if len(r.Uris) > 0 {
- var uris []string
- if err := json.Unmarshal([]byte(r.Uris), &uris); err == nil {
- rr.Uris = uris
- }
- }
-
- // uris
- var resp ApisixRouteResponse
- if err := json.Unmarshal([]byte(r.ContentAdminApi), &resp); err == nil {
- rr.Upstream = resp.Node.Value.Upstream
- }
-}
-
-// RouteRequest -> ApisixRouteRequest
-func ToApisixRequest(routeRequest *RouteRequest) *ApisixRouteRequest {
- // redirect -> plugins
- plugins := utils.CopyMap(routeRequest.Plugins)
- redirect := routeRequest.Redirect
- if redirect != nil {
- plugins["redirect"] = redirect
- }
-
- logger.Info(routeRequest.Plugins)
-
- // scheme https and not http -> vars ['scheme', '==', 'https']
- pMap := utils.Set2Map(routeRequest.Protocols)
-
- arr := &ApisixRouteRequest{}
- arr.Parse(routeRequest)
-
- // protocols[websokect] -> upstream
- if pMap[WEBSOCKET] == 1 && arr.Upstream != nil {
- arr.Upstream.EnableWebsocket = true
- }
- vars := utils.CopyStrings(routeRequest.Vars)
- if pMap[HTTP] != 1 || pMap[HTTPS] != 1 {
- if pMap[HTTP] == 1 {
- vars = append(vars, []string{SCHEME, "==", HTTP})
- }
- if pMap[HTTPS] == 1 {
- vars = append(vars, []string{SCHEME, "==", HTTPS})
- }
- }
- if len(vars) > 0 {
- arr.Vars = vars
- } else {
- arr.Vars = nil
- }
- // upstreamId
- arr.UpstreamId = routeRequest.UpstreamId
- // upstream protocol
- if arr.Upstream != nil || arr.UpstreamId != "" {
- pr := &ProxyRewrite{}
- pr.Scheme = routeRequest.UpstreamProtocol
- // upstream path
- proxyPath := routeRequest.UpstreamPath
- if proxyPath != nil {
- if proxyPath.UPathType == UPATHTYPE_STATIC || proxyPath.UPathType == "" {
- pr.Uri = proxyPath.To
- pr.RegexUri = nil
- } else {
- pr.RegexUri = []string{proxyPath.From, proxyPath.To}
- }
- }
- // upstream headers
- pr.Headers = routeRequest.UpstreamHeader
- if proxyPath != nil || pr.Scheme != UPATHTYPE_KEEP || (pr.Headers != nil && len(pr.Headers) > 0) {
- plugins[PROXY_REWRIETE] = pr
- }
- }
-
- if plugins != nil && len(plugins) > 0 {
- arr.Plugins = plugins
- } else {
- arr.Plugins = nil
- }
-
- if routeRequest.Script != nil {
- arr.Script, _ = generateLuaCode(routeRequest.Script)
- }
-
- return arr
-}
-
-func generateLuaCode(script map[string]interface{}) (string, error) {
- scriptString, err := json.Marshal(script)
- if err != nil {
- return "", err
- }
-
- cmd := exec.Command("sh", "-c",
- "cd /go/manager-api/dag-to-lua/ && lua cli.lua "+
- "'"+string(scriptString)+"'")
-
- logger.Info("generate conf:", string(scriptString))
-
- stdout, _ := cmd.StdoutPipe()
- defer stdout.Close()
- if err := cmd.Start(); err != nil {
- logger.Info("generate err:", err)
- return "", err
- }
-
- result, _ := ioutil.ReadAll(stdout)
- resData := string(result)
-
- logger.Info("generated code:", resData)
-
- return resData, nil
-}
-
-func ToRoute(routeRequest *RouteRequest,
- arr *ApisixRouteRequest,
- u4 uuid.UUID,
- resp *ApisixRouteResponse) (*Route, *errno.ManagerError) {
- rd := &Route{}
- if err := rd.Parse(routeRequest, arr); err != nil {
- e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
- return nil, e
- }
- if rd.Name == "" {
- rd.Name = routeRequest.Name
- }
- rd.ID = u4
- // content_admin_api
- if resp != nil {
- resp.Node.Value.RouteGroupId = rd.RouteGroupId
- resp.Node.Value.Status = rd.Status
- if respStr, err := json.Marshal(resp); err != nil {
- e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
- return nil, e
- } else {
- rd.ContentAdminApi = string(respStr)
- }
- }
- // hosts
- hosts := routeRequest.Hosts
- if hb, err := json.Marshal(hosts); err != nil {
- e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
- logger.Warn(e.Msg)
- } else {
- rd.Hosts = string(hb)
- }
- // uris
- uris := routeRequest.Uris
- if ub, err := json.Marshal(uris); err != nil {
- e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
- logger.Warn(e.Msg)
- } else {
- rd.Uris = string(ub)
- }
- // upstreamNodes
- if routeRequest.Upstream != nil {
- nodes := routeRequest.Upstream.Nodes
- ips := make([]string, 0)
- for k, _ := range nodes {
- ips = append(ips, k)
- }
- if nb, err := json.Marshal(ips); err != nil {
- e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
- logger.Warn(e.Msg)
- } else {
- rd.UpstreamNodes = string(nb)
- }
- }
- // upstreamId
- rd.UpstreamId = arr.UpstreamId
- return rd, nil
-}
diff --git a/api/service/route_group.go b/api/service/route_group.go
deleted file mode 100644
index 8eb9a4d..0000000
--- a/api/service/route_group.go
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 service
-
-import (
- "encoding/json"
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- uuid "github.com/satori/go.uuid"
-)
-
-type RouteGroupDao struct {
- Base
- Name string `json:"name"`
- Description string `json:"description,omitempty"`
-}
-
-func (RouteGroupDao) TableName() string {
- return "route_group"
-}
-
-func (rd *RouteGroupDao) CreateRouteGroup() error {
- return conf.DB().Create(&rd).Error
-}
-
-func (rd *RouteGroupDao) FindRouteGroup(id string) (error, int) {
- var count int
- if err := conf.DB().Table("route_group").Where("id=?", id).Count(&count).Error; err != nil {
- return err, 0
- }
- conf.DB().Table("route_group").Where("id=?", id).First(&rd)
- return nil, count
-}
-
-func (rd *RouteGroupDao) GetRouteGroupList(routeGroupList *[]RouteGroupDao, search string, page, size int) (error, int) {
- db := conf.DB()
- db = db.Table(rd.TableName())
- if len(search) != 0 {
- db = db.Where("name like ? or description like ? ", search, search)
- }
- var count int
- if err := db.Order("update_time desc").Offset((page - 1) * size).Limit(size).Find(&routeGroupList).Error; err != nil {
- return err, 0
- } else {
- if err := db.Count(&count).Error; err != nil {
- return err, 0
- }
- return nil, count
- }
-}
-
-func (rd *RouteGroupDao) UpdateRouteGroup() error {
- db := conf.DB()
- tx := db.Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
- if err := tx.Model(&RouteGroupDao{}).Update(rd).Error; err != nil {
- tx.Rollback()
- return err
- }
- if err := tx.Table("routes").Where("route_group_id = ?", rd.ID.String()).Update("route_group_name", rd.Name).Error; err != nil {
- tx.Rollback()
- return err
- }
- if err := tx.Commit().Error; err != nil {
- tx.Rollback()
- return err
- }
- return nil
-}
-
-func (rd *RouteGroupDao) DeleteRouteGroup() error {
- if err, count := rd.FindRoute(); err != nil {
- e := errno.FromMessage(errno.RouteGroupSelectRoutesError, err.Error())
- logger.Error(e.Msg)
- return e
- } else {
- if count > 0 {
- e := errno.FromMessage(errno.RouteGroupHasRoutesError)
- logger.Error(e.Msg)
- return e
- }
- }
- return conf.DB().Delete(&rd).Error
-}
-
-type RouteGroupNameResponse struct {
- ID string `json:"id"`
- Name string `json:"name"`
-}
-
-func (u *RouteGroupDao) Parse2NameResponse() (*RouteGroupNameResponse, error) {
- // routeGroup
- unr := &RouteGroupNameResponse{
- ID: u.ID.String(),
- Name: u.Name,
- }
- return unr, nil
-}
-
-type RouteGroupRequest struct {
- Id string `json:"id,omitempty"`
- Name string `json:"name"`
- Description string `json:"description"`
-}
-
-func (u *RouteGroupRequest) toJson() []byte {
- res, _ := json.Marshal(&u)
- return res
-}
-
-func (r *RouteGroupRequest) Parse(body interface{}) error {
- if err := json.Unmarshal(body.([]byte), r); err != nil {
- r = nil
- return err
- }
- return nil
-}
-
-func Trans2RouteGroupDao(r *RouteGroupRequest) (*RouteGroupDao, *errno.ManagerError) {
-
- u := &RouteGroupDao{
- Name: r.Name,
- Description: r.Description,
- }
- // id
- u.ID = uuid.FromStringOrNil(r.Id)
- return u, nil
-}
-
-func (r *RouteGroupDao) FindRoute() (error, int) {
- var count int
- if err := conf.DB().Table("routes").Where("route_group_id=?", r.ID).Count(&count).Error; err != nil {
- return err, 0
- }
- return nil, count
-}
diff --git a/api/service/ssl.go b/api/service/ssl.go
deleted file mode 100644
index 2fbfbfd..0000000
--- a/api/service/ssl.go
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 service
-
-import (
- "crypto/md5"
- "crypto/tls"
- "crypto/x509"
- "encoding/json"
- "encoding/pem"
- "errors"
- "fmt"
- "regexp"
- "strings"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/utils"
- uuid "github.com/satori/go.uuid"
-)
-
-type Ssl struct {
- Base
- ValidityStart uint64 `json:"validity_start"`
- ValidityEnd uint64 `json:"validity_end"`
- Snis string `json:"snis"`
- Status uint64 `json:"status"`
- PublicKey string `json:"public_key,omitempty"`
- PublicKeyHash string `json:"public_key_hash,omitempty"`
-}
-
-type SslDto struct {
- Base
- ValidityStart uint64 `json:"validity_start"`
- ValidityEnd uint64 `json:"validity_end"`
- Snis []string `json:"snis"`
- Status uint64 `json:"status"`
- PublicKey string `json:"public_key,omitempty"`
-}
-
-type SslRequest struct {
- ID string `json:"id,omitempty"`
- PublicKey string `json:"cert,omitempty"`
- PrivateKey string `json:"key,omitempty"`
- Snis []string `json:"snis,omitempty"`
- Status uint64 `json:"status,omitempty"`
-}
-
-// ApisixSslResponse is response from apisix admin api
-type ApisixSslResponse struct {
- Action string `json:"action"`
- Node *SslNode `json:"node"`
-}
-
-type SslNode struct {
- Value SslRequest `json:"value"`
- ModifiedIndex uint64 `json:"modifiedIndex"`
-}
-
-func (req *SslRequest) Parse(body interface{}) {
- if err := json.Unmarshal(body.([]byte), req); err != nil {
- logger.Info("req:")
- logger.Info(req)
- req = nil
- }
-}
-
-func (sslDto *SslDto) Parse(ssl *Ssl) error {
- sslDto.ID = ssl.ID
- sslDto.ValidityStart = ssl.ValidityStart
- sslDto.ValidityEnd = ssl.ValidityEnd
-
- var snis []string
- _ = json.Unmarshal([]byte(ssl.Snis), &snis)
- sslDto.Snis = snis
-
- sslDto.Status = ssl.Status
- sslDto.PublicKey = ssl.PublicKey
- sslDto.CreateTime = ssl.CreateTime
- sslDto.UpdateTime = ssl.UpdateTime
-
- return nil
-}
-
-func SslList(page, size, status, expireStart, expireEnd int, sni, sortType string) (int, []SslDto, error) {
- var count int
- sslList := []Ssl{}
- db := conf.DB().Table("ssls")
-
- if sni != "" {
- db = db.Where("snis like ? ", "%"+sni+"%")
- }
- if status > -1 {
- db = db.Where("status = ? ", status)
- }
- if expireStart > 0 {
- db = db.Where("validity_end >= ? ", expireStart)
- }
- if expireEnd > 0 {
- db = db.Where("validity_end <= ? ", expireEnd)
- }
-
- sortType = strings.ToLower(sortType)
- if sortType != "desc" {
- sortType = "asc"
- }
-
- if err := db.Order("validity_end " + sortType).Offset((page - 1) * size).Limit(size).Find(&sslList).Error; err != nil {
- e := errno.New(errno.DBReadError, err.Error())
- return 0, nil, e
- }
- if err := db.Count(&count).Error; err != nil {
- e := errno.New(errno.DBReadError, err.Error())
- return 0, nil, e
- }
-
- sslDtoList := []SslDto{}
-
- for _, ssl := range sslList {
- sslDto := SslDto{}
- sslDto.Parse(&ssl)
-
- sslDtoList = append(sslDtoList, sslDto)
- }
-
- return count, sslDtoList, nil
-}
-
-func SslItem(id string) (*SslDto, error) {
- if id == "" {
- return nil, errno.New(errno.InvalidParam)
- }
- ssl := &Ssl{}
-
- if err := conf.DB().Table("ssls").Where("id = ?", id).First(ssl).Error; err != nil {
- e := errno.New(errno.DBReadError, err.Error())
- return nil, e
- }
-
- sslDto := &SslDto{}
- sslDto.Parse(ssl)
-
- return sslDto, nil
-}
-
-func SslCheck(param interface{}) (*SslDto, error) {
- sslReq := &SslRequest{}
- sslReq.Parse(param)
-
- ssl, err := ParseCert(sslReq.PublicKey, sslReq.PrivateKey)
-
- if err != nil {
- e := errno.FromMessage(errno.SslParseError, err.Error())
- return nil, e
- }
-
- ssl.PublicKey = ""
-
- sslDto := &SslDto{}
- sslDto.Parse(ssl)
-
- return sslDto, nil
-}
-
-func SslCreate(param interface{}, id string) error {
- sslReq := &SslRequest{}
- sslReq.Parse(param)
-
- if sslReq.PrivateKey == "" {
- return errno.New(errno.InvalidParamDetail, "Key is required")
- }
- if sslReq.PublicKey == "" {
- return errno.New(errno.InvalidParamDetail, "Cert is required")
- }
-
- sslReq.PublicKey = strings.TrimSpace(sslReq.PublicKey)
- sslReq.PrivateKey = strings.TrimSpace(sslReq.PrivateKey)
-
- ssl, err := ParseCert(sslReq.PublicKey, sslReq.PrivateKey)
- if err != nil {
- e := errno.FromMessage(errno.SslParseError, err.Error())
- return e
- }
-
- ssl.ID = uuid.FromStringOrNil(id)
- ssl.Status = 1
- data := []byte(ssl.PublicKey)
- hash := md5.Sum(data)
- ssl.PublicKeyHash = fmt.Sprintf("%x", hash)
-
- //check hash
- exists := Ssl{}
- conf.DB().Table("ssls").Where("public_key_hash = ?", ssl.PublicKeyHash).First(&exists)
- if exists != (Ssl{}) {
- e := errno.New(errno.DuplicateSslCert)
- return e
- }
-
- //check sni
- var snis []string
- _ = json.Unmarshal([]byte(ssl.Snis), &snis)
- sslReq.Snis = snis
-
- // trans
- tx := conf.DB().Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
-
- // update mysql
- if err := tx.Create(ssl).Error; err != nil {
- tx.Rollback()
- return errno.New(errno.DBWriteError, err.Error())
- }
-
- //admin api
-
- if _, err := sslReq.PutToApisix(id); err != nil {
- tx.Rollback()
- if _, ok := err.(*errno.HttpError); ok {
- return err
- }
- e := errno.New(errno.ApisixSslCreateError, err.Error())
- return e
- }
-
- tx.Commit()
-
- return nil
-}
-
-func SslUpdate(param interface{}, id string) error {
- if id == "" {
- return errno.New(errno.InvalidParam)
- }
-
- sslReq := &SslRequest{}
- sslReq.Parse(param)
-
- if sslReq.PrivateKey == "" {
- return errno.New(errno.InvalidParamDetail, "Key is required")
- }
- if sslReq.PublicKey == "" {
- return errno.New(errno.InvalidParamDetail, "Cert is required")
- }
-
- ssl, err := ParseCert(sslReq.PublicKey, sslReq.PrivateKey)
- if err != nil {
- return errno.FromMessage(errno.SslParseError, err.Error())
- }
-
- hash := md5.Sum([]byte(ssl.PublicKey))
- ssl.ID = uuid.FromStringOrNil(id)
- ssl.PublicKeyHash = fmt.Sprintf("%x", hash)
-
- //check hash
- exists := Ssl{}
- conf.DB().Table("ssls").Where("public_key_hash = ?", ssl.PublicKeyHash).First(&exists)
- if exists != (Ssl{}) && exists.ID != ssl.ID {
- e := errno.New(errno.DuplicateSslCert)
- return e
- }
-
- // trans
- tx := conf.DB().Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
-
- //sni check
- var snis []string
- _ = json.Unmarshal([]byte(ssl.Snis), &snis)
- sslReq.Snis = snis
-
- // update mysql
- data := Ssl{PublicKey: ssl.PublicKey, Snis: ssl.Snis, ValidityStart: ssl.ValidityStart, ValidityEnd: ssl.ValidityEnd}
- if err := tx.Model(&ssl).Updates(data).Error; err != nil {
- tx.Rollback()
- return errno.New(errno.DBWriteError, err.Error())
- }
-
- //admin api
- if _, err := sslReq.PutToApisix(id); err != nil {
- tx.Rollback()
- if _, ok := err.(*errno.HttpError); ok {
- return err
- }
- e := errno.New(errno.ApisixSslUpdateError, err.Error())
- return e
- }
-
- tx.Commit()
-
- return nil
-}
-
-func SslPatch(param interface{}, id string) error {
- if id == "" {
- return errno.New(errno.InvalidParam)
- }
-
- sslReq := &SslRequest{}
- sslReq.Parse(param)
-
- // trans
- tx := conf.DB().Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
-
- // update mysql
- ssl := Ssl{}
- ssl.ID = uuid.FromStringOrNil(id)
- if err := tx.Model(&ssl).Update("status", sslReq.Status).Error; err != nil {
- tx.Rollback()
- return errno.New(errno.DBWriteError, err.Error())
- }
-
- if _, err := sslReq.PatchToApisix(id); err != nil {
- tx.Rollback()
- if _, ok := err.(*errno.HttpError); ok {
- return err
- }
- e := errno.New(errno.ApisixSslUpdateError, err.Error())
- return e
- }
-
- tx.Commit()
-
- return nil
-}
-
-func SslDelete(id string) error {
- if id == "" {
- return errno.New(errno.InvalidParam)
- }
-
- // trans
- tx := conf.DB().Begin()
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- }
- }()
-
- // delete from mysql
- ssl := &Ssl{}
- ssl.ID = uuid.FromStringOrNil(id)
- if err := conf.DB().Delete(ssl).Error; err != nil {
- tx.Rollback()
- return errno.New(errno.DBDeleteError, err.Error())
- }
-
- // delete from apisix
- request := &SslRequest{}
- request.ID = id
- if _, err := request.DeleteFromApisix(); err != nil {
- tx.Rollback()
- if _, ok := err.(*errno.HttpError); ok {
- return err
- }
- e := errno.New(errno.ApisixSslDeleteError, err.Error())
- return e
- }
-
- tx.Commit()
-
- return nil
-}
-
-func (req *SslRequest) PatchToApisix(id string) (*ApisixSslResponse, error) {
- url := fmt.Sprintf("%s/ssl/%s", conf.BaseUrl, id)
- if data, err := json.Marshal(req); err != nil {
- return nil, err
- } else {
- if resp, err := utils.Patch(url, data); err != nil {
- logger.Error(url)
- logger.Error(string(data))
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixSslResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
- }
-}
-
-func (req *SslRequest) PutToApisix(rid string) (*ApisixSslResponse, error) {
- url := fmt.Sprintf("%s/ssl/%s", conf.BaseUrl, rid)
- if data, err := json.Marshal(req); err != nil {
- return nil, err
- } else {
- if resp, err := utils.Put(url, data); err != nil {
- logger.Error(url)
- logger.Error(string(data))
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixSslResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
- }
-}
-
-func (req *SslRequest) DeleteFromApisix() (*ApisixSslResponse, error) {
- id := req.ID
- url := fmt.Sprintf("%s/ssl/%s", conf.BaseUrl, id)
-
- if resp, err := utils.Delete(url); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixSslResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
-}
-
-func ParseCert(crt, key string) (*Ssl, error) {
- if crt == "" || key == "" {
- return nil, errors.New("invalid certificate")
- }
-
- certDERBlock, _ := pem.Decode([]byte(crt))
- if certDERBlock == nil {
- return nil, errors.New("Certificate resolution failed")
- }
- // match
- _, err := tls.X509KeyPair([]byte(crt), []byte(key))
- if err != nil {
- return nil, errors.New("key and cert don't match")
- }
-
- x509Cert, err := x509.ParseCertificate(certDERBlock.Bytes)
-
- if err != nil {
- return nil, errors.New("Certificate resolution failed")
- } else {
- ssl := Ssl{}
- //domain
- snis := []byte{}
- if x509Cert.DNSNames != nil && len(x509Cert.DNSNames) > 0 {
- snis, _ = json.Marshal(x509Cert.DNSNames)
- } else if x509Cert.IPAddresses != nil && len(x509Cert.IPAddresses) > 0 {
- snis, _ = json.Marshal(x509Cert.IPAddresses)
- } else {
- tmp := []string{}
-
- if x509Cert.Subject.Names != nil && len(x509Cert.Subject.Names) > 1 {
-
- var attributeTypeNames = map[string]string{
- "2.5.4.6": "C",
- "2.5.4.10": "O",
- "2.5.4.11": "OU",
- "2.5.4.3": "CN",
- "2.5.4.5": "SERIALNUMBER",
- "2.5.4.7": "L",
- "2.5.4.8": "ST",
- "2.5.4.9": "STREET",
- "2.5.4.17": "POSTALCODE",
- }
-
- for _, tv := range x509Cert.Subject.Names {
- oidString := tv.Type.String()
- typeName, ok := attributeTypeNames[oidString]
- if ok && typeName == "CN" {
- valueString := fmt.Sprint(tv.Value)
- tmp = append(tmp, valueString)
- }
-
- }
- }
-
- if len(tmp) < 1 && x509Cert.Subject.CommonName != "" {
- tmp = []string{x509Cert.Subject.CommonName}
- }
-
- snis, _ = json.Marshal(tmp)
- }
- ssl.Snis = string(snis)
-
- ssl.ValidityStart = uint64(x509Cert.NotBefore.Unix())
- ssl.ValidityEnd = uint64(x509Cert.NotAfter.Unix())
- ssl.PublicKey = crt
-
- return &ssl, nil
- }
-}
-
-func CheckSniExists(param interface{}) error {
- var hosts []string
- if err := json.Unmarshal(param.([]byte), &hosts); err != nil {
- return errno.FromMessage(errno.InvalidParam)
- }
-
- sslList := []Ssl{}
- db := conf.DB().Table("ssls")
- db = db.Where("`status` = ? ", 1)
-
- condition := ""
- args := []interface{}{}
- first := true
- for _, host := range hosts {
- idx := strings.Index(host, "*")
- keyword := strings.Replace(host, "*.", "", -1)
- if idx == -1 {
- if j := strings.Index(host, "."); j != -1 {
- keyword = host[j:]
- //just one `.`
- if j := strings.Index(host[(j+1):], "."); j == -1 {
- keyword = host
- }
- }
- }
- if first {
- condition = condition + "`snis` like ?"
- } else {
- condition = condition + " or `snis` like ?"
- }
- first = false
- args = append(args, "%"+keyword+"%")
- }
- db = db.Where(condition, args...)
-
- if err := db.Find(&sslList).Error; err != nil {
- return errno.FromMessage(errno.SslForSniNotExists, hosts[0])
- }
-
-hre:
- for _, host := range hosts {
- for _, ssl := range sslList {
- sslDto := SslDto{}
- sslDto.Parse(&ssl)
- for _, sni := range sslDto.Snis {
- if sni == host {
- continue hre
- }
- regx := strings.Replace(sni, ".", `\.`, -1)
- regx = strings.Replace(regx, "*", `([^\.]+)`, -1)
- regx = "^" + regx + "$"
- if isOk, _ := regexp.MatchString(regx, host); isOk {
- continue hre
- }
- }
- }
- return errno.FromMessage(errno.SslForSniNotExists, host)
- }
-
- return nil
-}
-
-func DeleteTestSslData() {
- db := conf.DB().Table("ssls")
- db.Where("snis LIKE ? OR (snis LIKE ? AND snis LIKE ? )", "%*.route.com%", "%r.com%", "%s.com%").Delete(Ssl{})
-}
diff --git a/api/service/upstream.go b/api/service/upstream.go
deleted file mode 100644
index 5b9d920..0000000
--- a/api/service/upstream.go
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 service
-
-import (
- "encoding/json"
- "fmt"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/errno"
- "github.com/apisix/manager-api/utils"
- uuid "github.com/satori/go.uuid"
-)
-
-type UpstreamDao struct {
- Base
- Name string `json:"name"`
- Description string `json:"description,omitempty"`
- Nodes string `json:"nodes"`
- Content string `json:"content"`
- ContentAdminApi string `json:"content_admin_api"`
-}
-
-func (UpstreamDao) TableName() string {
- return "upstreams"
-}
-
-type ApisixUpstreamRequest struct {
- Id string `json:"id"`
- Name string `json:"name"`
- Description string `json:"desc"`
- Upstream
-}
-
-func (u *ApisixUpstreamRequest) toJson() []byte {
- res, _ := json.Marshal(&u)
- return res
-}
-
-type UpstreamRequest struct {
- Id string `json:"id,omitempty"`
- Name string `json:"name"`
- Description string `json:"description"`
- Upstream
-}
-
-func (u *UpstreamRequest) toJson() []byte {
- res, _ := json.Marshal(&u)
- return res
-}
-
-func (r *UpstreamRequest) Parse(body interface{}) error {
- if err := json.Unmarshal(body.([]byte), r); err != nil {
- r = nil
- return err
- }
- return nil
-}
-
-func (r *UpstreamRequest) Parse2Apisix() (*ApisixUpstreamRequest, error) {
- aur := &ApisixUpstreamRequest{
- Id: r.Id,
- Name: r.Name,
- Description: r.Description,
- Upstream: r.Upstream,
- }
- return aur, nil
-}
-
-type UpstreamResponse struct {
- Base
- Name string `json:"name"`
- Description string `json:"description,omitempty"`
- 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{}
- if err := json.Unmarshal([]byte(u.ContentAdminApi), &aur); err != nil {
- return nil, err
- } else {
- v := aur.UNode.UValue
- result := &UpstreamResponse{
- Name: v.Name,
- Description: v.Description,
- }
- result.Base = u.Base
- result.Upstream = Upstream{
- UType: v.UType,
- Timeout: v.Timeout,
- Nodes: v.Nodes,
- EnableWebsocket: v.EnableWebsocket,
- }
- return result, nil
- }
-}
-
-type ApisixUpstreamResponse struct {
- Action string `json:"action"`
- UNode *UNode `json:"node"`
-}
-
-type UNode struct {
- UValue UValue `json:"value"`
- ModifiedIndex uint64 `json:"modifiedIndex"`
-}
-
-type UValue struct {
- Id string `json:"id"`
- Name string `json:"name"`
- Description string `json:"desc,omitempty"`
- Upstream
-}
-
-func (u *UValue) toJson() []byte {
- res, _ := json.Marshal(&u)
- return res
-}
-
-func (aur *ApisixUpstreamResponse) Parse2Request() (*UpstreamRequest, error) {
- v := aur.UNode.UValue
- result := &UpstreamRequest{
- Id: v.Id,
- Name: v.Name,
- Description: v.Description,
- Upstream: v.Upstream,
- }
- return result, nil
-}
-
-func Trans2UpstreamDao(resp *ApisixUpstreamResponse, r *UpstreamRequest) (*UpstreamDao, *errno.ManagerError) {
- ips := make([]string, 0)
- nodes := r.Nodes
- for k, _ := range nodes {
- ips = append(ips, k)
- }
- if nb, err := json.Marshal(ips); err != nil {
- e := errno.FromMessage(errno.DBUpstreamError, err.Error())
- logger.Warn(e.Msg)
- return nil, e
- } else {
- u := &UpstreamDao{
- Name: r.Name,
- Description: r.Description,
- Nodes: string(nb),
- }
- // id
- u.ID = uuid.FromStringOrNil(r.Id)
- // content
- if content, err := json.Marshal(r); err != nil {
- e := errno.FromMessage(errno.DBUpstreamError, err.Error())
- return nil, e
- } else {
- u.Content = string(content)
- }
- // content_admin_api
- if resp != nil {
- if respStr, err := json.Marshal(resp); err != nil {
- e := errno.FromMessage(errno.DBUpstreamError, err.Error())
- return nil, e
- } else {
- u.ContentAdminApi = string(respStr)
- }
- }
- return u, nil
- }
-}
-
-func (aur *ApisixUpstreamRequest) Create() (*ApisixUpstreamResponse, error) {
- url := fmt.Sprintf("%s/upstreams/%s", conf.BaseUrl, aur.Id)
- if b, err := json.Marshal(aur); err != nil {
- return nil, err
- } else {
- fmt.Println(string(b))
- if resp, err := utils.Put(url, b); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixUpstreamResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
- }
-}
-
-func (aur *ApisixUpstreamRequest) Update() (*ApisixUpstreamResponse, error) {
- url := fmt.Sprintf("%s/upstreams/%s", conf.BaseUrl, aur.Id)
- if b, err := json.Marshal(aur); err != nil {
- return nil, err
- } else {
- fmt.Println(string(b))
- if resp, err := utils.Put(url, b); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixUpstreamResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
- }
-}
-
-func (arr *ApisixUpstreamRequest) FindById() (*ApisixUpstreamResponse, error) {
- url := fmt.Sprintf("%s/upstreams/%s", conf.BaseUrl, arr.Id)
- if resp, err := utils.Get(url); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixUpstreamResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
-}
-
-func (arr *ApisixUpstreamRequest) Delete() (*ApisixUpstreamResponse, error) {
- url := fmt.Sprintf("%s/upstreams/%s", conf.BaseUrl, arr.Id)
- if resp, err := utils.Delete(url); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- var arresp ApisixUpstreamResponse
- if err := json.Unmarshal(resp, &arresp); err != nil {
- logger.Error(err.Error())
- return nil, err
- } else {
- return &arresp, nil
- }
- }
-}
diff --git a/api/utils/copy.go b/api/utils/copy.go
deleted file mode 100644
index 30f228a..0000000
--- a/api/utils/copy.go
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 utils
-
-func CopyMap(origin map[string]interface{}) map[string]interface{} {
- result := make(map[string]interface{})
- for k, v := range origin {
- result[k] = v
- }
- return result
-}
-
-func CopyStrings(origin [][]string) [][]string {
- result := make([][]string, 0)
- for _, s := range origin {
- result = append(result, s)
- }
- return result
-}
-
-func Set2Map(origin []string) map[string]int {
- result := make(map[string]int)
- for _, s := range origin {
- result[s] = 1
- }
- return result
-}
diff --git a/api/utils/http.go b/api/utils/http.go
deleted file mode 100644
index bdc9590..0000000
--- a/api/utils/http.go
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 utils
-
-import (
- "fmt"
- "net/http"
- "time"
-
- "github.com/apisix/manager-api/conf"
- "github.com/apisix/manager-api/log"
- "gopkg.in/resty.v1"
-)
-
-const timeout = 3000
-
-var logger = log.GetLogger()
-
-func Get(url string) ([]byte, error) {
- r := resty.New().
- SetTimeout(time.Duration(timeout)*time.Millisecond).
- R().
- SetHeader("content-type", "application/json").
- SetHeader("X-API-KEY", conf.ApiKey)
- resp, err := r.Get(url)
- if err != nil {
- return nil, err
- }
- if resp.StatusCode() != http.StatusOK {
- return nil, fmt.Errorf("status: %d, body: %s", resp.StatusCode(), resp.Body())
- }
- return resp.Body(), nil
-}
-
-func Post(url string, bytes []byte) ([]byte, error) {
- r := resty.New().
- SetTimeout(time.Duration(timeout)*time.Millisecond).
- R().
- SetHeader("content-type", "application/json").
- SetHeader("X-API-KEY", conf.ApiKey)
- r.SetBody(bytes)
- resp, err := r.Post(url)
- if err != nil {
- return nil, err
- }
- if resp.StatusCode() != http.StatusOK && resp.StatusCode() != http.StatusCreated {
- return nil, fmt.Errorf("status: %d, body: %s", resp.StatusCode(), resp.Body())
- }
- return resp.Body(), nil
-}
-
-func Put(url string, bytes []byte) ([]byte, error) {
- r := resty.New().
- SetTimeout(time.Duration(timeout)*time.Millisecond).
- R().
- SetHeader("content-type", "application/json").
- SetHeader("X-API-KEY", conf.ApiKey)
- r.SetBody(bytes)
- resp, err := r.Put(url)
- if err != nil {
- return nil, err
- }
- if resp.StatusCode() != http.StatusOK && resp.StatusCode() != http.StatusCreated {
- return nil, fmt.Errorf("status: %d, body: %s", resp.StatusCode(), resp.Body())
- }
- return resp.Body(), nil
-}
-
-func Patch(url string, bytes []byte) ([]byte, error) {
- r := resty.New().
- SetTimeout(time.Duration(timeout)*time.Millisecond).
- R().
- SetHeader("content-type", "application/json").
- SetHeader("X-API-KEY", conf.ApiKey)
- r.SetBody(bytes)
- resp, err := r.Patch(url)
- if err != nil {
- return nil, err
- }
- if resp.StatusCode() != http.StatusOK {
- return nil, fmt.Errorf("status: %d, body: %s", resp.StatusCode(), resp.Body())
- }
- return resp.Body(), nil
-}
-
-func Delete(url string) ([]byte, error) {
- r := resty.New().
- SetTimeout(time.Duration(timeout)*time.Millisecond).
- R().
- SetHeader("content-type", "application/json").
- SetHeader("X-API-KEY", conf.ApiKey)
- resp, err := r.Delete(url)
- if err != nil {
- return nil, err
- }
- if resp.StatusCode() != http.StatusOK {
- return nil, fmt.Errorf("status: %d, body: %s", resp.StatusCode(), resp.Body())
- }
- return resp.Body(), nil
-}