Kong系列-14-自定义插件_twingao的博客-程序员宅基地

技术标签: 插件  自定义  Kong  Plugin  customer  

Kong开源了大量的开源插件,当这些开源插件不能满足我们的需求,就需要修改这些开源插件或者自定义插件。Kong提供了方便地自定义插件机制,用户可以开发自己的定制插件。自定义插件可以和Kong进行深层次的集成,如使用数据库表结构,或者扩展Admin API。如果插件实现了所有可选模块,则其目录结构如下所示:

complete-plugin
├── api.lua
├── daos.lua
├── handler.lua
├── migrations
│   ├── init.lua
│   └── 000_base_complete_plugin.lua
└── schema.lua

插件的每个模块对应不同的功能,其中handler.lua和schema.lua是两个必须模块。

Module Name Required Description
api.lua No 插件需要向Admin API暴露接口时使用。
daos.lua No 数据层相关,当插件需要访问数据库是配置。
handler.lua Yes 插件的主要逻辑,Kong在不同阶段执行其对应的handler。
migrations/*.lua No 插件依赖的数据库表结构,启用了daos.lua时需要定义。
schema.lua Yes 插件的配置参数定义,主要用于Kong参数验证。

可以参考官方开源插件Key Authentication的目录结构。

下面演示如何在Kong加载自定义插件。先准备自定义插件的Lua代码。

mkdir myheader
cd myheader
 
vi handler.lua
local MyHeader = {}
 
MyHeader.PRIORITY = 1000
 
function MyHeader:header_filter(conf)
  -- do custom logic here
  kong.response.set_header("myheader", conf.header_value)
end
 
return MyHeader
 
vi schema.lua
return {
  name = "myheader",
  fields = {
    { config = {
        type = "record",
        fields = {
          { header_value = { type = "string", default = "twingao", }, },
        },
    }, },
  }
}
 
tree myheader/
myheader/
├── handler.lua
└── schema.lua

Kong已经预置了大量的开源插件,这些插件都放在/usr/local/share/lua/5.1/kong/plugins/目录下,我们自定义的插件也可以放到该目录下。

cd /usr/local/share/lua/5.1/kong/plugins/

ls
acl              datadog                      ldap-auth        rate-limiting          syslog
aws-lambda       file-log                     loggly           request-size-limiting  tcp-log
azure-functions  hmac-auth                    log-serializers  request-termination    udp-log
base_plugin.lua  http-log                     oauth2           request-transformer    zipkin
basic-auth       ip-restriction               post-function    response-ratelimiting
bot-detection    jwt                          pre-function     response-transformer
correlation-id   key-auth                     prometheus       session
cors             kubernetes-sidecar-injector  proxy-cache      statsd

mv /root/kong/plugin/myheader/ .

ls
acl              datadog                      ldap-auth        proxy-cache            statsd
aws-lambda       file-log                     loggly           rate-limiting          syslog
azure-functions  hmac-auth                    log-serializers  request-size-limiting  tcp-log
base_plugin.lua  http-log                     myheader         request-termination    udp-log
basic-auth       ip-restriction               oauth2           request-transformer    zipkin
bot-detection    jwt                          post-function    response-ratelimiting
correlation-id   key-auth                     pre-function     response-transformer
cors             kubernetes-sidecar-injector  prometheus       session

kong.conf定义了加载哪些插件,plugins配置项的缺省值是bundled,表示加载官方开源插件,如果要加载自定义插件,去掉注释并在后面跟上自定义插件名称。

vi /etc/kong/kong.conf
#plugins = bundled               # Comma-separated list of plugins this node
                                 # should load. By default, only plugins
                                 # bundled in official distributions are
                                 # loaded via the `bundled` keyword.

改为

plugins = bundled,myheader       # Comma-separated list of plugins this node
                                 # should load. By default, only plugins
                                 # bundled in official distributions are
                                 # loaded via the `bundled` keyword.

查看Kong配置。

kong start

curl http://localhost:8001 -s | python -m json.tool
{
......
        "loaded_plugins": {
            "acl": true,
            "aws-lambda": true,
            "azure-functions": true,
            "basic-auth": true,
            "bot-detection": true,
            "correlation-id": true,
            "cors": true,
            "datadog": true,
            "file-log": true,
            "hmac-auth": true,
            "http-log": true,
            "ip-restriction": true,
            "jwt": true,
            "key-auth": true,
            "kubernetes-sidecar-injector": true,
            "ldap-auth": true,
            "loggly": true,

            "myheader": true,

            "oauth2": true,
            "post-function": true,
            "pre-function": true,
            "prometheus": true,
            "proxy-cache": true,
            "rate-limiting": true,
            "request-size-limiting": true,
            "request-termination": true,
            "request-transformer": true,
            "response-ratelimiting": true,
            "response-transformer": true,
            "session": true,
            "statsd": true,
            "syslog": true,
            "tcp-log": true,
            "udp-log": true,
            "zipkin": true
        },
......
}

测试一下。

curl -X POST \
  --url http://localhost:8001/services/ \
  --data 'name=example-service' \
  --data 'url=http://www.baidu.com' \
  -s | python -m json.tool
{
    "client_certificate": null,
    "connect_timeout": 60000,
    "created_at": 1577356917,
    "host": "www.baidu.com",
    "id": "a658c31d-28f9-49aa-ab74-497beadd0921",
    "name": "example-service",
    "path": null,
    "port": 80,
    "protocol": "http",
    "read_timeout": 60000,
    "retries": 5,
    "tags": null,
    "updated_at": 1577356917,
    "write_timeout": 60000
}

curl -X POST \
  --url http://localhost:8001/services/example-service/routes \
  --data 'name=example-service-route' \
  --data 'paths[]=/foo' \
  -s | python -m json.tool
{
    "created_at": 1577357100,
    "destinations": null,
    "headers": null,
    "hosts": null,
    "https_redirect_status_code": 426,
    "id": "b3190688-0412-4016-85e8-22c96ad26df3",
    "methods": null,
    "name": "example-service-route",
    "paths": [
        "/foo"
    ],
    "preserve_host": false,
    "protocols": [
        "http",
        "https"
    ],
    "regex_priority": 0,
    "service": {
        "id": "a658c31d-28f9-49aa-ab74-497beadd0921"
    },
    "snis": null,
    "sources": null,
    "strip_path": true,
    "tags": null,
    "updated_at": 1577357100
}

curl -i http://localhost:8000/foo
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 2381
Connection: keep-alive
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Date: Thu, 26 Dec 2019 10:45:41 GMT
Etag: "588604c4-94d"
Last-Modified: Mon, 23 Jan 2017 13:27:32 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
X-Kong-Upstream-Latency: 13
X-Kong-Proxy-Latency: 93
Via: kong/1.4.2

<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

curl -X POST \
  --url http://localhost:8001/services/example-service/plugins \
  --data 'name=myheader' \
  -s | python -m json.tool
{
    "config": {
        "header_value": "twingao"
    },
    "consumer": null,
    "created_at": 1577357447,
    "enabled": true,
    "id": "95f27854-ebc5-4797-9023-165d59089e98",
    "name": "myheader",
    "protocols": [
        "grpc",
        "grpcs",
        "http",
        "https"
    ],
    "route": null,
    "run_on": "first",
    "service": {
        "id": "a658c31d-28f9-49aa-ab74-497beadd0921"
    },
    "tags": null
}

curl -i http://localhost:8000/foo
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 2381
Connection: keep-alive
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Date: Thu, 26 Dec 2019 10:51:21 GMT
Etag: "588604c4-94d"
Last-Modified: Mon, 23 Jan 2017 13:27:32 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
myheader: twingao                  ##注意此处
X-Kong-Upstream-Latency: 15
X-Kong-Proxy-Latency: 5
Via: kong/1.4.2

<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/twingao/article/details/104073442

智能推荐

细说Nullable<T>类型_anmei1912的博客-程序员宅基地

细说Nullable&lt;T&gt;类型目录一、简介二、语法和用法三、类型的转换和运算四、装箱与拆箱五、GetType()方法六、ToString()方法七、System.Nullable帮助类八、语法糖一、简介  众所周知,值类型变量不能null,这也是为什么它们被称为值类型。但是,在实际的开发过程中,也需要值为null的一些场景。例如以下场景: ...

21.VC(custom)-注册窗口类_花熊的博客-程序员宅基地

在WNDCLASS结构中最重要的两个字段是第二个和最后一个,第二个字段(lpfnWndProc) 是依据这个类别来建立的所有窗口所使用的窗口消息处理程序的地址,最后一个字段是窗口类别的文字名称。程序写作者可以随意定义其名称。在只建立一个窗口的程序中,窗口类别名称通常设定为程序名称。

SpringBoot2.X启动项目出现The APR based Apache Tomcat Native library..._chujia1956的博客-程序员宅基地

一.现象 项目启动时出现如下信息 Starting WarmStartApplication on DESKTOP-H32M6NI with PID 4264 (D:\IntelliJIdea\demo-nuan\admin\target\classes started by y...

【学习摘记】马士兵Servlet&JSP_课时24_forward_sendredirect——原页面跳转 vs 新页面跳转_醒见夜明的博客-程序员宅基地

forward:网页前后共用1个request(url不变,跳转在服务器端,给人感觉还是刚才的页面在服务)sendredirect:必须由客户端发起第2次请求,才能跳转到第2个页面

JXTA核心协议之对等机解析协议(PRP)_hwalk的博客-程序员宅基地_prp协议

3.1.1. Introduction    The Peer Resolver Protocol (PRP) provides a generic query/response interface applications and services can use for building resolution services. The PRP provides the ability to

sapui5 table不显示Table数据_杨江的博客-程序员宅基地

例子代码:显示数据 <Table noDataText="Drop column list items here and columns in the area above" id="__table0"> <items> <ColumnListItem id=

随便推点

用qwt绘制AD波形(转载)_与你相约的博客-程序员宅基地

引子      项目终于快完成了,现在开始整理下代码,总结下,今天先分享下关于使用如何用QWT绘制波形,先把图给贴出来。关于QWT     以下源于百度百科“QWT全称是Qt Widgets for Technical Applications,是一个基于LGPL版权协议的开源项目,可生成各种统计图。它为具有技术专业背景的程序提供GUI组件和一组实用类,

u-boot 在s3c44b0移植总结 _bird67的博客-程序员宅基地_cannot open cpu/s3c44b0/start.o: 没有那个文件或目录

我在移植过程主要参考以下文章,在此对其作者表示感谢。u-boot移植44b0的详细步骤  http://blog.chinaunix.net/u1/36543/showart_290665.htmlU-Boot移植到S3C44B0X开发板的过程http://www.linuxforum.net/forum/gshowflat.php?Board=embedded&Number=65

CQRS学习——一个例子(其六)_weixin_33724570的博客-程序员宅基地

【先上链接:http://pan.baidu.com/s/1o62AHbc 】多图杀猫先用一组图看看实现的功能:添加一个功能假定现在要添加一个书本录入的功能,那么执行如下的操作:1.添加Controllerpublic class BookController : DpfbMvcController { public Acti...

JavaScript 中 call()、apply()、bind() 的区别_zhlstudy123的博客-程序员宅基地

this 是什么this指当前对象。对变量来说this指当前对象;对函数来说函数体里的this指调用当前函数的对象,一般来说函数只能被其所属类的对象调用,但有时候我们使得函数能被其他对象调用(也就是我们需要改变this的指向)这时候我们就可以使用call,apply和bind方法了。1,call()、apply()、bind() 都是用来重定义 this 这个对象的!2、apply()与call()和bind()的区别apply()的第二个参数是数组,而call()和bind()可以传递多个参数3

java按钮点击无反应_登录按钮按了没反应_李北方的博客-程序员宅基地

//页面显示没有问题,就是登录,注册按钮按了没反应//这是登录页面代码%&gt;Stringpath=request.getContextPath();StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%&gt;htmlPUBLIC...

OkHttp3.9拦截器原理与区别_梦里梦到醒不来的梦里的博客-程序员宅基地

接上回传送门上回我们讲到,OkHttp的请求过程中有个非常重要的东西-“拦截器”,而且拦截器又分为interceptors和networkInterceptors两种,那它们具体有何区别呢?又要怎么来使用?现在来一探究竟拦截器工作原理在弄清楚区别之前,要先知道他们工作的原理,还是来到RealCall.execute方法里面的getResponseWithInterceptorChain...

推荐文章

热门文章

相关标签