ameryhan commented on issue #5955:
URL: https://github.com/apache/apisix/issues/5955#issuecomment-1002479651


   
   local ngx = ngx
   local plugin = require("apisix.plugin")
   local core = require("apisix.core")
   local upstream = require("apisix.upstream")
   
   local plugin_name = "saas-route"
   
   local schema = {
       type = "object",
       properties = {
           deny_on_mismatch = {type = "boolean", default = false} ,
           header_name = {type = "string", default = "saas_code"} ,
       }
   }
   
   local _M = {
       version = 0.1,
       priority = 0,
       name = plugin_name,
       schema = schema ,
   }
   
   local saas_schema = 
{type="object",properties={saas_code={type="string"},upstream_id={type="string"}
 } }
   local config_path
   local config_obj
   
   function _M.check_schema(conf, schema_type)
       if schema_type == core.schema.TYPE_METADATA then
           return core.schema.check(metadata_schema, conf)
       end
       return core.schema.check(schema, conf)
   end
   
   function _M.init()
       local local_conf = core.config.local_conf()
   --     config_path = core.table.try_read_attr(local_conf, plugin_name,  
"config_path")
       -- config_path = "/config_path"
   
       local attr = plugin.plugin_attr(plugin_name)
       config_path = attr and attr.config_path
       if not config_path then
           core.log.error("failed to get config_path")
           return 
       end
       core.log.warn(plugin_name, " init , config_path = ",config_path)
   
       local saas_dict_obj = core.config.fetch_created_obj(config_path)
   --     if not set_saas_dict then
   --         core.log.warn("start to create------------------------ ", 
saas_dict_obj)
   --         config_obj = core.config.new(config_path,{automatic = 
true,item_schema = saas_schema,single_item=false } )
   --         if not config_obj then
   --             core.log.error("failed to init config")
   --             return
   --         end
   --         core.log.warn("create finish------------------------ ", 
saas_dict_obj)
   --     end
   
   end
   
   function _M.destroy()
       -- call this function when plugin is unloaded
   end
   
   function _M.rewrite(conf, ctx)
       
       -- if not headers[conf.header_name] then
       --     core.request.set_header(ctx, conf.header_name, )
       -- end
   end
   
   function _M.access(conf, ctx)
       local header_name = conf.header_name
       local saas_code = core.request.header(ctx,header_name)
       if not saas_code then
           saas_code = core.request.get_uri_args(ctx)[header_name]
       end
   
       if not saas_code then
           return 200,{msg="invalid router key"}
       end
       
       local saas_dict_obj = core.config.fetch_created_obj(config_path)
      
       core.log.warn("saas_code------------------------ ", saas_code)
       core.log.warn("saas_dict_obj------------------------ ", saas_dict_obj)
   
       local saas_info = saas_dict_obj:get(saas_code)
   
       -- core.log.error("saas_info= ", saas_info)
   
       if not saas_info or not saas_info.value then
           if conf.deny_on_mismatch then
              core.log.error("deny_on_mismatch ------------------------")
              return 404
           end
           core.log.error(plugin_name, " ------------------------ etcd did not 
found saas_code=" ,saas_code)
           return 
       end
   
       local upstream_id = saas_info.value.upstream_id
       core.log.warn(plugin_name," ------------------------ matched ", 
saas_code, " -> ", upstream_id)
   
       if not upstream_id then
           return 200,{msg="------------------------ invalid upstream_id"}
       end
   
       ctx.upstream_id = upstream_id
   end
   
   local function check_token(ctx)
       local local_conf = core.config.local_conf()
       if not local_conf or not local_conf.apisix
          or not local_conf.apisix.admin_key then
           return true
       end
   
       local req_token = ctx.var.arg_api_key or ctx.var.http_x_api_key
                         or ctx.var.cookie_x_api_key
       if not req_token then
           return false, "missing apikey"
       end
   
       local admin
       for i, row in ipairs(local_conf.apisix.admin_key) do
           if req_token == row.key then
               admin = row
               break
           end
       end
   
       if not admin then
           return false, "wrong apikey"
       end
   
       return true
   end
   
   local function set_saas_dict(ctx)
       local args = core.request.get_uri_args(ctx)
       if not args.saas_code or not args.upstream_id then
           return 200, {msg = "invalid args"}
       end
   
       local ok, err = check_token(ctx)
       if not ok then
           core.log.warn("failed to check token: ", err)
           return 200, {msg = "invalid token"}
       end
   
       local key = config_path .. "/"  .. args.saas_code
       local res,err = 
core.etcd.set(key,{saas_code=args.saas_code,upstream_id=args.upstream_id})
       local info = res and res.body.node
       return 200,{data=info}
   end
   
   local function get_saas_dict(ctx)
       local ok, err = check_token(ctx)
       if not ok then
           core.log.warn("failed to check token: ", err)
           return 401
       end
   
       local saas_infos = core.config.fetch_created_obj(config_path)
       core.log.error("get_saas_dict ------------------------", saas_infos)
   --     local saas_infos = config_obj.values
   
       local total =0
       for _,info in ipairs(saas_infos) do
           core.log.warn("saas_code ",info.key,core.json.encode(info.value) )
           total = total+1
       end
   
       --local saas_dict_obj = core.config.fetch_created_obj(config_path)
      
       return 200,{total=total}
   end
   
   
   function _M.api()
       return { 
           { methods = { "POST" },uri = "/apisix/plugin/saas-route/set",handler 
= set_saas_dict,},
           { methods = { "GET" },uri = "/apisix/plugin/saas-route/get",handler 
= get_saas_dict,},
       }
   
   end
   
   return _M
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to