Skip to content

Commit

Permalink
feat: generate create/update_time automatically
Browse files Browse the repository at this point in the history
Close #2654.
  • Loading branch information
spacewander committed Nov 13, 2020
1 parent 358d83a commit d44e914
Show file tree
Hide file tree
Showing 13 changed files with 433 additions and 22 deletions.
14 changes: 14 additions & 0 deletions apisix/admin/consumers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
--
local core = require("apisix.core")
local plugins = require("apisix.admin.plugins")
local utils = require("apisix.admin.utils")
local plugin = require("apisix.plugin")
local pairs = pairs

Expand Down Expand Up @@ -76,6 +77,19 @@ function _M.put(consumer_name, conf)

local key = "/consumers/" .. consumer_name
core.log.info("key: ", key)

local res, err = core.etcd.get(key)
if not res or (res.status ~= 200 and res.status ~= 404) then
core.log.error("failed to get consumer[", key, "] from etcd: ", err or res.status)
return 500, {error_msg = err}
end

if res.status == 404 then
utils.inject_timestamp(conf)
else
utils.inject_timestamp(conf, res.body)
end

local res, err = core.etcd.set(key, conf)
if not res then
core.log.error("failed to put consumer[", key, "]: ", err)
Expand Down
17 changes: 17 additions & 0 deletions apisix/admin/routes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
local core = require("apisix.core")
local schema_plugin = require("apisix.admin.plugins").check_schema
local upstreams = require("apisix.admin.upstreams")
local utils = require("apisix.admin.utils")
local tostring = tostring
local type = type
local loadstring = loadstring
Expand Down Expand Up @@ -147,6 +148,19 @@ function _M.put(id, conf, sub_path, args)
end

local key = "/routes/" .. id

local res, err = core.etcd.get(key)
if not res or (res.status ~= 200 and res.status ~= 404) then
core.log.error("failed to get route[", key, "] from etcd: ", err or res.status)
return 500, {error_msg = err}
end

if res.status == 404 then
utils.inject_timestamp(conf)
else
utils.inject_timestamp(conf, res.body)
end

local res, err = core.etcd.set(key, conf, args.ttl)
if not res then
core.log.error("failed to put route[", key, "] to etcd: ", err)
Expand Down Expand Up @@ -181,6 +195,7 @@ function _M.post(id, conf, sub_path, args)

local key = "/routes"
-- core.log.info("key: ", key)
utils.inject_timestamp(conf)
local res, err = core.etcd.push("/routes", conf, args.ttl)
if not res then
core.log.error("failed to post route[", key, "] to etcd: ", err)
Expand Down Expand Up @@ -253,6 +268,8 @@ function _M.patch(id, conf, sub_path, args)
node_value = core.table.merge(node_value, conf);
end

utils.inject_timestamp(node_value, nil, conf)

core.log.info("new conf: ", core.json.delay_encode(node_value, true))

local id, err = check_conf(id, node_value, true)
Expand Down
18 changes: 18 additions & 0 deletions apisix/admin/services.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ local core = require("apisix.core")
local get_routes = require("apisix.router").http_routes
local schema_plugin = require("apisix.admin.plugins").check_schema
local upstreams = require("apisix.admin.upstreams")
local utils = require("apisix.admin.utils")
local tostring = tostring
local ipairs = ipairs
local type = type
Expand Down Expand Up @@ -116,6 +117,20 @@ function _M.put(id, conf)

local key = "/services/" .. id
core.log.info("key: ", key)

local res, err = core.etcd.get(key)
if not res or (res.status ~= 200 and res.status ~= 404) then
core.log.error("failed to get service[", key, "] from etcd: ",
err or res.status)
return 500, {error_msg = err}
end

if res.status == 404 then
utils.inject_timestamp(conf)
else
utils.inject_timestamp(conf, res.body)
end

local res, err = core.etcd.set(key, conf)
if not res then
core.log.error("failed to put service[", key, "]: ", err)
Expand Down Expand Up @@ -149,6 +164,7 @@ function _M.post(id, conf)
end

