function _M:patch()

in apisix/admin/resource.lua [360:462]


function _M:patch(id, conf, sub_path, args)
    if core.table.array_find(self.unsupported_methods, "patch") then
        return 405, {error_msg = "not supported `PATCH` method for " .. self.kind}
    end

    local key = "/" .. self.name
    local typ = nil
    if self.name == "secrets" then
        local uri_segs = core.utils.split_uri(sub_path)
        if #uri_segs < 1 then
            return 400, {error_msg = "no secret id"}
        end
        typ = id
        id = uri_segs[1]
        sub_path = core.table.concat(uri_segs, "/", 2)
    end

    if not id then
        return 400, {error_msg = "missing " .. self.kind .. " id"}
    end

    if self.name == "secrets" then
        key = key .. "/" .. typ
    end

    key = key .. "/" .. id

    if conf == nil then
        return 400, {error_msg = "missing new configuration"}
    end

    if not sub_path or sub_path == "" then
        if type(conf) ~= "table"  then
            return 400, {error_msg = "invalid configuration"}
        end
    end

    local res_old, err = core.etcd.get(key)
    if not res_old then
        core.log.error("failed to get ", self.kind, " [", key, "] in etcd: ", err)
        return 503, {error_msg = err}
    end

    if res_old.status ~= 200 then
        return res_old.status, res_old.body
    end
    core.log.info("key: ", key, " old value: ", core.json.delay_encode(res_old, true))

    local node_value = res_old.body.node.value
    local modified_index = res_old.body.node.modifiedIndex

    if sub_path and sub_path ~= "" then
        if self.name == "ssls" then
            if sub_path == "key" then
                conf = apisix_ssl.aes_encrypt_pkey(conf)
            elseif sub_path == "keys" then
                for i = 1, #conf do
                    conf[i] = apisix_ssl.aes_encrypt_pkey(conf[i])
                end
            end
        end
        local code, err, node_val = core.table.patch(node_value, sub_path, conf)
        node_value = node_val
        if code then
            return code, {error_msg = err}
        end
        utils.inject_timestamp(node_value, nil, true)
    else
        if self.name == "ssls" then
            if conf.key then
                conf.key = apisix_ssl.aes_encrypt_pkey(conf.key)
            end

            if conf.keys then
                for i = 1, #conf.keys do
                    conf.keys[i] = apisix_ssl.aes_encrypt_pkey(conf.keys[i])
                end
            end
        end
        node_value = core.table.merge(node_value, conf)
        utils.inject_timestamp(node_value, nil, conf)
    end

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

    local ok, err = self:check_conf(id, node_value, true, typ, true)
    if not ok then
        return 400, err
    end

    local ttl = nil
    if args then
        ttl = args.ttl
    end

    local res, err = core.etcd.atomic_set(key, node_value, ttl, modified_index)
    if not res then
        core.log.error("failed to set new ", self.kind, "[", key, "] to etcd: ", err)
        return 503, {error_msg = err}
    end

    return res.status, res.body
end