Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support patch in route module in order to support publish/offline #1049

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/build-tools/schema-sync.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ local fake_module_list = {
'cjson.safe',
'bit',
'lfs',
'ngx.worker',
'ngx.errlog',
'ngx.process',
'ngx.re',
'net.url',
Expand Down Expand Up @@ -80,10 +82,12 @@ ngx.timer = {}
ngx.location = {}
ngx.socket = {}
ngx.thread = {}
ngx.worker = {}
ngx.re.gmatch = empty_function
ngx.shared = {
["plugin-api-breaker"] = {}
}
ngx.shared.internal_status = {}

-- additional define for management
local time_def = {
Expand Down
101 changes: 76 additions & 25 deletions api/conf/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,19 @@
}]
},
"ip_def": [{
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$",
"format": "ipv4",
"title": "IPv4",
"type": "string"
}, {
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$",
"title": "IPv4/CIDR",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$",
"format": "ipv6",
"title": "IPv6",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"title": "IPv6/CIDR",
"type": "string"
}],
Expand Down Expand Up @@ -147,6 +147,41 @@
},
"route": {
"additionalProperties": false,
"allOf": [{
"oneOf": [{
"required": ["uri"]
}, {
"required": ["uris"]
}]
}, {
"oneOf": [{
"not": {
"anyOf": [{
"required": ["host"]
}, {
"required": ["hosts"]
}]
}
}, {
"required": ["host"]
}, {
"required": ["hosts"]
}]
}, {
"oneOf": [{
"not": {
"anyOf": [{
"required": ["remote_addr"]
}, {
"required": ["remote_addrs"]
}]
}
}, {
"required": ["remote_addr"]
}, {
"required": ["remote_addrs"]
}]
}],
"anyOf": [{
"required": ["plugins", "uri"]
}, {
Expand Down Expand Up @@ -199,6 +234,7 @@
"pattern": "^\\*?[0-9a-zA-Z-.]+$",
"type": "string"
},
"minItems": 1,
"type": "array",
"uniqueItems": true
},
Expand Down Expand Up @@ -250,19 +286,19 @@
},
"remote_addr": {
"anyOf": [{
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$",
"format": "ipv4",
"title": "IPv4",
"type": "string"
}, {
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$",
"title": "IPv4/CIDR",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$",
"format": "ipv6",
"title": "IPv6",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"title": "IPv6/CIDR",
"type": "string"
}],
Expand All @@ -272,25 +308,26 @@
"remote_addrs": {
"items": {
"anyOf": [{
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$",
"format": "ipv4",
"title": "IPv4",
"type": "string"
}, {
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$",
"title": "IPv4/CIDR",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$",
"format": "ipv6",
"title": "IPv6",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"title": "IPv6/CIDR",
"type": "string"
}],
"description": "client IP",
"type": "string"
},
"minItems": 1,
"type": "array",
"uniqueItems": true
},
Expand All @@ -313,6 +350,12 @@
"service_protocol": {
"enum": ["grpc", "http"]
},
"status": {
"default": 1,
"description": "route status, 1 to enable, 0 to disable",
"enum": [0, 1],
"type": "integer"
},
"update_time": {
"type": "integer"
},
Expand Down Expand Up @@ -707,6 +750,7 @@
"description": "HTTP uri",
"type": "string"
},
"minItems": 1,
"type": "array",
"uniqueItems": true
},
Expand Down Expand Up @@ -1281,19 +1325,19 @@
},
"remote_addr": {
"anyOf": [{
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$",
"format": "ipv4",
"title": "IPv4",
"type": "string"
}, {
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$",
"title": "IPv4/CIDR",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$",
"format": "ipv6",
"title": "IPv6",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"title": "IPv6/CIDR",
"type": "string"
}],
Expand All @@ -1302,19 +1346,19 @@
},
"server_addr": {
"anyOf": [{
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$",
"format": "ipv4",
"title": "IPv4",
"type": "string"
}, {
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$",
"title": "IPv4/CIDR",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$",
"format": "ipv6",
"title": "IPv6",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"title": "IPv6/CIDR",
"type": "string"
}],
Expand Down Expand Up @@ -2307,7 +2351,7 @@
"properties": {
"allow_credential": {
"default": false,
"description": "allow client append credential. according to CORS specification, if you set this option to 'true', you can not use '*' for other options.",
"description": "allow client append credential. according to CORS specification,if you set this option to 'true', you can not use '*' for other options.",
"type": "boolean"
},
"allow_headers": {
Expand Down Expand Up @@ -2406,7 +2450,6 @@
"minProperties": 1,
"properties": {
"abort": {
"minProperties": 1,
"properties": {
"body": {
"minLength": 0,
Expand All @@ -2422,10 +2465,10 @@
"type": "integer"
}
},
"required": ["http_status"],
"type": "object"
},
"delay": {
"minProperties": 1,
"properties": {
"duration": {
"minimum": 0,
Expand All @@ -2437,6 +2480,7 @@
"type": "integer"
}
},
"required": ["duration"],
"type": "object"
}
},
Expand Down Expand Up @@ -2620,19 +2664,19 @@
"whitelist": {
"items": {
"anyOf": [{
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$",
"format": "ipv4",
"title": "IPv4",
"type": "string"
}, {
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$",
"title": "IPv4/CIDR",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$",
"format": "ipv6",
"title": "IPv6",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"title": "IPv6/CIDR",
"type": "string"
}]
Expand All @@ -2649,19 +2693,19 @@
"blacklist": {
"items": {
"anyOf": [{
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$",
"format": "ipv4",
"title": "IPv4",
"type": "string"
}, {
"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$",
"title": "IPv4/CIDR",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$",
"format": "ipv6",
"title": "IPv6",
"type": "string"
}, {
"pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
"title": "IPv6/CIDR",
"type": "string"
}]
Expand Down Expand Up @@ -2891,6 +2935,7 @@
"type": "integer"
},
"key": {
"default": "remote_addr",
"enum": ["consumer_name", "http_x_forwarded_for", "http_x_real_ip", "remote_addr", "server_addr", "service_id"],
"type": "string"
},
Expand All @@ -2910,7 +2955,7 @@
"type": "integer"
}
},
"required": ["count", "key", "time_window"],
"required": ["count", "time_window"],
"type": "object"
}
},
Expand Down Expand Up @@ -3240,6 +3285,12 @@
"type": "object"
}
},
"server-info": {
"schema": {
"additionalProperties": false,
"type": "object"
}
},
"serverless-post-function": {
"schema": {
"properties": {
Expand Down
36 changes: 36 additions & 0 deletions api/filter/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ var resources = map[string]string{
"ssl": "ssl",
}


type Status int

const (
StatusDisable Status = iota
StatusEnable
)

func parseCert(crt, key string) ([]string, error) {
if crt == "" || key == "" {
return nil, errors.New("invalid certificate")
Expand Down Expand Up @@ -136,6 +144,25 @@ func handleSpecialField(resource string, reqBody []byte) ([]byte, error) {
return reqBody, nil
}

func handleDefaultValue(resource string, reqBody []byte) ([]byte, error) {
// go jsonschema lib doesn't support setting default values, so we need to set for some fields necessary
if resource == "routes" {
var route map[string]interface{}
err := json.Unmarshal(reqBody, &route)
if err != nil {
return reqBody, fmt.Errorf("read request body failed: %s", err)
}
if _, ok := route["status"]; !ok {
route["status"] = StatusEnable
reqBody, err = json.Marshal(route)
if err != nil {
return nil, fmt.Errorf("read request body failed: %s", err)
}
}
}
return reqBody, nil
}

func SchemaCheck() gin.HandlerFunc {
return func(c *gin.Context) {
pathPrefix := "/apisix/admin/"
Expand Down Expand Up @@ -164,6 +191,15 @@ func SchemaCheck() gin.HandlerFunc {
return
}

// set default value
reqBody, err = handleDefaultValue(resource, reqBody)
if err != nil {
errMsg := err.Error()
c.AbortWithStatusJSON(http.StatusBadRequest, consts.InvalidParam(errMsg))
log.Error(errMsg)
return
}

// other filter need it
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody))

Expand Down
1 change: 1 addition & 0 deletions api/internal/core/entity/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type Route struct {
ServiceProtocol string `json:"service_protocol,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
EnableWebsocket bool `json:"enable_websocket,omitempty"`
Status uint8 `json:"status"`
juzhiyuan marked this conversation as resolved.
Show resolved Hide resolved
}

// --- structures for upstream start ---
Expand Down
Loading