local key = "/services"
utils.inject_timestamp(conf)
local res, err = core.etcd.push(key, conf)
if not res then
core.log.error("failed to post service[", key, "]: ", err)
Expand Down Expand Up @@ -231,6 +247,8 @@ function _M.patch(id, conf, sub_path)
node_value = core.table.merge(node_value, conf);
end

utils.inject_timestamp(node_value, nil, conf)

core.log.info("new value ", core.json.delay_encode(node_value, true))

local id, err = check_conf(id, node_value, true)
Expand Down
18 changes: 18 additions & 0 deletions apisix/admin/ssl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
-- limitations under the License.
--
local core = require("apisix.core")
local utils = require("apisix.admin.utils")
local tostring = tostring
local aes = require "resty.aes"
local ngx_encode_base64 = ngx.encode_base64
Expand Down Expand Up @@ -103,6 +104,20 @@ function _M.put(id, conf)
end

local key = "/ssl/" .. id

local res, err = core.etcd.get(key)
if not res or (res.status ~= 200 and res.status ~= 404) then
core.log.error("failed to get ssl[", key, "] from etcd: ",
err or res.status)
return 500, {error_msg = err}
end

if res.status == 404 then
utils.inject_timestamp(conf)
else
utils.inject_timestamp(conf, res.body)
end

local res, err = core.etcd.set(key, conf)
if not res then
core.log.error("failed to put ssl[", key, "]: ", err)
Expand Down Expand Up @@ -151,6 +166,7 @@ function _M.post(id, conf)

local key = "/ssl"
-- core.log.info("key: ", key)
utils.inject_timestamp(conf)
local res, err = core.etcd.push("/ssl", conf)
if not res then
core.log.error("failed to post ssl[", key, "]: ", err)
Expand Down Expand Up @@ -214,6 +230,8 @@ function _M.patch(id, conf)

node_value = core.table.merge(node_value, conf);

utils.inject_timestamp(node_value, nil, conf)

core.log.info("new ssl conf: ", core.json.delay_encode(node_value, true))

local id, err = check_conf(id, node_value, true)
Expand Down
18 changes: 18 additions & 0 deletions apisix/admin/upstreams.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
local core = require("apisix.core")
local get_routes = require("apisix.router").http_routes
local get_services = require("apisix.http.service").services
local utils = require("apisix.admin.utils")
local tostring = tostring
local ipairs = ipairs
local type = type
Expand Down Expand Up @@ -135,6 +136,20 @@ function _M.put(id, conf)

local key = "/upstreams/" .. id
core.log.info("key: ", key)

local res, err = core.etcd.get(key)
if not res or (res.status ~= 200 and res.status ~= 404) then
core.log.error("failed to get upstream[", key, "] from etcd: ",
err or res.status)
return 500, {error_msg = err}
end

if res.status == 404 then
utils.inject_timestamp(conf)
else
utils.inject_timestamp(conf, res.body)
end

local res, err = core.etcd.set(key, conf)
if not res then
core.log.error("failed to put upstream[", key, "]: ", err)
Expand Down Expand Up @@ -168,6 +183,7 @@ function _M.post(id, conf)
end

local key = "/upstreams"
utils.inject_timestamp(conf)
local res, err = core.etcd.push(key, conf)
if not res then
core.log.error("failed to post upstream[", key, "]: ", err)
Expand Down Expand Up @@ -265,6 +281,8 @@ function _M.patch(id, conf, sub_path)
new_value = core.table.merge(new_value, conf);
end

utils.inject_timestamp(new_value, nil, conf)

core.log.info("new value ", core.json.delay_encode(new_value, true))

local id, err = check_conf(id, new_value, true)
Expand Down
41 changes: 41 additions & 0 deletions apisix/admin/utils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--
-- 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.
--
local ngx_time = ngx.time


local _M = {}


function _M.inject_timestamp(conf, prev_conf, patch_conf)
if not conf.create_time then
if prev_conf and prev_conf.node.value.create_time then
conf.create_time = prev_conf.node.value.create_time
end

