mirror of
https://github.com/eliasstepanik/caddy-ingess.git
synced 2026-01-09 19:48: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
|
||||
.idea/
|
||||
dist/
|
||||
ingress-controller
|
||||
|
||||
@ -27,7 +27,7 @@ kind export kubeconfig
|
||||
|
||||
## 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:
|
||||
```
|
||||
@ -36,7 +36,7 @@ kubectl create ns caddy-system
|
||||
|
||||
Then we can start skaffold using:
|
||||
```
|
||||
skaffold dev --port-forward
|
||||
make dev
|
||||
```
|
||||
|
||||
this will automatically:
|
||||
|
||||
3
Makefile
3
Makefile
@ -1,3 +1,6 @@
|
||||
build:
|
||||
@mkdir -p bin
|
||||
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
|
||||
httpGet:
|
||||
port: 9765
|
||||
path: /metrics
|
||||
path: /healthz
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
|
||||
8
go.mod
8
go.mod
@ -16,6 +16,11 @@ require (
|
||||
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 (
|
||||
filippo.io/edwards25519 v1.0.0-rc.1 // 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/pflag v1.0.5 // 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/urfave/cli v1.22.5 // 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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // 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
|
||||
k8s.io/klog/v2 v2.30.0 // 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.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
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 v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
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.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
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/tailscale/tscert v0.0.0-20220125204807-4509a5fbaf74 h1:uFx5aih29p2IaRUF0lJwtVViCXStlvnPPE3NEmM4Ivs=
|
||||
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-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.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=
|
||||
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=
|
||||
|
||||
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 {
|
||||
httpApp := config.Apps["http"].(*caddyhttp.App)
|
||||
|
||||
if store.ConfigMap.Metrics {
|
||||
httpApp.Servers[converter.MetricsServer] = &caddyhttp.Server{
|
||||
Listen: []string{":9765"},
|
||||
AutoHTTPS: &caddyhttp.AutoHTTPSConfig{Disabled: true},
|
||||
Routes: []caddyhttp.Route{{
|
||||
HandlersRaw: []json.RawMessage{json.RawMessage(`{ "handler": "metrics" }`)},
|
||||
MatcherSetsRaw: []caddy.ModuleMap{{
|
||||
"path": caddyconfig.JSON(caddyhttp.MatchPath{"/metrics"}, nil),
|
||||
}},
|
||||
metricsRoute := caddyhttp.Route{
|
||||
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
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
func (c Config) GetMetricsServer() *caddyhttp.Server {
|
||||
return c.Apps["http"].(*caddyhttp.App).Servers[MetricsServer]
|
||||
}
|
||||
|
||||
func (c Config) GetTLSApp() *caddytls.TLS {
|
||||
return c.Apps["tls"].(*caddytls.TLS)
|
||||
}
|
||||
@ -50,6 +54,10 @@ func NewConfig() *Config {
|
||||
&caddytls.ConnectionPolicy{},
|
||||
},
|
||||
},
|
||||
MetricsServer: {
|
||||
Listen: []string{":9765"},
|
||||
AutoHTTPS: &caddyhttp.AutoHTTPSConfig{Disabled: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
apiVersion: skaffold/v2beta3
|
||||
apiVersion: skaffold/v2beta29
|
||||
kind: Config
|
||||
metadata:
|
||||
name: caddy-ingress-controller
|
||||
@ -12,6 +12,10 @@ deploy:
|
||||
namespace: caddy-system
|
||||
chartPath: charts/caddy-ingress-controller
|
||||
recreatePods: true
|
||||
artifactOverrides:
|
||||
image: caddy/ingress
|
||||
imageStrategy:
|
||||
helm: {}
|
||||
kubectl:
|
||||
manifests:
|
||||
- kubernetes/sample/*.yaml
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user