traefikのプラグインをGoでサクッと書く
日本語での参考資料がなかったので。
業務上、ローカル環境での開発時にtraefikを使った擬似的なAWS API Gatewayのような仕組み(同一のhostnameにECS, Lambda, S3がありパスで振り分ける) を導入しているが、複雑なクエリの書き換えや、レスポンスを編集するmiddlewareが必要になったので自作する。
traefikの内部実装はGoであり、プラグインシステムもGo(traefik/yaegi を用いたインタプリタ) を使用できる。
他にもwasmなどに対応しているが、今回はyaegi/Goを扱う。
yaegiの部分が結構面白く、Configの適用からMiddlewareの動作まで、reflectionなどを用いて関数名を動的に解決しコンパイルせずに動かしている。
ただし、その為外部packageがimportできず、vendoringが必須となる。
プラグインの探索、validtion、リストの管理は traefik/piceus で行われているので、困ったら最悪これを読めばなんとかなる(というかドキュメントがかなり薄いので、僕は積極的に読みに行く)
こんなものまでOSS化してくれるのは嬉しい。
プラグインの作り方やインストール方法。
ソースコードを読みながら見ると割と記述漏れがある。気合いでなんとかする
Goのプラグインテンプレート
これをベースに書き換えて実装する
実際の内部実装はまだ見れていないが、少なくてもpiceusでは以下のチェックを実施している。
- manifestファイル(
.traefik.yml
) が有効であること -
import
が機能すること -
CreateConfig()
関数が正しく実行されること - manifestファイルの
testData
がConfig
構造体に合致すること -
New()
関数のシグネチャが正しいこと(func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error)
) - (
ServeHTTP
メソッドは確認していないのか?)
実装についてはスクラップではなく別途記事を書きたい気持ち
下記の条件を満たしたレポジトリは、piceus
の探査対象になる。
- GitHubの公開レポジトリ
- レポジトリのタグに
traefik-plugin
が設定されている - タグが設定され、semver形式でReleaseされている必要がある(バイナリ不要)
-
go.mod
がある
探査されたレポジトリは、piceus
のチェックを正しく通過しているとtraefik Pluginで公開され、traefik
上から使用可能になる。
探査されても、プラグインとして配布出来ない(piceus
のチェックに失敗するなど) 場合は、外套のレポジトリにissueが作成されてエラーメッセージを教えてくれる。
issueを閉じると、次の探査タイミングで再度評価される。
ドキュメントを読む限り「30分に一度探査され、条件に合致された場合はリストされる」とあったが、自作したプラグインの通知は1時間にしか通知がされなかった。