-- As we don't know existent data's create_time, we have to pretend
-- they are created now.
conf.create_time = ngx_time()
end

-- For PATCH request, the modification is passed as 'patch_conf'
if not conf.update_time or (patch_conf and patch_conf.update_time == nil) then
conf.update_time = ngx_time()
end
end


return _M
20 changes: 10 additions & 10 deletions doc/admin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@
|service_protocol|False|Upstream protocol type|only `grpc` and `http` are supported|`http` is the default value; Must set `grpc` if using `gRPC proxy` or `gRPC transcode`|
|labels |False |Match Rules|Key/value pairs to specify attributes|{"version":"v2","build":"16","env":"production"}|
|enable_websocket|False|Auxiliary| enable `websocket`(boolean), default `false`.||
|create_time|False| Auxiliary|epoch timestamp in second| 1602883670|
|update_time|False| Auxiliary|epoch timestamp in second| 1602883670|
|create_time|False| Auxiliary|epoch timestamp in second, will be created automatically if missing | 1602883670|
|update_time|False| Auxiliary|epoch timestamp in second, will be created automatically if missing | 1602883670|

For the same type of parameters, such as `host` and `hosts`, `remote_addr` and `remote_addrs` cannot exist at the same time, only one of them can be selected. If enabled at the same time, the API will response an error.

Expand Down Expand Up @@ -295,8 +295,8 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13
|desc |False |Auxiliary |service usage scenarios, and more.|customer xxxx|
|labels |False |Match Rules|Key/value pairs to specify attributes|{"version":"v2","build":"16","env":"production"}|
|enable_websocket|False|Auxiliary| enable `websocket`(boolean), default `false`.||
|create_time|False| Auxiliary|epoch timestamp in second| 1602883670|
|update_time|False| Auxiliary|epoch timestamp in second| 1602883670|
|create_time|False| Auxiliary|epoch timestamp in second, will be created automatically if missing | 1602883670|
|update_time|False| Auxiliary|epoch timestamp in second, will be created automatically if missing | 1602883670|

Config Example:

