0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

KongAdvent Calendar 2024

Day 24

Kong GatewayのAdmin APIにエンドポイントを追加する

Posted at

Kong Gatewayを操作するためのAdmin APIはLuaのフレームワークであるLapisで実装されており、Lapisの作りに従ってAdmin APIにAPIエンドポイントを追加することが出来る。

エンドポイントの追加はカスタムプラグインの追加と同じ要領で追加できるので、実際にやってみる。

エンドポイントの基礎

Kongはkong.plugins.<plugin_name>.apiにエンドポイントの定義があれば検出して読み込む。
そのため、エンドポイントを追加する際はカスタムプラグインの要領でプラグインを追加し、その中にapi.luaを用意して読み込ませることになる。
api.luaの基本構造は以下となる。(Add endpoints to the Admin APIより抜粋)

return {
  ["<path>"] = {
     schema = <schema>,
     methods = {
       before = function(self) ... end,
       on_error = function(self) ... end,
       GET = function(self) ... end,
       PUT = function(self) ... end,
       ...
     }
  },
  ...
}

<path>部分はAPIへのアクセスパスであり、例えば["/my_endpoint"]と指定すると<Admin APIのURL>/my_endpoint
でアクセス出来るようになる。
パスの中に:consumersのようにコロンを含んだ値がある場合、これは動的に変更する部分でアクセス時にself.params.<:を除いた名前>に格納される(参考:Routes&URL Patterns)。
UUIDなど外部から変数を渡したい時に利用できる。

schemaについてはKongのエンティティのスキーマを指定し、フィールドの解析などに利用する。エンティティのスキーマはkong.db.<エンティティ名>.schemaのような形で指定する。

methodsの中は実際にAPIを呼び出した際の処理を記述する。

  • before:前処理的なものを行うための呼び出し。全ての関数の前に実行される(指定は任意)
  • on_error:他の関数がエラーとなった時にエラーをハンドルする関数。指定しない場合はKongのデフォルトのエラーハンドリングが行われる。
  • GET等:HTTPメソッドごとの処理を記述する。

ちなみにapi.luaを持ってるKongの公式プラグインは数が少ないが、実装する際の参考になるので参考までにリンクを貼っておく。

検証

APIエンドポイントを含むプラグインのファイル構造についてはAdvanced plugin modulesに説明がある。
ファイル構造の説明に従うと以下のファイルが必要となる。

kong/plugins/<プラグイン名>/
├── api.lua
├── handler.lua
└── schema.lua

以降、それぞれのファイルを作成して検証する。

api.lua

ここでは以下の仕様のAPIエンドポイントをお試しで作ってみる。

  • /my_endpoint
    • GETでアクセスすると接続元と接続先のIPと内部で持ってる文字列を返す
  • /my_endpoint/<任意の文字列>
    • POSTでアクセスするとパスで指定した任意の文字列を返す

実装は以下のような感じ。

api.lua
return {
  ["/my_endpoint"] = {
    GET = function(self)
      local client_ip = kong.client.get_ip()
      local server_ip = ngx.var.server_addr
      local msg = "Hello from Kong"
      return kong.response.exit(200, { 
        message = msg,
        ip = {
          client_ip = client_ip, 
          server_ip = server_ip,  
        }
      })
    end,
  },
  ["/my_endpoint/:my_endpoint"] = {
    POST = function(self)
      local msg = "params: " .. self.params.my_endpoint
      return kong.response.exit(200, { 
        message = msg
      })
    end,
  },
}

KongのPDKは問題なく呼び出せるので、IPの取得やレスポンスを返す時に利用している。

handler.luaとschema.luaの作成

handler.luaschema.luaについては今回はプラグインではないので、中身がないものを適当に用意しておけばOK。

handler.lua
local CustomEndpoints = {
    PRIORITY = 1000,
    VERSION = "1.0.0",
}

return CustomEndpoints
schema.lua
return {
    name = "custom-endpoints",
    fields = {
        { config = {
            type = "record",
            fields = {}
        }}
    }
}

導入

ここではKubernetes上のKong Gatewayに導入する。
なお検証環境はHybridモードで展開しているが、APIのエンドポイント追加はAdmin APIがいるControl Planeにのみ影響するため、作成したカスタムプラグインの導入はControl PlaneのみでOK。
またカスタムプラグインの導入方法はここではConfigMapを利用する。
最初にConfigMapを作成する。3つのluaファイルは./custom-endpointsに置いているものとする。

kubectl create cm kong-plugin-endpoint \
  --from-file=./custom-endpoints/ \
  -n kong \
  --dry-run=client -o yaml \
  | kubectl apply -f -

次にControl PlaneのHelmのvalues.yamlに以下を追記し、エンドポイントを追加したプラグインを読み込むようにする。

env:
  plugins: bundled,custom-endpoints
plugins:
  configMaps:
  - name: kong-plugin-endpoints
    pluginName: custom-endpoints

修正したvalues.yamlを使ってControl Planeを再デプロイする。

helm upgrade -i kong-aws-cp kong/kong -f ./values.yaml -n kong --wait --debug

以上で追加したAPIエンドポイントが有効化された。
なお、カスタムプラグインと異なり、特にプラグインを有効化せずともエンドポイントは有効化されているので、プラグイン導入直後からアクセス出来るようになっている。
最初に/my_endpointの方にGETでアクセスしてみる。

$ curl -sX GET https://adminapi.mydomain.info/my_endpoint | jq .
{
  "message": "Hello from Kong",
  "ip": {
    "client_ip": "192.168.34.31",
    "server_ip": "192.168.53.23"
  }

意図したレスポンスが取得できた。
次に/my_endpoint/<任意の文字列>へのPOSTも確認する。

$ curl -sX POST https://adminapi.mydomain.info/my_endpoint/hoge | jq .
{
  "message": "params: hoge"
}

こちらも確認できた。

まとめ

カスタムプラグインと同じ感覚でエンドポイントを追加できた。
カスタムプラグイン作成時に独自のエンドポイントを持たせて機能追加したい場合などには有用だと思う。
特にカスタムエンティティなどを実装し始めると使い道も増えそうなので、カスタムプラグイン実装時には覚えておくとよさそう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?