Earlier this year, Kong has announced brilliant features. You check it out the following.
https://konghq.com/blog/kong-gateway-2-0-0-released/
I was very interested in one of them which is we will be able to develop Go plugins on Kong. I built a plugin to test and as soon as possible I'm writing this blog post eventually. I'm going to demonstrate a plugin that checks the consumer key from query string.
I used to run DB-less Kong on Docker and I prefer that either.
FROM kong/go-plugin-tool:2.0.4-alpine-latest AS builder
RUN mkdir -p /tmp/key-checker/
COPY . /tmp/key-checker/
RUN cd /tmp/key-checker/ && \
go get github.com/Kong/go-pdk && \
go mod init kong-go-plugin && \
go get -d -v github.com/Kong/go-pluginserver && \
go build github.com/Kong/go-pluginserver && \
go build -buildmode plugin key-checker.go
FROM kong:2.0.4-alpine
RUN mkdir /tmp/go-plugins
COPY --from=builder /tmp/key-checker/go-pluginserver /usr/local/bin/go-pluginserver
COPY --from=builder /tmp/key-checker/key-checker.so /tmp/go-plugins
COPY config.yml /tmp/config.yml
USER root
RUN chmod -R 777 /tmp
RUN /usr/local/bin/go-pluginserver -version && \
cd /tmp/go-plugins && \
/usr/local/bin/go-pluginserver -dump-plugin-info key-checker
USER kong
In this way, we copy our required files. Let's go into details. Firstly, we create a builder image and I copy my key-checker.go file and I build it as a go plugin. After that, I get that file from the builder image and I put it in Kong image. That's straightforward.
Let's look over the Go file.
package main
import (
"github.com/Kong/go-pdk"
)
// it represents to config parameters into the config.yml
type Config struct {
Apikey string
}
func New() interface{} {
return &Config{}
}
func (conf Config) Access(kong *pdk.PDK) {
key, err := kong.Request.GetQueryArg("key")
apiKey := conf.Apikey
if err != nil {
kong.Log.Err(err.Error())
}
//it adjusts the header parameters in this way.
x := make(map[string][]string)
x["Content-Type"] = append(x["Content-Type"], "application/json")
//If the key of the consumer is not equal to the claimed key, kong doesn't ensure the proxy
if apiKey != key {
kong.Response.Exit(403, "You have no correct consumer key.", x)
}
}
This file tells us that we check the key from the query string. If it is not equal to the key from the config file, we don't provide proxy service. In another case, it will ensure the proxy well and clearly the claimed URL from the config file. This is the config file. Also, I try to show changing header parameters and I write content type as a parameter for only showing.
# go.yml
_format_version: "1.1"
services:
- url: https://reqres.in/api/users?page=2
routes:
- paths:
- "/"
plugins:
- name: key-checker
config:
apikey: mysecretconsumerkey
To build the Dockerfile I run this command.
docker build -t kong-demo .
Once it built, I run the following command. I point the related directories by using environment variables.
docker run -ti --rm --name kong-go-plugins \
-e "KONG_DATABASE=off" \
-e "KONG_GO_PLUGINS_DIR=/tmp/go-plugins" \
-e "KONG_DECLARATIVE_CONFIG=/tmp/config.yml" \
-e "KONG_PLUGINS=key-checker" \
-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \
-p 8000:8000 \
kong-demo
Right, we're able to check the service. As you can see, the key is not equal. Therefore the status code is 403 and proxy service is not working.
When I enter the correct consumer key, as expected Kong ensures the proxy service clearly and URL is requested.
Conclusion
This feature drastically will be useful for Go developers and you could build pretty cool plugins in this way. I also want to share some practical URLs like the following. I hope the blog post ignites the minds to build awesome Go plugins on Kong. Happy Konging!
https://docs.konghq.com/2.0.x/go
Top comments (2)
Hi Simsek,
I have some problem when I use go plugin, can i ask for your help?
I hope to use kong.Response.GetStatus() or kong.ServiceResponse.Getxxx func then do some thing,bug i got error: 'function cannot be called in access phase (only in: header_filter, body_filter, log)'. Do you know how to fix it?
I'm not sure but there is an issue about this on Github repository. Perhaps, you could type this clarification about that.
github.com/Kong/kong/issues/4848