Expand Down Expand Up @@ -437,8 +437,8 @@ Return response from etcd currently.
|plugins |False |Plugin|See [Plugin](architecture-design.md#plugin) for more ||
|desc |False |Auxiliary |Identifies route names, usage scenarios, and more.|customer xxxx|
|labels |False |Match Rules|Key/value pairs to specify attributes|{"version":"v2","build":"16","env":"production"}|
|create_time|False| Auxiliary|epoch timestamp in second| 1602883670|
|update_time|False| Auxiliary|epoch timestamp in second| 1602883670|
|create_time|False| Auxiliary|epoch timestamp in second, will be created automatically if missing | 1602883670|
|update_time|False| Auxiliary|epoch timestamp in second, will be created automatically if missing | 1602883670|

Config Example:

Expand Down Expand Up @@ -520,8 +520,8 @@ In addition to the basic complex equalization algorithm selection, APISIX's Upst
|pass_host |optional|`pass` pass the client request host, `node` not pass the client request host, using the upstream node host, `rewrite` rewrite host by the configured `upstream_host`.|
|upstream_host |optional|This option is only valid if the `pass_host` is `rewrite`.|
|labels|optional |Key/value pairs to specify attributes|{"version":"v2","build":"16","env":"production"}|
|create_time|optional| epoch timestamp in second, like `1602883670`|
|update_time|optional| epoch timestamp in second, like `1602883670`|
|create_time|optional| epoch timestamp in second, like `1602883670`, will be created automatically if missing|
|update_time|optional| epoch timestamp in second, like `1602883670`, will be created automatically if missing|


Config Example:
Expand Down Expand Up @@ -664,8 +664,8 @@ Return response from etcd currently.
|key|True|Private key|https Private key||
|sni|True|Match Rules|https SNI||
|labels|False |Match Rules|Key/value pairs to specify attributes|{"version":"v2","build":"16","env":"production"}|
|create_time|False| Auxiliary|epoch timestamp in second| 1602883670|
|update_time|False| Auxiliary|epoch timestamp in second| 1602883670|
|create_time|False| Auxiliary|epoch timestamp in second, will be created automatically if missing | 1602883670|
|update_time|False| Auxiliary|epoch timestamp in second, will be created automatically if missing | 1602883670|

Config Example:

Expand Down
20 changes: 10 additions & 10 deletions doc/zh-cn/admin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@
|filter_func|可选|匹配规则|用户自定义的过滤函数。可以使用它来实现特殊场景的匹配要求实现。该函数默认接受一个名为 vars 的输入参数,可以用它来获取 Nginx 变量。|function(vars) return vars["arg_name"] == "json" end|
|labels |可选 |匹配规则|标识附加属性的键值对|{"version":"v2","build":"16","env":"production"}|
|enable_websocket|可选 |辅助| 是否启用 `websocket`(boolean), 缺省 `false`.||
|create_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|create_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|

有两点需要特别注意:

Expand Down Expand Up @@ -305,8 +305,8 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13
|desc |可选 |辅助 |服务描述、使用场景等。||
|labels |可选 |匹配规则|标识附加属性的键值对|{"version":"v2","build":"16","env":"production"}|
|enable_websocket|可选 |辅助| 是否启用 `websocket`(boolean), 缺省 `false`.||
|create_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|create_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|

serivce 对象 json 配置内容:

Expand Down Expand Up @@ -450,8 +450,8 @@ HTTP/1.1 200 OK
|plugins|可选|Plugin|该 Consumer 对应的插件配置,它的优先级是最高的:Consumer > Route > Service。对于具体插件配置,可以参考 [Plugins](#plugin) 章节。||
|desc |可选 |辅助|consumer描述||
|labels |可选 |匹配规则|标识附加属性的键值对|{"version":"v2","build":"16","env":"production"}|
|create_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|create_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|

consumer 对象 json 配置内容:

Expand Down Expand Up @@ -534,8 +534,8 @@ APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上
|pass_host |可选|枚举|`pass` 透传客户端请求的 host, `node` 不透传客户端请求的 host, 使用 upstream node 配置的 host, `rewrite` 使用 `upstream_host` 配置的值重写 host 。||
|upstream_host |可选|辅助|只在 `pass_host` 配置为 `rewrite` 时有效。||
|labels |可选 |匹配规则|标识附加属性的键值对|{"version":"v2","build":"16","env":"production"}|
|create_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|create_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|

upstream 对象 json 配置内容:

Expand Down Expand Up @@ -676,8 +676,8 @@ HTTP/1.1 200 OK
|key|必需|私钥|https 证书私钥||
|sni|必需|匹配规则|https 证书SNI||
|labels|可选|匹配规则|标识附加属性的键值对|{"version":"v2","build":"16","env":"production"}|
|create_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳|1602883670|
|create_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|
|update_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670|

ssl 对象 json 配置内容:

Expand Down
13 changes: 13 additions & 0 deletions t/admin/consumers.t
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ passed
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local etcd = require("apisix.core.etcd")
local res = assert(etcd.get('/consumers/jack'))
local prev_create_time = res.body.node.value.create_time
assert(prev_create_time ~= nil, "create_time is nil")
local update_time = res.body.node.value.update_time
assert(update_time ~= nil, "update_time is nil")

local code, body = t('/apisix/admin/consumers',
ngx.HTTP_PUT,
[[{
Expand Down Expand Up @@ -95,6 +102,12 @@ passed

ngx.status = code
ngx.say(body)

local res = assert(etcd.get('/consumers/jack'))
local create_time = res.body.node.value.create_time
assert(prev_create_time == create_time, "create_time mismatched")
local update_time = res.body.node.value.update_time
assert(update_time ~= nil, "update_time is nil")
}
}
--- request
Expand Down
Loading

0 comments on commit d44e914

Please sign in to comment.