mirror of
https://github.com/eliasstepanik/caddy-ingess.git
synced 2026-01-10 03:58:28 +00:00
Add healthz endpoint (#107)
This commit is contained in:
parent
9dba87b050
commit
6e28cb2cb3
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ bin
|
|||||||
vendor
|
vendor
|
||||||
.idea/
|
.idea/
|
||||||
dist/
|
dist/
|
||||||
|
ingress-controller
|
||||||
|
|||||||
@ -27,7 +27,7 @@ kind export kubeconfig
|
|||||||
|
|
||||||
## Setup development env
|
## Setup development env
|
||||||
|
|
||||||
Replace also the domain name to use in `hack/test/example-ingress.yaml` from `kubernetes.localhost` to your domain (ensure also that the subdomain `example1` and `example2` are resolved to the server public IP)
|
Replace also the domain name to use in `kubernetes/sample/example-ingress.yaml` from `kubernetes.localhost` to your domain (ensure also that the subdomain `example1` and `example2` are resolved to the server public IP)
|
||||||
|
|
||||||
Create a namespace to host the caddy ingress controller:
|
Create a namespace to host the caddy ingress controller:
|
||||||
```
|
```
|
||||||
@ -36,7 +36,7 @@ kubectl create ns caddy-system
|
|||||||
|
|
||||||
Then we can start skaffold using:
|
Then we can start skaffold using:
|
||||||
```
|
```
|
||||||
skaffold dev --port-forward
|
make dev
|
||||||
```
|
```
|
||||||
|
|
||||||
this will automatically:
|
this will automatically:
|
||||||
|
|||||||
3
Makefile
3
Makefile
@ -1,3 +1,6 @@
|
|||||||
build:
|
build:
|
||||||
@mkdir -p bin
|
@mkdir -p bin
|
||||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/ingress-controller ./cmd/caddy
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/ingress-controller ./cmd/caddy
|
||||||
|
|
||||||
|
dev: build
|
||||||
|
skaffold dev --port-forward
|
||||||
|
|||||||
@ -87,7 +87,7 @@ spec:
|
|||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
httpGet:
|
httpGet:
|
||||||
port: 9765
|
port: 9765
|
||||||
path: /metrics
|
path: /healthz
|
||||||
{{- with .Values.nodeSelector }}
|
{{- with .Values.nodeSelector }}
|
||||||
nodeSelector:
|
nodeSelector:
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
8
go.mod
8
go.mod
@ -16,6 +16,11 @@ require (
|
|||||||
k8s.io/client-go v0.23.6
|
k8s.io/client-go v0.23.6
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/stretchr/objx v0.4.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
|
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
|
||||||
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
|
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
|
||||||
@ -100,6 +105,7 @@ require (
|
|||||||
github.com/spf13/cast v1.4.1 // indirect
|
github.com/spf13/cast v1.4.1 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||||
|
github.com/stretchr/testify v1.8.0
|
||||||
github.com/tailscale/tscert v0.0.0-20220125204807-4509a5fbaf74 // indirect
|
github.com/tailscale/tscert v0.0.0-20220125204807-4509a5fbaf74 // indirect
|
||||||
github.com/urfave/cli v1.22.5 // indirect
|
github.com/urfave/cli v1.22.5 // indirect
|
||||||
go.etcd.io/bbolt v1.3.6 // indirect
|
go.etcd.io/bbolt v1.3.6 // indirect
|
||||||
@ -128,7 +134,7 @@ require (
|
|||||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
howett.net/plist v1.0.0 // indirect
|
howett.net/plist v1.0.0 // indirect
|
||||||
k8s.io/klog/v2 v2.30.0 // indirect
|
k8s.io/klog/v2 v2.30.0 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
|
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
|
||||||
|
|||||||
6
go.sum
6
go.sum
@ -1074,6 +1074,8 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
|
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
@ -1083,6 +1085,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/tailscale/tscert v0.0.0-20220125204807-4509a5fbaf74 h1:uFx5aih29p2IaRUF0lJwtVViCXStlvnPPE3NEmM4Ivs=
|
github.com/tailscale/tscert v0.0.0-20220125204807-4509a5fbaf74 h1:uFx5aih29p2IaRUF0lJwtVViCXStlvnPPE3NEmM4Ivs=
|
||||||
github.com/tailscale/tscert v0.0.0-20220125204807-4509a5fbaf74/go.mod h1:hL4gB6APAasMR2NNi/JHzqKkxW3EPQlFgLEq9PMi2t0=
|
github.com/tailscale/tscert v0.0.0-20220125204807-4509a5fbaf74/go.mod h1:hL4gB6APAasMR2NNi/JHzqKkxW3EPQlFgLEq9PMi2t0=
|
||||||
@ -1862,6 +1866,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|||||||
37
internal/caddy/convert_test.go
Normal file
37
internal/caddy/convert_test.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package caddy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/caddyserver/ingress/pkg/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConvertToCaddyConfig(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
expectedConfigPath string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "default",
|
||||||
|
expectedConfigPath: "./test_data/default.json",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
cfg, err := Converter{}.ConvertToCaddyConfig(store.NewStore(store.Options{}, &store.PodInfo{}))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
cfgJson, err := json.Marshal(cfg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expectedCfg, err := os.ReadFile(test.expectedConfigPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.JSONEq(t, string(expectedCfg), string(cfgJson))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
48
internal/caddy/global/healthz.go
Normal file
48
internal/caddy/global/healthz.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package global
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/caddyserver/caddy/v2"
|
||||||
|
"github.com/caddyserver/caddy/v2/caddyconfig"
|
||||||
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
||||||
|
"github.com/caddyserver/ingress/pkg/converter"
|
||||||
|
"github.com/caddyserver/ingress/pkg/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HealthzPlugin struct{}
|
||||||
|
|
||||||
|
func (p HealthzPlugin) IngressPlugin() converter.PluginInfo {
|
||||||
|
return converter.PluginInfo{
|
||||||
|
Name: "healthz",
|
||||||
|
Priority: -20,
|
||||||
|
New: func() converter.Plugin { return new(HealthzPlugin) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
converter.RegisterPlugin(HealthzPlugin{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p HealthzPlugin) GlobalHandler(config *converter.Config, store *store.Store) error {
|
||||||
|
healthzHandler := caddyhttp.StaticResponse{StatusCode: caddyhttp.WeakString(strconv.Itoa(http.StatusOK))}
|
||||||
|
|
||||||
|
healthzRoute := caddyhttp.Route{
|
||||||
|
HandlersRaw: []json.RawMessage{
|
||||||
|
caddyconfig.JSONModuleObject(healthzHandler, "handler", healthzHandler.CaddyModule().ID.Name(), nil),
|
||||||
|
},
|
||||||
|
MatcherSetsRaw: []caddy.ModuleMap{{
|
||||||
|
"path": caddyconfig.JSON(caddyhttp.MatchPath{"/healthz"}, nil),
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
config.GetMetricsServer().Routes = append(config.GetMetricsServer().Routes, healthzRoute)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface guards
|
||||||
|
var (
|
||||||
|
_ = converter.GlobalMiddleware(HealthzPlugin{})
|
||||||
|
)
|
||||||
@ -23,20 +23,15 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p MetricsPlugin) GlobalHandler(config *converter.Config, store *store.Store) error {
|
func (p MetricsPlugin) GlobalHandler(config *converter.Config, store *store.Store) error {
|
||||||
httpApp := config.Apps["http"].(*caddyhttp.App)
|
|
||||||
|
|
||||||
if store.ConfigMap.Metrics {
|
if store.ConfigMap.Metrics {
|
||||||
httpApp.Servers[converter.MetricsServer] = &caddyhttp.Server{
|
metricsRoute := caddyhttp.Route{
|
||||||
Listen: []string{":9765"},
|
HandlersRaw: []json.RawMessage{json.RawMessage(`{ "handler": "metrics" }`)},
|
||||||
AutoHTTPS: &caddyhttp.AutoHTTPSConfig{Disabled: true},
|
MatcherSetsRaw: []caddy.ModuleMap{{
|
||||||
Routes: []caddyhttp.Route{{
|
"path": caddyconfig.JSON(caddyhttp.MatchPath{"/metrics"}, nil),
|
||||||
HandlersRaw: []json.RawMessage{json.RawMessage(`{ "handler": "metrics" }`)},
|
|
||||||
MatcherSetsRaw: []caddy.ModuleMap{{
|
|
||||||
"path": caddyconfig.JSON(caddyhttp.MatchPath{"/metrics"}, nil),
|
|
||||||
}},
|
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.GetMetricsServer().Routes = append(config.GetMetricsServer().Routes, metricsRoute)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
27
internal/caddy/test_data/default.json
Normal file
27
internal/caddy/test_data/default.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"admin": {},
|
||||||
|
"storage": { "module": "secret_store", "namespace": "", "leaseId": "" },
|
||||||
|
"apps": {
|
||||||
|
"http": {
|
||||||
|
"servers": {
|
||||||
|
"ingress_server": {
|
||||||
|
"listen": [":80", ":443"],
|
||||||
|
"tls_connection_policies": [{}],
|
||||||
|
"automatic_https": {}
|
||||||
|
},
|
||||||
|
"metrics_server": {
|
||||||
|
"listen": [":9765"],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": [{ "path": ["/healthz"] }],
|
||||||
|
"handle": [{ "handler": "static_response", "status_code": 200 }]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"automatic_https": { "disable": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tls": {}
|
||||||
|
},
|
||||||
|
"logging": {}
|
||||||
|
}
|
||||||
@ -30,6 +30,10 @@ func (c Config) GetHTTPServer() *caddyhttp.Server {
|
|||||||
return c.Apps["http"].(*caddyhttp.App).Servers[HttpServer]
|
return c.Apps["http"].(*caddyhttp.App).Servers[HttpServer]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Config) GetMetricsServer() *caddyhttp.Server {
|
||||||
|
return c.Apps["http"].(*caddyhttp.App).Servers[MetricsServer]
|
||||||
|
}
|
||||||
|
|
||||||
func (c Config) GetTLSApp() *caddytls.TLS {
|
func (c Config) GetTLSApp() *caddytls.TLS {
|
||||||
return c.Apps["tls"].(*caddytls.TLS)
|
return c.Apps["tls"].(*caddytls.TLS)
|
||||||
}
|
}
|
||||||
@ -50,6 +54,10 @@ func NewConfig() *Config {
|
|||||||
&caddytls.ConnectionPolicy{},
|
&caddytls.ConnectionPolicy{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
MetricsServer: {
|
||||||
|
Listen: []string{":9765"},
|
||||||
|
AutoHTTPS: &caddyhttp.AutoHTTPSConfig{Disabled: true},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
apiVersion: skaffold/v2beta3
|
apiVersion: skaffold/v2beta29
|
||||||
kind: Config
|
kind: Config
|
||||||
metadata:
|
metadata:
|
||||||
name: caddy-ingress-controller
|
name: caddy-ingress-controller
|
||||||
@ -12,6 +12,10 @@ deploy:
|
|||||||
namespace: caddy-system
|
namespace: caddy-system
|
||||||
chartPath: charts/caddy-ingress-controller
|
chartPath: charts/caddy-ingress-controller
|
||||||
recreatePods: true
|
recreatePods: true
|
||||||
|
artifactOverrides:
|
||||||
|
image: caddy/ingress
|
||||||
|
imageStrategy:
|
||||||
|
helm: {}
|
||||||
kubectl:
|
kubectl:
|
||||||
manifests:
|
manifests:
|
||||||
- kubernetes/sample/*.yaml
|
- kubernetes/sample/*.yaml
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user