feat: read yaml as config for potentialy configuring the app

This commit is contained in:
Tine 2024-02-15 18:43:35 +01:00
parent 1e09aa1455
commit 6243cb28f3
Signed by: mentos1386
SSH key fingerprint: SHA256:MNtTsLbihYaWF8j1fkOHfkKNlnN1JQfxEU/rBU8nCGw
17 changed files with 641 additions and 71 deletions

View file

@ -16,7 +16,7 @@ func main() {
r := mux.NewRouter()
db, query, err := internal.ConnectToDatabase(config.ZDRAVKO_DATABASE_PATH)
db, query, err := internal.ConnectToDatabase(config.DatabasePath)
if err != nil {
log.Fatal(err)
}
@ -60,6 +60,6 @@ func main() {
// 404
r.PathPrefix("/").HandlerFunc(h.Error404).Methods("GET")
log.Println("Server started on", config.PORT)
log.Fatal(http.ListenAndServe(":"+config.PORT, r))
log.Println("Server started on", config.Port)
log.Fatal(http.ListenAndServe(":"+config.Port, r))
}

View file

@ -14,7 +14,7 @@ func main() {
// Initialize a Temporal Client
// Specify the Namespace in the Client options
clientOptions := client.Options{
HostPort: config.TEMPORAL_SERVER_HOST,
HostPort: config.Temporal.ServerHost,
Namespace: "default",
}
temporalClient, err := client.Dial(clientOptions)

23
go.mod
View file

@ -33,14 +33,19 @@ require (
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/coreos/go-oidc/v3 v3.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.18.0 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/gocql/gocql v1.5.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
@ -58,6 +63,7 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
@ -70,18 +76,22 @@ require (
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/labstack/echo/v4 v4.9.1 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/olivere/elastic/v7 v7.0.32 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pborman/uuid v1.2.1 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
@ -90,9 +100,17 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/robfig/cron v1.2.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/temporalio/ringpop-go v0.0.0-20230606200434-b5c079f412d3 // indirect
github.com/temporalio/sqlparser v0.0.0-20231115171017-f4060bcfa6cb // indirect
github.com/temporalio/tchannel-go v1.22.1-0.20231116015023-bd4fb7678499 // indirect
@ -140,6 +158,7 @@ require (
google.golang.org/grpc v1.61.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/validator.v2 v2.0.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

42
go.sum
View file

@ -65,6 +65,8 @@ github.com/crossdock/crossdock-go v0.0.0-20160816171116-049aabb0122b/go.mod h1:v
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-farm v0.0.0-20140601200337-fc41e106ee0e/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
@ -85,6 +87,10 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-faker/faker/v4 v4.2.0 h1:dGebOupKwssrODV51E0zbMrv5e2gO9VWSLNC1WDCpWg=
github.com/go-faker/faker/v4 v4.2.0/go.mod h1:F/bBy8GH9NxOxMInug5Gx4WYeG6fHJZ8Ol/dhcpRub4=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@ -99,6 +105,12 @@ github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.18.0 h1:BvolUXjp4zuvkZ5YN5t7ebzbhlUtPsPm2S9NAZ5nl9U=
github.com/go-playground/validator/v10 v10.18.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
@ -186,6 +198,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0Q
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
@ -235,9 +249,13 @@ github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+
github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
@ -256,6 +274,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@ -272,12 +292,16 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a h1:AA9vgIBDjMHPC2McaGPojgV2dcI78ZC0TLNhYCXEKH8=
github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a/go.mod h1:lzZQ3Noex5pfAy7mkAeCjcBDteYU85uWWnJ/y6gKU8k=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@ -315,6 +339,10 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/samuel/go-thrift v0.0.0-20190219015601-e8b6b52668fe/go.mod h1:Vrkh1pnjV9Bl8c3P9zH0/D4NlOHWP5d4/hF4YTULaec=
github.com/sirupsen/logrus v1.0.2-0.20170726183946-abee6f9b0679/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@ -322,6 +350,16 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@ -337,6 +375,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/temporalio/ringpop-go v0.0.0-20230606200434-b5c079f412d3 h1:V1U9fvhusDJ1pyAvQWg0+u6mQ+o5WtRfMbnnTIZe0Fo=
github.com/temporalio/ringpop-go v0.0.0-20230606200434-b5c079f412d3/go.mod h1:LA2yFb94r5XoEnuMVHkCC/P5174whMy2Dd+cu+AEcQA=
github.com/temporalio/sqlparser v0.0.0-20231115171017-f4060bcfa6cb h1:YzHH/U/dN7vMP+glybzcXRTczTrgfdRisNTzAj7La04=
@ -626,6 +666,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=

View file

@ -1,66 +1,125 @@
package internal
import (
"fmt"
"log"
"os"
"strings"
"time"
"github.com/go-playground/validator/v10"
"github.com/spf13/viper"
)
type Config struct {
PORT string
ROOT_URL string // Needed for oauth2 redirect
Port string `validate:"required"`
RootUrl string `validate:"required,url"`
DatabasePath string `validate:"required"`
SessionSecret string `validate:"required"`
SESSION_SECRET string
OAuth2 OAuth2 `validate:"required"`
OAUTH2_CLIENT_ID string
OAUTH2_CLIENT_SECRET string
OAUTH2_SCOPES []string
OAUTH2_ENDPOINT_TOKEN_URL string
OAUTH2_ENDPOINT_AUTH_URL string
OAUTH2_ENDPOINT_USER_INFO_URL string
OAUTH2_ENDPOINT_LOGOUT_URL string
Temporal Temporal `validate:"required"`
ZDRAVKO_DATABASE_PATH string
TEMPORAL_DATABASE_PATH string
TEMPORAL_LISTEN_ADDRESS string
TEMPORAL_UI_HOST string
TEMPORAL_SERVER_HOST string
HealthChecks []Healthcheck
CronJobs []CronJob
}
func getEnv(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
type OAuth2 struct {
ClientID string `validate:"required"`
ClientSecret string `validate:"required"`
Scopes []string `validate:"required"`
EndpointTokenURL string `validate:"required"`
EndpointAuthURL string `validate:"required"`
EndpointUserInfoURL string `validate:"required"`
EndpointLogoutURL string `validate:"required"`
}
func getEnvRequired(key string) string {
if value, ok := os.LookupEnv(key); ok {
return value
type Temporal struct {
DatabasePath string `validate:"required"`
ListenAddress string `validate:"required"`
UIHost string `validate:"required"`
ServerHost string `validate:"required"`
}
panic("Environment variable " + key + " is required")
type HealthCheckHTTP struct {
URL string `validate:"required,url"`
Method string `validate:"required,oneof=GET POST PUT"`
}
type HealthCheckTCP struct {
Host string `validate:"required,hostname"`
Port int `validate:"required,gte=1,lte=65535"`
}
type Healthcheck struct {
Name string `validate:"required"`
Retries int `validate:"optional,gte=0"`
Schedule string `validate:"required,cron"`
Timeout time.Duration `validate:"required"`
HTTP HealthCheckHTTP `validate:"required"`
TCP HealthCheckTCP `validate:"required"`
}
type CronJob struct {
Name string `validate:"required"`
Schedule string `validate:"required,cron"`
Buffer time.Duration `validate:"required"`
}
func NewConfig() *Config {
return &Config{
PORT: getEnv("PORT", "8000"),
ROOT_URL: getEnvRequired("ROOT_URL"),
viper.SetConfigName("zdravko")
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/zdravko/")
viper.AddConfigPath("$HOME/.zdravko")
viper.AddConfigPath("$HOME/.config/zdravko")
viper.AddConfigPath("$XDG_CONFIG_HOME/zdravko")
viper.AddConfigPath(".")
SESSION_SECRET: getEnvRequired("SESSION_SECRET"),
// Set defaults
viper.SetDefault("port", "8000")
viper.SetDefault("rooturl", "http://localhost:8000")
viper.SetDefault("databasepath", "zdravko.db")
viper.SetDefault("oauth2.scopes", "openid profile email")
viper.SetDefault("temporal.databasepath", "temporal.db")
viper.SetDefault("temporal.listenaddress", "0.0.0.0")
viper.SetDefault("temporal.uihost", "127.0.0.1:8223")
viper.SetDefault("temporal.serverhost", "127.0.0.1:7233")
OAUTH2_CLIENT_ID: getEnvRequired("OAUTH2_CLIENT_ID"),
OAUTH2_CLIENT_SECRET: getEnvRequired("OAUTH2_CLIENT_SECRET"),
OAUTH2_SCOPES: strings.Split(getEnv("OAUTH2_SCOPES", "openid,profile,email"), ","),
OAUTH2_ENDPOINT_TOKEN_URL: getEnvRequired("OAUTH2_ENDPOINT_TOKEN_URL"),
OAUTH2_ENDPOINT_AUTH_URL: getEnvRequired("OAUTH2_ENDPOINT_AUTH_URL"),
OAUTH2_ENDPOINT_USER_INFO_URL: getEnvRequired("OAUTH2_ENDPOINT_USER_INFO_URL"),
OAUTH2_ENDPOINT_LOGOUT_URL: getEnvRequired("OAUTH2_ENDPOINT_LOGOUT_URL"),
// Cant figure out the viper env, so lets just do it manually.
viper.SetDefault("sessionsecret", os.Getenv("SESSION_SECRET"))
viper.SetDefault("oauth2.clientid", os.Getenv("OAUTH2_CLIENT_ID"))
viper.SetDefault("oauth2.clientsecret", os.Getenv("OAUTH2_CLIENT_SECRET"))
viper.SetDefault("oauth2.scope", os.Getenv("OAUTH2_ENDPOINT_SCOPE"))
viper.SetDefault("oauth2.endpointtokenurl", os.Getenv("OAUTH2_ENDPOINT_TOKEN_URL"))
viper.SetDefault("oauth2.endpointauthurl", os.Getenv("OAUTH2_ENDPOINT_AUTH_URL"))
viper.SetDefault("oauth2.endpointuserinfourl", os.Getenv("OAUTH2_ENDPOINT_USER_INFO_URL"))
viper.SetDefault("oauth2.endpointlogouturl", os.Getenv("OAUTH2_ENDPOINT_LOGOUT_URL"))
ZDRAVKO_DATABASE_PATH: getEnv("ZDRAVKO_DATABASE_PATH", "zdravko.db"),
TEMPORAL_DATABASE_PATH: getEnv("TEMPORAL_DATABASE_PATH", "temporal.db"),
TEMPORAL_LISTEN_ADDRESS: getEnv("TEMPORAL_LISTEN_ADDRESS", "0.0.0.0"),
TEMPORAL_UI_HOST: getEnv("TEMPORAL_UI_HOST", "127.0.0.1:8223"),
TEMPORAL_SERVER_HOST: getEnv("TEMPORAL_SERVER_HOST", "127.0.0.1:7233"),
err := viper.ReadInConfig()
if err != nil {
log.Fatalf("Error reading config file, %s", err)
}
log.Println("Config file used: ", viper.ConfigFileUsed())
config := &Config{}
err = viper.Unmarshal(config)
if err != nil {
log.Fatalf("Error unmarshalling config, %s", err)
}
// OAuth2 scopes are space separated
config.OAuth2.Scopes = strings.Split(viper.GetString("oauth2.scopes"), " ")
// Validate config
validate := validator.New(validator.WithRequiredStructEnabled())
err = validate.Struct(config)
if err != nil {
log.Fatalf("Error validating config, %s", err)
}
fmt.Printf("Config: %+v\n", config)
return config
}

View file

@ -32,7 +32,7 @@ type BaseHandler struct {
}
func NewBaseHandler(db *gorm.DB, q *query.Query, config *internal.Config) *BaseHandler {
store := sessions.NewCookieStore([]byte(config.SESSION_SECRET))
store := sessions.NewCookieStore([]byte(config.SessionSecret))
return &BaseHandler{db, q, config, store}
}

View file

@ -31,13 +31,13 @@ func newRandomState() string {
func newOAuth2(config *internal.Config) *oauth2.Config {
return &oauth2.Config{
ClientID: config.OAUTH2_CLIENT_ID,
ClientSecret: config.OAUTH2_CLIENT_SECRET,
Scopes: config.OAUTH2_SCOPES,
RedirectURL: config.ROOT_URL + "/oauth2/callback",
ClientID: config.OAuth2.ClientID,
ClientSecret: config.OAuth2.ClientSecret,
Scopes: config.OAuth2.Scopes,
RedirectURL: config.RootUrl + "/oauth2/callback",
Endpoint: oauth2.Endpoint{
TokenURL: config.OAUTH2_ENDPOINT_TOKEN_URL,
AuthURL: config.OAUTH2_ENDPOINT_AUTH_URL,
TokenURL: config.OAuth2.EndpointTokenURL,
AuthURL: config.OAuth2.EndpointAuthURL,
},
}
}
@ -119,7 +119,7 @@ func (h *BaseHandler) OAuth2CallbackGET(w http.ResponseWriter, r *http.Request)
// Ge the user information.
client := oauth2.NewClient(ctx, oauth2.StaticTokenSource(tok))
resp, err := client.Get(h.config.OAUTH2_ENDPOINT_USER_INFO_URL)
resp, err := client.Get(h.config.OAuth2.EndpointUserInfoURL)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@ -156,7 +156,7 @@ func (h *BaseHandler) OAuth2CallbackGET(w http.ResponseWriter, r *http.Request)
func (h *BaseHandler) OAuth2LogoutGET(w http.ResponseWriter, r *http.Request, user *AuthenticatedUser) {
tok := h.AuthenticatedUserToOAuth2Token(user)
client := oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(tok))
_, err := client.Get(h.config.OAUTH2_ENDPOINT_USER_INFO_URL)
_, err := client.Get(h.config.OAuth2.EndpointLogoutURL)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return

View file

@ -18,6 +18,7 @@ type Settings struct {
var SettingsPages = []*components.Page{
{Path: "/settings", Title: "Overview"},
{Path: "/settings/healthchecks", Title: "Healthchecks"},
{Path: "/settings/cronjobs", Title: "CronJobs"},
{Path: "/settings/workers", Title: "Workers"},
{Path: "/temporal", Title: "Temporal"},
{Path: "/oauth2/logout", Title: "Logout"},

View file

@ -8,7 +8,7 @@ import (
func (h *BaseHandler) Temporal(w http.ResponseWriter, r *http.Request, user *AuthenticatedUser) {
proxy := httputil.NewSingleHostReverseProxy(&url.URL{
Host: h.config.TEMPORAL_UI_HOST,
Host: h.config.Temporal.UIHost,
Scheme: "http",
})

View file

@ -29,7 +29,7 @@ func NewServerConfig(cfg *internal.Config) *config.Config {
ConnectAttributes: map[string]string{
"mode": "rwc",
},
DatabaseName: cfg.TEMPORAL_DATABASE_PATH,
DatabaseName: cfg.Temporal.DatabasePath,
},
},
},
@ -50,7 +50,7 @@ func NewServerConfig(cfg *internal.Config) *config.Config {
GRPCPort: FrontendPort,
MembershipPort: FrontendPort + 100,
BindOnLocalHost: false,
BindOnIP: cfg.TEMPORAL_LISTEN_ADDRESS,
BindOnIP: cfg.Temporal.ListenAddress,
},
},
"history": {

View file

@ -9,9 +9,9 @@ import (
func NewUiConfig(cfg *internal.Config) *config.Config {
return &config.Config{
Host: cfg.TEMPORAL_LISTEN_ADDRESS,
Host: cfg.Temporal.ListenAddress,
Port: 8223,
TemporalGRPCAddress: cfg.TEMPORAL_SERVER_HOST,
TemporalGRPCAddress: cfg.Temporal.ServerHost,
EnableUI: true,
PublicPath: "/temporal",
Codec: config.Codec{

View file

@ -16,7 +16,7 @@ func main() {
FieldNullable: true,
})
db, _, _ := internal.ConnectToDatabase(config.ZDRAVKO_DATABASE_PATH)
db, _, _ := internal.ConnectToDatabase(config.DatabasePath)
// Use the above `*gorm.DB` instance to initialize the generator,
// which is required to generate structs from db when using `GenerateModel/GenerateModelAs`

View file

@ -48,7 +48,7 @@
}
.healthchecks {
@apply grid justify-items-stretch justify-stretch items-center mt-20 bg-gray-200 shadow-inner p-5 rounded-lg;
@apply grid justify-items-stretch justify-stretch items-center mt-20 bg-white shadow-md p-5 rounded-lg;
}
.healthchecks > div:not(:last-child) {

View file

@ -590,6 +590,10 @@ video {
}
}
.relative {
position: relative;
}
.col-span-2 {
grid-column: span 2 / span 2;
}
@ -603,10 +607,22 @@ video {
margin-bottom: 1rem;
}
.mb-8 {
margin-bottom: 2rem;
}
.me-2 {
margin-inline-end: 0.5rem;
}
.ms-2 {
margin-inline-start: 0.5rem;
}
.mt-1 {
margin-top: 0.25rem;
}
.mt-20 {
margin-top: 5rem;
}
@ -619,6 +635,14 @@ video {
display: flex;
}
.inline-flex {
display: inline-flex;
}
.table {
display: table;
}
.grid {
display: grid;
}
@ -631,6 +655,10 @@ video {
height: 0.75rem;
}
.h-3\.5 {
height: 0.875rem;
}
.h-8 {
height: 2rem;
}
@ -643,10 +671,22 @@ video {
width: 0.75rem;
}
.w-3\.5 {
width: 0.875rem;
}
.w-full {
width: 100%;
}
.max-w-screen-md {
max-width: 768px;
}
.max-w-screen-xl {
max-width: 1280px;
}
.flex-auto {
flex: 1 1 auto;
}
@ -671,6 +711,10 @@ video {
align-items: center;
}
.justify-center {
justify-content: center;
}
.gap-2 {
gap: 0.5rem;
}
@ -683,6 +727,12 @@ video {
gap: 1px;
}
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.justify-self-start {
justify-self: start;
}
@ -699,6 +749,14 @@ video {
overflow: visible;
}
.overflow-x-auto {
overflow-x: auto;
}
.whitespace-nowrap {
white-space: nowrap;
}
.rounded {
border-radius: 0.25rem;
}
@ -707,11 +765,29 @@ video {
border-radius: 9999px;
}
.rounded-lg {
border-radius: 0.5rem;
}
.border-b {
border-bottom-width: 1px;
}
.bg-blue-700 {
--tw-bg-opacity: 1;
background-color: rgb(29 78 216 / var(--tw-bg-opacity));
}
.bg-gray-100 {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
}
.bg-gray-50 {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
}
.bg-green-300 {
--tw-bg-opacity: 1;
background-color: rgb(134 239 172 / var(--tw-bg-opacity));
@ -732,19 +808,77 @@ video {
background-color: rgb(248 113 113 / var(--tw-bg-opacity));
}
.bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.p-4 {
padding: 1rem;
}
.p-5 {
padding: 1.25rem;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.px-5 {
padding-left: 1.25rem;
padding-right: 1.25rem;
}
.px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.py-3 {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
}
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
.py-8 {
padding-top: 2rem;
padding-bottom: 2rem;
}
.text-left {
text-align: left;
}
.text-center {
text-align: center;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
}
.text-base {
font-size: 1rem;
line-height: 1.5rem;
}
.text-lg {
font-size: 1.125rem;
line-height: 1.75rem;
}
.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
@ -759,6 +893,34 @@ video {
font-weight: 700;
}
.font-extrabold {
font-weight: 800;
}
.font-medium {
font-weight: 500;
}
.font-normal {
font-weight: 400;
}
.font-semibold {
font-weight: 600;
}
.uppercase {
text-transform: uppercase;
}
.leading-none {
line-height: 1;
}
.tracking-tight {
letter-spacing: -0.025em;
}
.text-blue-600 {
--tw-text-opacity: 1;
color: rgb(37 99 235 / var(--tw-text-opacity));
@ -769,6 +931,16 @@ video {
color: rgb(107 114 128 / var(--tw-text-opacity));
}
.text-gray-700 {
--tw-text-opacity: 1;
color: rgb(55 65 81 / var(--tw-text-opacity));
}
.text-gray-900 {
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-red-600 {
--tw-text-opacity: 1;
color: rgb(220 38 38 / var(--tw-text-opacity));
@ -779,10 +951,21 @@ video {
color: rgb(100 116 139 / var(--tw-text-opacity));
}
.text-white {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
}
.underline {
text-decoration-line: underline;
}
.shadow-md {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.navbar {
margin-top: 2.5rem;
display: flex;
@ -900,10 +1083,10 @@ video {
justify-items: stretch;
border-radius: 0.5rem;
--tw-bg-opacity: 1;
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
padding: 1.25rem;
--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
@ -911,6 +1094,21 @@ video {
margin-bottom: 0.75rem;
}
.odd\:bg-white:nth-child(odd) {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.even\:bg-gray-50:nth-child(even) {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
}
.hover\:bg-blue-800:hover {
--tw-bg-opacity: 1;
background-color: rgb(30 64 175 / var(--tw-bg-opacity));
}
.hover\:bg-green-500:hover {
--tw-bg-opacity: 1;
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
@ -924,3 +1122,79 @@ video {
.hover\:underline:hover {
text-decoration-line: underline;
}
.focus\:ring-4:focus {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.focus\:ring-blue-300:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(147 197 253 / var(--tw-ring-opacity));
}
@media (min-width: 640px) {
.sm\:flex-row {
flex-direction: row;
}
.sm\:justify-center {
justify-content: center;
}
.sm\:space-y-0 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0px * var(--tw-space-y-reverse));
}
.sm\:rounded-lg {
border-radius: 0.5rem;
}
.sm\:px-8 {
padding-left: 2rem;
padding-right: 2rem;
}
}
@media (min-width: 768px) {
.md\:text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
}
}
@media (min-width: 1024px) {
.lg\:px-40 {
padding-left: 10rem;
padding-right: 10rem;
}
.lg\:py-16 {
padding-top: 4rem;
padding-bottom: 4rem;
}
.lg\:text-4xl {
font-size: 2.25rem;
line-height: 2.5rem;
}
}
.rtl\:rotate-180:where([dir="rtl"], [dir="rtl"] *) {
--tw-rotate: 180deg;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rtl\:text-right:where([dir="rtl"], [dir="rtl"] *) {
text-align: right;
}
@media (prefers-color-scheme: dark) {
.dark\:text-gray-400 {
--tw-text-opacity: 1;
color: rgb(156 163 175 / var(--tw-text-opacity));
}
}

View file

@ -1,5 +1,142 @@
{{define "settings"}}
<h1 class="text-3xl">Hello, {{.User.Email}}</h1>
<p> Imagine you see a list of healthchecks and how to configure them.<p>
{{ $description := "Healthchecks represent periodic checks of some HTTP or TCP service, to see if it's responding correctly to deterime if it's healthy or not." }}
<section>
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1 class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl">
There are no healthchecks yet.
</h1>
<p class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40">
{{ $description }}
</p>
<div class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0">
<a href="#" class="inline-flex justify-center items-center py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300">
Create Healthcheck
<svg class="w-3.5 h-3.5 ms-2 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9"/>
</svg>
</a>
</div>
</div>
</section>
<div class="relative overflow-x-auto shadow-md sm:rounded-lg">
<table class="w-full text-sm text-left rtl:text-right text-gray-500">
<caption class="p-5 text-lg font-semibold text-left rtl:text-right text-gray-900 bg-white">
List of Healthchecks
<p class="mt-1 text-sm font-normal text-gray-500 dark:text-gray-400">
Healthchecks represent periodic checks of some HTTP or TCP service, to see if it's
responding correctly to deterime if it's healthy or not.
</p>
</caption>
<thead class="text-xs text-gray-700 uppercase bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3">
Name
</th>
<th scope="col" class="px-6 py-3">
Type
</th>
<th scope="col" class="px-6 py-3">
Status
</th>
<th scope="col" class="px-6 py-3">
Cron
</th>
<th scope="col" class="px-6 py-3">
Action
</th>
</tr>
</thead>
<tbody>
<tr class="odd:bg-white even:bg-gray-50">
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
Apple MacBook Pro 17"
</th>
<td class="px-6 py-4">
Silver
</td>
<td class="px-6 py-4">
Laptop
</td>
<td class="px-6 py-4">
$2999
</td>
<td class="px-6 py-4">
<a href="#" class="font-medium text-blue-600 hover:underline">Details</a>
</td>
</tr>
<tr class="odd:bg-white even:bg-gray-50">
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
Microsoft Surface Pro
</th>
<td class="px-6 py-4">
White
</td>
<td class="px-6 py-4">
Laptop PC
</td>
<td class="px-6 py-4">
$1999
</td>
<td class="px-6 py-4">
<a href="#" class="font-medium text-blue-600 hover:underline">Details</a>
</td>
</tr>
<tr class="odd:bg-white even:bg-gray-50 border-b">
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
Magic Mouse 2
</th>
<td class="px-6 py-4">
Black
</td>
<td class="px-6 py-4">
Accessories
</td>
<td class="px-6 py-4">
$99
</td>
<td class="px-6 py-4">
<a href="#" class="font-medium text-blue-600 hover:underline">Details</a>
</td>
</tr>
<tr class="odd:bg-white even:bg-gray-50 border-b">
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
Google Pixel Phone
</th>
<td class="px-6 py-4">
Gray
</td>
<td class="px-6 py-4">
Phone
</td>
<td class="px-6 py-4">
$799
</td>
<td class="px-6 py-4">
<a href="#" class="font-medium text-blue-600 hover:underline">Details</a>
</td>
</tr>
<tr class="odd:bg-white even:bg-gray-50 border-b">
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
Apple Watch 5
</th>
<td class="px-6 py-4">
Red
</td>
<td class="px-6 py-4">
Wearables
</td>
<td class="px-6 py-4">
$999
</td>
<td class="px-6 py-4">
<a href="#" class="font-medium text-blue-600 hover:underline">Details</a>
</td>
</tr>
</tbody>
</table>
</div>
{{end}}

View file

@ -1,3 +1,14 @@
{{define "settings"}}
<h1 class="text-3xl">Hello, {{.User.Email}}</h1>
<section>
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1 class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl">
Hi there, {{.User.Email}}.
</h1>
<p class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
</div>
</section>
{{end}}

27
zdravko.yaml Normal file
View file

@ -0,0 +1,27 @@
healthchecks:
- name: "Google"
http:
url: "https://www.google.com"
method: GET
timeout: 5s
schedule: "* * * * *"
retries: 3
- name: "GitHub"
http:
url: "https://www.github.com"
method: GET
timeout: 5s
schedule: "* * * * *"
retries: 3
- name: "Docker"
tcp:
hostname: "docker.com"
port: 443
schedule: "* * * * *"
timeout: 60s
retries: 3
cronjobs:
- name: "Backup"
schedule: "0 0 * * *"
buffer: 1h