Skip to content

Commit 7f52341

Browse files
feat(server): add healthcheck path (#1611)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent 7254d83 commit 7f52341

File tree

8 files changed

+385
-25
lines changed

8 files changed

+385
-25
lines changed

go.work.sum

Lines changed: 41 additions & 0 deletions
Large diffs are not rendered by default.

server/.env.example

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# General
22
PORT=8080
3-
REEARTH_DB=mongodb://localhost # for reearth database url
3+
REEARTH_DB=mongodb://localhost # for reearth database url
44
REEARTH_DB_ACCOUNT=reearth_account # for reearth account database name
5-
REEARTH_DB_VIS=reearth # for reearth visualizer database name
5+
REEARTH_DB_VIS=reearth # for reearth visualizer database name
66
REEARTH_HOST=https://localhost:8080
77
REEARTH_HOST_WEB=https://localhost:3000
88
REEARTH_ASSETBASEURL=https://localhost:8080/assets
@@ -86,3 +86,7 @@ REEARTH_SES_NAME=
8686
# Extension plugin url as csv
8787
# each path should contain `reearth.yml` file
8888
REEARTH_EXT_PLUGIN=http://fileserve.local:8090/pluging-01,http://fileserve.local:8090/pluging-02
89+
90+
#Health Check Config
91+
REEARTH_HEALTHCHECK_USERNAME=
92+
REEARTH_HEALTHCHECK_PASSWORD=

server/go.mod

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
github.com/go-faker/faker/v4 v4.6.0
1616
github.com/goccy/go-yaml v1.15.15
1717
github.com/google/uuid v1.6.0
18+
github.com/hellofresh/health-go/v5 v5.5.4
1819
github.com/iancoleman/strcase v0.3.0
1920
github.com/idubinskiy/schematyper v0.0.0-20190118213059-f71b40dac30d
2021
github.com/jarcoal/httpmock v1.3.1
@@ -41,12 +42,12 @@ require (
4142
go.mongodb.org/mongo-driver v1.17.2
4243
go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho v0.59.0
4344
go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo v0.59.0
44-
go.opentelemetry.io/otel v1.34.0
45+
go.opentelemetry.io/otel v1.35.0
4546
go.opentelemetry.io/otel/sdk v1.34.0
4647
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
4748
golang.org/x/net v0.34.0
4849
golang.org/x/oauth2 v0.25.0
49-
golang.org/x/text v0.21.0
50+
golang.org/x/text v0.22.0
5051
golang.org/x/tools v0.29.0
5152
google.golang.org/api v0.219.0
5253
google.golang.org/grpc v1.70.0
@@ -166,16 +167,16 @@ require (
166167
go.opentelemetry.io/contrib/detectors/gcp v1.32.0 // indirect
167168
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
168169
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect
169-
go.opentelemetry.io/otel/metric v1.34.0 // indirect
170+
go.opentelemetry.io/otel/metric v1.35.0 // indirect
170171
go.opentelemetry.io/otel/sdk/metric v1.32.0 // indirect
171-
go.opentelemetry.io/otel/trace v1.34.0 // indirect
172+
go.opentelemetry.io/otel/trace v1.35.0 // indirect
172173
go.uber.org/atomic v1.11.0 // indirect
173174
go.uber.org/multierr v1.11.0 // indirect
174175
go.uber.org/zap v1.26.0 // indirect
175-
golang.org/x/crypto v0.32.0 // indirect
176+
golang.org/x/crypto v0.35.0 // indirect
176177
golang.org/x/mod v0.22.0 // indirect
177-
golang.org/x/sync v0.10.0 // indirect
178-
golang.org/x/sys v0.29.0 // indirect
178+
golang.org/x/sync v0.11.0 // indirect
179+
golang.org/x/sys v0.30.0 // indirect
179180
golang.org/x/time v0.9.0 // indirect
180181
google.golang.org/genproto v0.0.0-20250106144421-5f5ef82da422 // indirect
181182
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect

server/go.sum

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ github.com/google/go-cmp v0.1.1-0.20171103154506-982329095285/go.mod h1:oXzfMopK
204204
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
205205
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
206206
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
207-
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
208-
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
207+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
208+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
209209
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
210210
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
211211
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
@@ -240,6 +240,8 @@ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplb
240240
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
241241
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
242242
github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
243+
github.com/hellofresh/health-go/v5 v5.5.4 h1:aOCIf1eHSRrPegRUJ2rzc7avck/lFSFLn+Zl3qKJcjc=
244+
github.com/hellofresh/health-go/v5 v5.5.4/go.mod h1:W+6uiWHS/m9jaB0aYBVlUBTeyE98yom6f+0ewLoBPYQ=
243245
github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f h1:7LYC+Yfkj3CTRcShK0KOL/w6iTiKyqqBA9a41Wnggw8=
244246
github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI=
245247
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
@@ -476,18 +478,18 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/
476478
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI=
477479
go.opentelemetry.io/contrib/propagators/b3 v1.34.0 h1:9pQdCEvV/6RWQmag94D6rhU+A4rzUhYBEJ8bpscx5p8=
478480
go.opentelemetry.io/contrib/propagators/b3 v1.34.0/go.mod h1:FwM71WS8i1/mAK4n48t0KU6qUS/OZRBgDrHZv3RlJ+w=
479-
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
480-
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
481+
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
482+
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
481483
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc=
482484
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I=
483-
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
484-
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
485+
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
486+
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
485487
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
486488
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
487489
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
488490
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
489-
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
490-
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
491+
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
492+
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
491493
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
492494
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
493495
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -505,8 +507,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
505507
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
506508
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
507509
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
508-
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
509-
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
510+
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
511+
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
510512
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
511513
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
512514
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
@@ -538,8 +540,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
538540
golang.org/x/sync v0.0.0-20201008141435-b3e1573b7520/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
539541
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
540542
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
541-
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
542-
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
543+
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
544+
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
543545
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
544546
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
545547
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -560,8 +562,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
560562
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
561563
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
562564
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
563-
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
564-
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
565+
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
566+
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
565567
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
566568
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
567569
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -570,8 +572,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
570572
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
571573
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
572574
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
573-
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
574-
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
575+
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
576+
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
575577
golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
576578
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
577579
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=

server/internal/app/app.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ func initEcho(ctx context.Context, cfg *ServerConfig) *echo.Echo {
134134
api := e.Group("/api")
135135
api.GET("/ping", Ping(), privateCache)
136136
api.GET("/published/:name", PublishedMetadata())
137+
api.GET("/health", HealthCheck(cfg.Config, "v1.0.0"))
137138
api.GET("/published_data/:name", PublishedData("", true))
138139

139140
apiPrivate := api.Group("", privateCache)

server/internal/app/config/config.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,17 @@ type Config struct {
7373

7474
MockAuth bool `pp:",omitempty"`
7575

76+
// Health Check Configuration
77+
HealthCheck HealthCheckConfig `pp:",omitempty"`
78+
7679
Visualizer VisualizerConfig `pp:",omitempty"`
7780
}
7881

82+
type HealthCheckConfig struct {
83+
Username string `pp:",omitempty"`
84+
Password string `pp:",omitempty"`
85+
}
86+
7987
type VisualizerConfig struct {
8088
InternalApi InternalApiConfig `pp:",omitempty"`
8189
}

server/internal/app/health.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package app
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"net/url"
9+
"time"
10+
11+
"cloud.google.com/go/storage"
12+
"github.com/hellofresh/health-go/v5"
13+
"github.com/hellofresh/health-go/v5/checks/mongo"
14+
"github.com/labstack/echo/v4"
15+
"github.com/reearth/reearth/server/internal/app/config"
16+
"github.com/reearth/reearthx/log"
17+
)
18+
19+
func HealthCheck(conf *config.Config, ver string) echo.HandlerFunc {
20+
checks := []health.Config{
21+
{
22+
Name: "db",
23+
Timeout: time.Second * 5,
24+
SkipOnErr: false,
25+
Check: mongo.New(mongo.Config{DSN: conf.DB}),
26+
},
27+
}
28+
29+
for _, u := range conf.DB_Users {
30+
checks = append(checks, health.Config{
31+
Name: "db-" + u.Name,
32+
Timeout: time.Second * 5,
33+
SkipOnErr: false,
34+
Check: mongo.New(mongo.Config{DSN: u.URI}),
35+
})
36+
}
37+
38+
if conf.GCS.BucketName != "" {
39+
checks = append(checks, health.Config{
40+
Name: "gcs",
41+
Timeout: time.Second * 5,
42+
SkipOnErr: false,
43+
Check: func(ctx context.Context) error { return gcsCheck(ctx, conf.GCS.BucketName) },
44+
})
45+
}
46+
47+
for _, a := range conf.Auths() {
48+
if a.ISS != "" {
49+
u, err := url.Parse(a.ISS)
50+
if err != nil {
51+
log.Fatalf("invalid issuer URL: %v", err)
52+
}
53+
// Capture the issuer URL string so each closure gets its own copy.
54+
issuerURL := u.JoinPath(".well-known/openid-configuration").String()
55+
checks = append(checks, health.Config{
56+
Name: "auth:" + a.ISS,
57+
Timeout: time.Second * 5,
58+
SkipOnErr: false,
59+
Check: func(ctx context.Context) error {
60+
return authServerPingCheck(issuerURL)
61+
},
62+
})
63+
}
64+
}
65+
66+
h, err := health.New(health.WithComponent(health.Component{
67+
Name: "reearth-visualizer",
68+
Version: ver,
69+
}), health.WithChecks(checks...))
70+
if err != nil {
71+
log.Fatalf("failed to create health check: %v", err)
72+
}
73+
74+
return func(c echo.Context) error {
75+
// Optional HTTP Basic Auth
76+
if conf.HealthCheck.Username != "" && conf.HealthCheck.Password != "" {
77+
username, password, ok := c.Request().BasicAuth()
78+
if !ok || username != conf.HealthCheck.Username || password != conf.HealthCheck.Password {
79+
return c.JSON(http.StatusUnauthorized, map[string]string{
80+
"error": "unauthorized",
81+
})
82+
}
83+
}
84+
85+
// Serve the health check
86+
h.Handler().ServeHTTP(c.Response(), c.Request())
87+
return nil
88+
}
89+
}
90+
91+
func gcsCheck(ctx context.Context, bucketName string) (checkErr error) {
92+
client, err := storage.NewClient(ctx)
93+
if err != nil {
94+
return fmt.Errorf("GCS client creation failed: %v", err)
95+
}
96+
defer func(client *storage.Client) {
97+
err := client.Close()
98+
if err != nil {
99+
checkErr = fmt.Errorf("GCS client close failed: %v", err)
100+
}
101+
}(client)
102+
103+
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
104+
defer cancel()
105+
106+
_, err = client.Bucket(bucketName).Attrs(ctx)
107+
if err != nil {
108+
return fmt.Errorf("GCS bucket access failed: %v", err)
109+
}
110+
return nil
111+
}
112+
113+
func authServerPingCheck(issuerURL string) (checkErr error) {
114+
client := http.Client{
115+
Timeout: 2 * time.Second,
116+
}
117+
resp, err := client.Get(issuerURL)
118+
if err != nil {
119+
return fmt.Errorf("auth server unreachable: %v", err)
120+
}
121+
defer func(Body io.ReadCloser) {
122+
err := Body.Close()
123+
if err != nil {
124+
checkErr = fmt.Errorf("failed to close response body: %v", err)
125+
}
126+
}(resp.Body)
127+
128+
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
129+
return fmt.Errorf("auth server unhealthy, status: %d", resp.StatusCode)
130+
}
131+
return nil
132+
}

0 commit comments

Comments
 (0)