From 26777963220dd13baf0a8756c21df07e593c1b19 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Sun, 6 Nov 2022 07:54:32 -0800 Subject: [PATCH 01/26] fixing bug. Null value for temperatures should be ignored. --- .../backend/pkg/database/scrutiny_repository_temperature.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/webapp/backend/pkg/database/scrutiny_repository_temperature.go b/webapp/backend/pkg/database/scrutiny_repository_temperature.go index fb3be6a..9edec87 100644 --- a/webapp/backend/pkg/database/scrutiny_repository_temperature.go +++ b/webapp/backend/pkg/database/scrutiny_repository_temperature.go @@ -17,6 +17,10 @@ func (sr *scrutinyRepository) SaveSmartTemperature(ctx context.Context, wwn stri if len(collectorSmartData.AtaSctTemperatureHistory.Table) > 0 { for ndx, temp := range collectorSmartData.AtaSctTemperatureHistory.Table { + //temp value may be null, we must skip/ignore them. See #393 + if temp == 0 { + continue + } minutesOffset := collectorSmartData.AtaSctTemperatureHistory.LoggingIntervalMinutes * int64(ndx) * 60 smartTemp := measurements.SmartTemperature{ From 89f763e65d3474b3e051c5fcd61fe33151a4b0d2 Mon Sep 17 00:00:00 2001 From: boomam <37086258+boomam@users.noreply.github.com> Date: Sun, 27 Nov 2022 19:27:10 -0500 Subject: [PATCH 02/26] Addition of notification testing command to troubleshooting Addition of notification testing command to troubleshooting. --- docs/TROUBLESHOOTING_NOTIFICATIONS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/TROUBLESHOOTING_NOTIFICATIONS.md b/docs/TROUBLESHOOTING_NOTIFICATIONS.md index 2f2abee..9929de7 100644 --- a/docs/TROUBLESHOOTING_NOTIFICATIONS.md +++ b/docs/TROUBLESHOOTING_NOTIFICATIONS.md @@ -24,3 +24,7 @@ SCRUTINY_MESSAGE - eg. "Scrutiny SMART error notification for device: %s\nFailur SCRUTINY_HOST_ID - (optional) eg. "my-custom-host-id" ``` +# Testing Notifications +You can test that your notifications are configured correctly by posting an empty payload to the notifications health check API. + +curl -X POST http://localhost:8080/api/health/notify From fcd4bb4561b0dccb20441e3d39c554979c4795a2 Mon Sep 17 00:00:00 2001 From: boomam <37086258+boomam@users.noreply.github.com> Date: Sun, 27 Nov 2022 19:28:09 -0500 Subject: [PATCH 03/26] Added new formatting ....to match existing doc formatting standard. --- docs/TROUBLESHOOTING_NOTIFICATIONS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/TROUBLESHOOTING_NOTIFICATIONS.md b/docs/TROUBLESHOOTING_NOTIFICATIONS.md index 9929de7..1a1d22c 100644 --- a/docs/TROUBLESHOOTING_NOTIFICATIONS.md +++ b/docs/TROUBLESHOOTING_NOTIFICATIONS.md @@ -26,5 +26,6 @@ SCRUTINY_HOST_ID - (optional) eg. "my-custom-host-id" # Testing Notifications You can test that your notifications are configured correctly by posting an empty payload to the notifications health check API. - +``` curl -X POST http://localhost:8080/api/health/notify +``` From 0febe3fda50d3c8efc14aa11f94ef361d01b915e Mon Sep 17 00:00:00 2001 From: StratusFearMe21 <57533634+StratusFearMe21@users.noreply.github.com> Date: Mon, 28 Nov 2022 05:46:21 +0000 Subject: [PATCH 04/26] Looks like this is already implemented --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5e359f..cb1c60b 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Scrutiny is a simple but focused application, with a couple of core features: - Customized thresholds using real world failure rates - Temperature tracking - Provided as an all-in-one Docker image (but can be installed manually) -- Future Configurable Alerting/Notifications via Webhooks +- Configurable Alerting/Notifications via Webhooks - (Future) Hard Drive performance testing & tracking # Getting Started From 0a6ade4da9ba47981743d657c42636bf2fa60989 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Mon, 28 Nov 2022 08:13:19 -0800 Subject: [PATCH 05/26] trying to fix build --- .github/workflows/docker-build.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index cc8928b..de4bf03 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -77,6 +77,8 @@ jobs: - name: "Generate frontend" uses: addnab/docker-run-action@v3 with: + env: + NODE_OPTIONS: '--openssl-legacy-provider' image: node:lts options: -v ${{ github.workspace }}:/work run: | @@ -181,4 +183,4 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} # cache-from: type=gha -# cache-to: type=gha,mode=max \ No newline at end of file +# cache-to: type=gha,mode=max From dd03a8cf63880b84fb69a9352bd3fb7787c890fa Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Mon, 28 Nov 2022 08:16:45 -0800 Subject: [PATCH 06/26] Revert "trying to fix build" This reverts commit 0a6ade4da9ba47981743d657c42636bf2fa60989. --- .github/workflows/docker-build.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index de4bf03..cc8928b 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -77,8 +77,6 @@ jobs: - name: "Generate frontend" uses: addnab/docker-run-action@v3 with: - env: - NODE_OPTIONS: '--openssl-legacy-provider' image: node:lts options: -v ${{ github.workspace }}:/work run: | @@ -183,4 +181,4 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} # cache-from: type=gha -# cache-to: type=gha,mode=max +# cache-to: type=gha,mode=max \ No newline at end of file From c9f13f439864dd571d3e22fef5aa8735b6a351c2 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Tue, 29 Nov 2022 21:07:51 -0800 Subject: [PATCH 07/26] update README to correctly call-out the influxdb requirement in hub-spoke deployments. references #409 --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cb1c60b..0beddc1 100644 --- a/README.md +++ b/README.md @@ -91,10 +91,14 @@ docker run -it --rm -p 8080:8080 -p 8086:8086 \ ### Hub/Spoke Deployment -In addition to the Omnibus image (available under the `latest` tag) there are 2 other Docker images available: - -- `ghcr.io/analogj/scrutiny:master-collector` - Contains the Scrutiny data collector, `smartctl` binary and cron-like scheduler. You can run one collector on each server. -- `ghcr.io/analogj/scrutiny:master-web` - Contains the Web UI, API and Database. Only one container necessary +In addition to the Omnibus image (available under the `latest` tag) you can deploy in Hub/Spoke mode, which requires 3 +other Docker images: + +- `ghcr.io/analogj/scrutiny:master-collector` - Contains the Scrutiny data collector, `smartctl` binary and cron-like + scheduler. You can run one collector on each server. +- `ghcr.io/analogj/scrutiny:master-web` - Contains the Web UI and API. Only one container necessary +- `influxdb:2.2` - InfluxDB image, used by the Web container to persist SMART data. + See [docs/TROUBLESHOOTING_INFLUXDB.md](./docs/TROUBLESHOOTING_INFLUXDB.md) > See [docker/example.hubspoke.docker-compose.yml](./docker/example.hubspoke.docker-compose.yml) for a docker-compose file. From fb760a9f6d775d1c9fe6b3fab821cc5406fd8449 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Tue, 29 Nov 2022 22:06:42 -0800 Subject: [PATCH 08/26] make sure we print an error if the config file is invalid. fixes #408 --- webapp/backend/cmd/scrutiny/scrutiny.go | 1 + 1 file changed, 1 insertion(+) diff --git a/webapp/backend/cmd/scrutiny/scrutiny.go b/webapp/backend/cmd/scrutiny/scrutiny.go index ae22677..4d9f62f 100644 --- a/webapp/backend/cmd/scrutiny/scrutiny.go +++ b/webapp/backend/cmd/scrutiny/scrutiny.go @@ -34,6 +34,7 @@ func main() { if _, ok := err.(errors.ConfigFileMissingError); ok { // Handle errors reading the config file //ignore "could not find config file" } else if err != nil { + log.Print(color.HiRedString("CONFIG ERROR: %v", err)) os.Exit(1) } From 29a0860caa05439da2414cc62eed2def0ccffeb7 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Tue, 29 Nov 2022 22:24:16 -0800 Subject: [PATCH 09/26] trying to fix nodejs build of frontend. --- .github/workflows/docker-build.yaml | 30 +++++++++++++---------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index cc8928b..cecc0bd 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -74,15 +74,13 @@ jobs: uses: actions/checkout@v2 - name: "Populate frontend version information" run: "cd webapp/frontend && ./git.version.sh" - - name: "Generate frontend" - uses: addnab/docker-run-action@v3 + - name: "Install Node" + uses: actions/setup-node@v3 with: - image: node:lts - options: -v ${{ github.workspace }}:/work - run: | - cd /work - make binary-frontend && echo "print contents of /work/dist" && ls -alt /work/dist - + node-version: 16 + - name: "Generate frontend" + run: | + make binary-frontend && echo "print contents of ./dist" && ls -alt ./dist - name: Set up QEMU uses: docker/setup-qemu-action@v2 with: @@ -135,15 +133,13 @@ jobs: - name: "Populate frontend version information" run: "cd webapp/frontend && ./git.version.sh" - name: "Generate frontend & version information" - uses: addnab/docker-run-action@v3 + - name: "Install Node" + uses: actions/setup-node@v3 with: - image: node:lts - options: -v ${{ github.workspace }}:/work - run: | - cd /work - make binary-frontend && echo "print contents of /work/dist" && ls -alt /work/dist - - + node-version: 16 + - name: "Generate frontend" + run: | + make binary-frontend && echo "print contents of ./dist" && ls -alt ./dist - name: Set up QEMU uses: docker/setup-qemu-action@v2 with: @@ -181,4 +177,4 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} # cache-from: type=gha -# cache-to: type=gha,mode=max \ No newline at end of file +# cache-to: type=gha,mode=max From 6a6570b8e37d9656c97be4dbc95809e76f0ee975 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Tue, 29 Nov 2022 22:45:40 -0800 Subject: [PATCH 10/26] trying to fix nodejs build of frontend. --- .github/workflows/docker-build.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index cecc0bd..e31efb9 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -132,7 +132,6 @@ jobs: uses: actions/checkout@v2 - name: "Populate frontend version information" run: "cd webapp/frontend && ./git.version.sh" - - name: "Generate frontend & version information" - name: "Install Node" uses: actions/setup-node@v3 with: From 58ef1aa311c60743e902c563744aa3cfad3094e3 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Wed, 30 Nov 2022 07:56:01 -0800 Subject: [PATCH 11/26] update readme. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0beddc1..9eba883 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ other Docker images: - `ghcr.io/analogj/scrutiny:master-collector` - Contains the Scrutiny data collector, `smartctl` binary and cron-like scheduler. You can run one collector on each server. - `ghcr.io/analogj/scrutiny:master-web` - Contains the Web UI and API. Only one container necessary -- `influxdb:2.2` - InfluxDB image, used by the Web container to persist SMART data. +- `influxdb:2.2` - InfluxDB image, used by the Web container to persist SMART data. Only one container necessary See [docs/TROUBLESHOOTING_INFLUXDB.md](./docs/TROUBLESHOOTING_INFLUXDB.md) > See [docker/example.hubspoke.docker-compose.yml](./docker/example.hubspoke.docker-compose.yml) for a docker-compose file. From f2856e0f2607237d9886fee8625070448d6de0c4 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Wed, 30 Nov 2022 08:25:27 -0800 Subject: [PATCH 12/26] adding a healthcheck endpoint that confirms communication with influxdb and sqlite. ref: #381 --- webapp/backend/pkg/database/interface.go | 1 + .../pkg/database/scrutiny_repository.go | 23 +++++++++++++++ .../backend/pkg/web/handler/health_check.go | 29 +++++++++++++++++++ webapp/backend/pkg/web/server.go | 10 +------ 4 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 webapp/backend/pkg/web/handler/health_check.go diff --git a/webapp/backend/pkg/database/interface.go b/webapp/backend/pkg/database/interface.go index f140c26..f5dae30 100644 --- a/webapp/backend/pkg/database/interface.go +++ b/webapp/backend/pkg/database/interface.go @@ -10,6 +10,7 @@ import ( type DeviceRepo interface { Close() error + HealthCheck(ctx context.Context) error RegisterDevice(ctx context.Context, dev models.Device) error GetDevices(ctx context.Context) ([]models.Device, error) diff --git a/webapp/backend/pkg/database/scrutiny_repository.go b/webapp/backend/pkg/database/scrutiny_repository.go index 521ba7d..b163c2c 100644 --- a/webapp/backend/pkg/database/scrutiny_repository.go +++ b/webapp/backend/pkg/database/scrutiny_repository.go @@ -195,6 +195,29 @@ func (sr *scrutinyRepository) Close() error { return nil } +func (sr *scrutinyRepository) HealthCheck(ctx context.Context) error { + //check influxdb + status, err := sr.influxClient.Health(ctx) + if err != nil { + return fmt.Errorf("influxdb healthcheck failed: %w", err) + } + if status.Status != "pass" { + return fmt.Errorf("influxdb healthcheckf failed: status=%s", status.Status) + } + + //check sqlite db. + database, err := sr.gormClient.DB() + if err != nil { + return fmt.Errorf("sqlite healthcheck failed: %w", err) + } + err = database.Ping() + if err != nil { + return fmt.Errorf("sqlite healthcheck failed during ping: %w", err) + } + return nil + +} + func InfluxSetupComplete(influxEndpoint string) (bool, error) { influxUri, err := url.Parse(influxEndpoint) if err != nil { diff --git a/webapp/backend/pkg/web/handler/health_check.go b/webapp/backend/pkg/web/handler/health_check.go new file mode 100644 index 0000000..a99bf6f --- /dev/null +++ b/webapp/backend/pkg/web/handler/health_check.go @@ -0,0 +1,29 @@ +package handler + +import ( + "github.com/analogj/scrutiny/webapp/backend/pkg/database" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "net/http" +) + +func HealthCheck(c *gin.Context) { + logger := c.MustGet("LOGGER").(*logrus.Entry) + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) + logger.Infof("Checking Influxdb & Sqlite health") + + //check sqlite and influxdb health + err := deviceRepo.HealthCheck(c) + if err != nil { + logger.Errorln("An error occurred during healthcheck", err) + c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": err.Error()}) + return + } + + //TODO: + // check if the /web folder is populated. + + c.JSON(http.StatusOK, gin.H{ + "success": true, + }) +} diff --git a/webapp/backend/pkg/web/server.go b/webapp/backend/pkg/web/server.go index bb82405..3d56fe0 100644 --- a/webapp/backend/pkg/web/server.go +++ b/webapp/backend/pkg/web/server.go @@ -34,15 +34,7 @@ func (ae *AppEngine) Setup(logger *logrus.Entry) *gin.Engine { { api := base.Group("/api") { - api.GET("/health", func(c *gin.Context) { - //TODO: - // check if the /web folder is populated. - // check if access to influxdb - // check if access to sqlitedb. - c.JSON(http.StatusOK, gin.H{ - "success": true, - }) - }) + api.GET("/health", handler.HealthCheck) api.POST("/health/notify", handler.SendTestNotification) //check if notifications are configured correctly api.POST("/devices/register", handler.RegisterDevices) //used by Collector to register new devices and retrieve filtered list From d843bcc258e11fb25de77cc18c8886341c7ce346 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Fri, 2 Dec 2022 07:13:52 -0800 Subject: [PATCH 13/26] fix nightly build. --- .github/workflows/docker-nightly.yaml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker-nightly.yaml b/.github/workflows/docker-nightly.yaml index ff2addb..59f4601 100644 --- a/.github/workflows/docker-nightly.yaml +++ b/.github/workflows/docker-nightly.yaml @@ -19,16 +19,13 @@ jobs: uses: actions/checkout@v2 - name: "Populate frontend version information" run: "cd webapp/frontend && ./git.version.sh" - - name: "Generate frontend & version information" - uses: addnab/docker-run-action@v3 + - name: "Install Node" + uses: actions/setup-node@v3 with: - image: node:lts - options: -v ${{ github.workspace }}:/work - run: | - cd /work - make binary-frontend && echo "print contents of /work/dist" && ls -alt /work/dist - - + node-version: 16 + - name: "Generate frontend" + run: | + make binary-frontend && echo "print contents of ./dist" && ls -alt ./dist - name: Set up QEMU uses: docker/setup-qemu-action@v2 with: From 61fde6a2cac0dd31cd966837b3cb6e5a33c26d9b Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Wed, 11 Jan 2023 16:17:25 -0800 Subject: [PATCH 14/26] update shoutrrr version. fixes #355 --- go.mod | 16 ++++--------- go.sum | 76 +++++++--------------------------------------------------- 2 files changed, 13 insertions(+), 79 deletions(-) diff --git a/go.mod b/go.mod index 5a6daf3..daa70d2 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/analogj/go-util v0.0.0-20190301173314-5295e364eb14 - github.com/containrrr/shoutrrr v0.4.4 + github.com/containrrr/shoutrrr v0.6.1 github.com/fatih/color v1.10.0 github.com/gin-gonic/gin v1.6.3 github.com/glebarez/sqlite v1.4.5 @@ -24,7 +24,7 @@ require ( require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deepmap/oapi-codegen v1.8.2 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect @@ -43,7 +43,6 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.4 // indirect github.com/json-iterator/go v1.1.9 // indirect - github.com/klauspost/compress v1.11.7 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/kvz/logstreamer v0.0.0-20201023134116-02d20f4338f5 // indirect github.com/leodido/go-urn v1.2.0 // indirect @@ -53,14 +52,11 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect - github.com/nxadm/tail v1.4.6 // indirect - github.com/onsi/ginkgo v1.14.2 // indirect github.com/pelletier/go-toml v1.7.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect - github.com/russross/blackfriday/v2 v2.0.1 // indirect - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -73,17 +69,13 @@ require ( golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64 // indirect golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect golang.org/x/text v0.3.5 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/protobuf v1.23.0 // indirect gopkg.in/ini.v1 v1.55.0 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect - gopkg.in/yaml.v2 v2.3.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - gosrc.io/xmpp v0.5.1 // indirect howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect modernc.org/libc v1.16.8 // indirect modernc.org/mathutil v1.4.1 // indirect modernc.org/memory v1.1.1 // indirect modernc.org/sqlite v1.17.2 // indirect - nhooyr.io/websocket v1.8.6 // indirect ) diff --git a/go.sum b/go.sum index e2bdeaa..45b520d 100644 --- a/go.sum +++ b/go.sum @@ -18,7 +18,6 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/agnivade/wasmbrowsertest v0.3.1/go.mod h1:zQt6ZTdl338xxRaMW395qccVE2eQm0SjC/SDz0mPWQI= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/analogj/go-util v0.0.0-20190301173314-5295e364eb14 h1:wsrSjiqQtseStRIoLLxS4C5IEtXkazZVEPDHq8jW7r8= @@ -33,18 +32,11 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/chromedp/cdproto v0.0.0-20190614062957-d6d2f92b486d/go.mod h1:S8mB5wY3vV+vRIzf39xDXsw3XKYewW9X6rW2aEmkrSw= -github.com/chromedp/cdproto v0.0.0-20190621002710-8cbd498dd7a0/go.mod h1:S8mB5wY3vV+vRIzf39xDXsw3XKYewW9X6rW2aEmkrSw= -github.com/chromedp/cdproto v0.0.0-20190812224334-39ef923dcb8d/go.mod h1:0YChpVzuLJC5CPr+x3xkHN6Z8KOSXjNbL7qV8Wc4GW0= -github.com/chromedp/cdproto v0.0.0-20190926234355-1b4886c6fad6/go.mod h1:0YChpVzuLJC5CPr+x3xkHN6Z8KOSXjNbL7qV8Wc4GW0= -github.com/chromedp/chromedp v0.3.1-0.20190619195644-fd957a4d2901/go.mod h1:mJdvfrVn594N9tfiPecUidF6W5jPRKHymqHfzbobPsM= -github.com/chromedp/chromedp v0.4.0/go.mod h1:DC3QUn4mJ24dwjcaGQLoZrhm4X/uPHZ6spDbS2uFhm4= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/containrrr/shoutrrr v0.4.4 h1:vHZ4E/76pKVY+Jyn/qhBz3X540Bn8NI5ppPHK4PyILY= -github.com/containrrr/shoutrrr v0.4.4/go.mod h1:zqL2BvfC1W4FujrT4b3/ZCLxvD+uoeEpBL7rg9Dqpbg= +github.com/containrrr/shoutrrr v0.6.1 h1:6ih7jA6mo3t6C97MZbd3SxL/kRizOE3bI9CpBQZ6wzg= +github.com/containrrr/shoutrrr v0.6.1/go.mod h1:ye9jGX5YzMnJ76waaNVWlJ4luhMEyt1EWU5unYTQSb0= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -52,8 +44,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -66,8 +58,6 @@ github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xb github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= @@ -89,8 +79,6 @@ github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gormigrate/gormigrate/v2 v2.0.0 h1:e2A3Uznk4viUC4UuemuVgsNnvYZyOA8B3awlYk3UioU= github.com/go-gormigrate/gormigrate/v2 v2.0.0/go.mod h1:YuVJ+D/dNt4HWrThTBnjgZuRbt7AuwINeg4q52ZE3Jw= -github.com/go-interpreter/wagon v0.5.1-0.20190713202023-55a163980b6c/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc= -github.com/go-interpreter/wagon v0.6.0/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -109,12 +97,6 @@ github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GO github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -131,7 +113,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -152,10 +133,7 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190908185732-236ed259b199/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -164,8 +142,6 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -272,10 +248,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= -github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/knq/sysutil v0.0.0-20181215143952-f05b59f0f307/go.mod h1:BjPj+aVjl9FW/cCGiF3nGh5v+9Gd3VCgBQbod/GlMaQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -295,14 +267,10 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= @@ -348,11 +316,9 @@ github.com/nxadm/tail v1.4.6 h1:11TGpSHY7Esh/i/qnq02Jo5oVrI1Gue8Slbq0ujPZFQ= github.com/nxadm/tail v1.4.6/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -383,8 +349,9 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samber/lo v1.25.0 h1:H8F6cB0RotRdgcRCivTByAQePaYhGMdOTJIj2QFS2I0= github.com/samber/lo v1.25.0/go.mod h1:2I7tgIv8Q1SG2xEIkRq0F2i2zgxVpnyPOP0d3Gj2r+A= @@ -392,9 +359,7 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= @@ -412,16 +377,14 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw= github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= @@ -438,8 +401,6 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/twitchyliquid64/golang-asm v0.0.0-20190126203739-365674df15fc/go.mod h1:NoCfSFWosfqMqmmD7hApkirIK9ozpHjxRnRxs1l413A= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= @@ -452,7 +413,6 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -go.coder.com/go-tools v0.0.0-20190317003359-0c6a35b74a16/go.mod h1:iKV5yK9t+J5nG9O3uF6KYdPEz3dyfMyB15MN1rbQ8Qw= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -464,7 +424,6 @@ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKY go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180426230345-b49d69b5da94/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -506,7 +465,6 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -536,7 +494,6 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -548,7 +505,6 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190306220234-b354f8bf4d9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -556,13 +512,10 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190618155005-516e3c20635f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -591,7 +544,6 @@ golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -611,7 +563,6 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -655,14 +606,12 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.55.0 h1:E8yzL5unfpW3M6fz/eB7Cb5MQAYSZ7GKo4Qth+N2sgQ= @@ -675,8 +624,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= @@ -692,10 +642,6 @@ gorm.io/gorm v1.9.19/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.0/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.23.5 h1:TnlF26wScKSvknUC/Rn8t0NLLM22fypYBlvj1+aH6dM= gorm.io/gorm v1.23.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= -gosrc.io/xmpp v0.5.1 h1:Rgrm5s2rt+npGggJH3HakQxQXR8ZZz3+QRzakRQqaq4= -gosrc.io/xmpp v0.5.1/go.mod h1:L3NFMqYOxyLz3JGmgFyWf7r9htE91zVGiK40oW4RwdY= -gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/gotestsum v0.3.5/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -728,10 +674,6 @@ modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= -mvdan.cc/sh v2.6.4+incompatible/go.mod h1:IeeQbZq+x2SUGBensq/jge5lLQbS3XT2ktyp3wrt4x8= -nhooyr.io/websocket v1.6.5/go.mod h1:F259lAzPRAH0htX2y3ehpJe09ih1aSHN7udWki1defY= -nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From 1c7f299b9864920ab1b2f54b5db2e8abb093e84d Mon Sep 17 00:00:00 2001 From: packagrio-bot Date: Thu, 12 Jan 2023 00:42:30 +0000 Subject: [PATCH 15/26] (v0.6.0) Automated packaging of release by Packagr --- webapp/backend/pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/backend/pkg/version/version.go b/webapp/backend/pkg/version/version.go index bacf8d5..ac3b3c2 100644 --- a/webapp/backend/pkg/version/version.go +++ b/webapp/backend/pkg/version/version.go @@ -2,4 +2,4 @@ package version // VERSION is the app-global version string, which will be replaced with a // new value during packaging -const VERSION = "0.5.0" +const VERSION = "0.6.0" From 22d2f9847c1653ae5ce9b3d5537cfda17b8f157a Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Wed, 11 Jan 2023 17:24:01 -0800 Subject: [PATCH 16/26] fixes #418 when using device type `sat,auto`, scrutiny config parser will treat `type: 'sat,auto'` as a list, which will cause it to be treated like a raid disk. force single command execution using `type: ['sat,auto']` --- collector/pkg/config/config_test.go | 19 +++++++++++++++++++ .../config/testdata/device_type_comma.yaml | 9 +++++++++ example.collector.yaml | 4 ++++ 3 files changed, 32 insertions(+) create mode 100644 collector/pkg/config/testdata/device_type_comma.yaml diff --git a/collector/pkg/config/config_test.go b/collector/pkg/config/config_test.go index d5af79d..f123131 100644 --- a/collector/pkg/config/config_test.go +++ b/collector/pkg/config/config_test.go @@ -36,6 +36,25 @@ func TestConfiguration_GetScanOverrides_Simple(t *testing.T) { require.Equal(t, []models.ScanOverride{{Device: "/dev/sda", DeviceType: []string{"sat"}, Ignore: false}}, scanOverrides) } +// fixes #418 +func TestConfiguration_GetScanOverrides_DeviceTypeComma(t *testing.T) { + t.Parallel() + + //setup + testConfig, _ := config.Create() + + //test + err := testConfig.ReadConfig(path.Join("testdata", "device_type_comma.yaml")) + require.NoError(t, err, "should correctly load simple device config") + scanOverrides := testConfig.GetDeviceOverrides() + + //assert + require.Equal(t, []models.ScanOverride{ + {Device: "/dev/sda", DeviceType: []string{"sat", "auto"}, Ignore: false}, + {Device: "/dev/sdb", DeviceType: []string{"sat,auto"}, Ignore: false}, + }, scanOverrides) +} + func TestConfiguration_GetScanOverrides_Ignore(t *testing.T) { t.Parallel() diff --git a/collector/pkg/config/testdata/device_type_comma.yaml b/collector/pkg/config/testdata/device_type_comma.yaml new file mode 100644 index 0000000..0009d50 --- /dev/null +++ b/collector/pkg/config/testdata/device_type_comma.yaml @@ -0,0 +1,9 @@ +version: 1 +devices: + # the scrutiny config parser will detect `sat,auto` as two separate items in a list. If you want to use `-d sat,auto` you must + # set 'sat,auto' in a list (see eg. /dev/sbd) + - device: /dev/sda + type: 'sat,auto' + - device: /dev/sdb + type: + - sat,auto diff --git a/example.collector.yaml b/example.collector.yaml index 393672b..d1fc9f1 100644 --- a/example.collector.yaml +++ b/example.collector.yaml @@ -31,6 +31,10 @@ devices: # - device: /dev/sda # type: 'sat' # +# # example for using `-d sat,auto`, notice the square brackets (workaround for #418) +# - device: /dev/sda +# type: ['sat,auto'] +# # # example to show how to ignore a specific disk/device. # - device: /dev/sda # ignore: true From ad4b117f6e2e41626c5e2b945ce965cd43f8a259 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Wed, 11 Jan 2023 17:41:09 -0800 Subject: [PATCH 17/26] fixes #412 Added ability to trigger collector at startup. Disabled by default, (enable by setting `-e COLLECTOR_RUN_STARTUP=true`) Added COLLECTOR_RUN_STARTUP_SLEEP env variable to specify seconds before calling scrutiny collector on first run, default sleep value = 1s. --- docker/entrypoint-collector.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docker/entrypoint-collector.sh b/docker/entrypoint-collector.sh index d51e5e3..7c78183 100755 --- a/docker/entrypoint-collector.sh +++ b/docker/entrypoint-collector.sh @@ -7,6 +7,8 @@ # adding ability to customize the cron schedule. COLLECTOR_CRON_SCHEDULE=${COLLECTOR_CRON_SCHEDULE:-"0 0 * * *"} +COLLECTOR_RUN_STARTUP=${COLLECTOR_RUN_STARTUP:-"false"} +COLLECTOR_RUN_STARTUP_SLEEP=${COLLECTOR_RUN_STARTUP_SLEEP:-"1"} # if the cron schedule has been overridden via env variable (eg docker-compose) we should make sure to strip quotes [[ "${COLLECTOR_CRON_SCHEDULE}" == \"*\" || "${COLLECTOR_CRON_SCHEDULE}" == \'*\' ]] && COLLECTOR_CRON_SCHEDULE="${COLLECTOR_CRON_SCHEDULE:1:-1}" @@ -14,6 +16,13 @@ COLLECTOR_CRON_SCHEDULE=${COLLECTOR_CRON_SCHEDULE:-"0 0 * * *"} # replace placeholder with correct value sed -i 's|{COLLECTOR_CRON_SCHEDULE}|'"${COLLECTOR_CRON_SCHEDULE}"'|g' /etc/cron.d/scrutiny +if [[ "${COLLECTOR_RUN_STARTUP}" == "true" ]]; then + sleep ${COLLECTOR_RUN_STARTUP_SLEEP} + echo "starting scrutiny collector (run-once mode. subsequent calls will be triggered via cron service)" + /opt/scrutiny/bin/scrutiny-collector-metrics run +fi + + # now that we have the env start cron in the foreground echo "starting cron" su -c "cron -f -L 15" root From d8c359bd8a7ac5f95ba2aebbdfa432026ff11432 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Wed, 11 Jan 2023 17:49:58 -0800 Subject: [PATCH 18/26] instructions documenting added ability to trigger collector at startup. Disabled by default, (enable by setting `-e COLLECTOR_RUN_STARTUP=true`) Added COLLECTOR_RUN_STARTUP_SLEEP env variable to specify seconds before calling scrutiny collector on first run, default sleep value = 1s. --- docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md b/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md index 793d3cb..3a9476a 100644 --- a/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md +++ b/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md @@ -305,3 +305,20 @@ Or if you're not using docker, you can pass CLI arguments to the collector durin ```bash scrutiny-collector-metrics run --debug --log-file /tmp/collector.log ``` + +## Collector trigger on startup + +When the `omnibus` docker image starts up, it will automatically trigger the collector, which will populate the Scrutiny +Webui with your disks. +This is not the case when running the collector docker image in **hub/spoke** mode, as the collector and webui are +running in different containers (and potentially different host machines), so +the web container may not be ready for incoming connections. By default the container will only run the collector at the +time specified in the cron schedule. + +You can force the collector to run on startup using the following env variables: + +- `-e COLLECTOR_RUN_STARTUP=true` - forces the collector to run on startup (cron will be started after the collector + completes) +- `-e COLLECTOR_RUN_STARTUP_SLEEP=10` - if `COLLECTOR_RUN_STARTUP` is enabled, you can use this env variable to + configure the delay before the collector is run (default: `1` second). Used to ensure the web container has started + successfully. From d49497da805327dec2a6dc33010676b260188e5a Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Wed, 11 Jan 2023 18:03:49 -0800 Subject: [PATCH 19/26] update hub/spoke guide - thanks @TinJoy59 fixes #417 --- docs/INSTALL_HUB_SPOKE.md | 182 +++++++++++++++++++++++++++++++++++++- 1 file changed, 181 insertions(+), 1 deletion(-) diff --git a/docs/INSTALL_HUB_SPOKE.md b/docs/INSTALL_HUB_SPOKE.md index 17d8f67..2849aa8 100644 --- a/docs/INSTALL_HUB_SPOKE.md +++ b/docs/INSTALL_HUB_SPOKE.md @@ -1 +1,181 @@ -> See [docker/example.hubspoke.docker-compose.yml](https://github.com/AnalogJ/scrutiny/blob/master/docker/example.hubspoke.docker-compose.yml) for a docker-compose file. +> +See [docker/example.hubspoke.docker-compose.yml](https://github.com/AnalogJ/scrutiny/blob/master/docker/example.hubspoke.docker-compose.yml) +for a docker-compose file. + +> The following guide was contributed by @TinJoy59 in #417 +> It describes how to deploy the Scrutiny in Hub/Spoke mode, where the Hub is running in Docker, and the Spokes ( +> collectors) are running as binaries. +> He's using Proxmox & Synology in his guide, however this should be applicable for almost anyone + +# S.M.A.R.T. Monitoring with Scrutiny across machines + +![drawing-3-1671744407](https://user-images.githubusercontent.com/86809766/209230023-bf1ef9f8-65c4-454e-9e1a-be1293cd737e.png) + +### ๐Ÿค” The problem: + +Scrutiny offers a nice Docker package called "Omnibus" that can monitor HDDs attached to a Docker host with relative +ease. Scrutiny can also be installed in a Hub-Spoke layout where Web interface, Database and Collector come in 3 +separate packages. The official documentation assumes that the spokes in the "Hub-Spokes layout" run Docker, which is +not always the case. The third approach is to install Scrutiny manually, entirely outside of Docker. + +### ๐Ÿ’ก The solution: + +This tutorial provides a hybrid configuration where the Hub lives in a Docker instance while the spokes have only +Scrutiny Collector installed manually. The Collector periodically send data to the Hub. It's not mind-boggling hard to +understand but someone might struggle with the setup. This is for them. + +### ๐Ÿ–ฅ๏ธ My setup: + +I have a Proxmox cluster where one VM runs Docker and all monitoring services - Grafana, Prometheus, various exporters, +InfluxDB and so forth. Another VM runs the NAS - OpenMediaVault v6, where all hard drives reside. The Scrutiny Collector +is triggered every 30min to collect data on the drives. The data is sent to the Docker VM, running InfluxDB. + +## Setting up the Hub + +![drawing-3-1671744714](https://user-images.githubusercontent.com/86809766/209230113-c954d834-521b-4555-bcd2-eb6b80f343be.png) + +The Hub consists of Scrutiny Web - a web interface for viewing the SMART data. And InfluxDB, where the smartmon data is +stored. + +[๐Ÿ”—This is the official Hub-Spoke layout in docker-compose.](https://github.com/AnalogJ/scrutiny/blob/master/docker/example.hubspoke.docker-compose.yml) +We are going to reuse parts of it. The ENV variables provide the necessary configuration for the initial setup, both for +InfluxDB and Scrutiny. + +If you are working with and existing InfluxDB instance, you can forgo all the `INIT` variables as they already exist. + +The official Scrutiny documentation has a +sample [scrutiny.yaml ](https://github.com/AnalogJ/scrutiny/blob/master/example.scrutiny.yaml)file that normally +contains the connection and notification details but I always find it easier to configure as much as possible in the +docker-compose. + +```yaml +version: "3.4" + +networks: + monitoring: # A common network for all monitoring services to communicate into + external: true + notifications: # To Gotify or another Notification service + external: true + +services: + influxdb: + container_name: influxdb + image: influxdb:2.1-alpine + ports: + - 8086:8086 + volumes: + - ${DIR_CONFIG}/influxdb2/db:/var/lib/influxdb2 + - ${DIR_CONFIG}/influxdb2/config:/etc/influxdb2 + environment: + - DOCKER_INFLUXDB_INIT_MODE=setup + - DOCKER_INFLUXDB_INIT_USERNAME=Admin + - DOCKER_INFLUXDB_INIT_PASSWORD=${PASSWORD} + - DOCKER_INFLUXDB_INIT_ORG=homelab + - DOCKER_INFLUXDB_INIT_BUCKET=scrutiny + - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=your-very-secret-token + restart: unless-stopped + networks: + - monitoring + + scrutiny: + container_name: scrutiny + image: ghcr.io/analogj/scrutiny:master-web + ports: + - 8080:8080 + volumes: + - ${DIR_CONFIG}/scrutiny/config:/opt/scrutiny/config + environment: + - SCRUTINY_WEB_INFLUXDB_HOST=influxdb + - SCRUTINY_WEB_INFLUXDB_PORT=8086 + - SCRUTINY_WEB_INFLUXDB_TOKEN=your-very-secret-token + - SCRUTINY_WEB_INFLUXDB_ORG=homelab + - SCRUTINY_WEB_INFLUXDB_BUCKET=scrutiny + # Optional but highly recommended to notify you in case of a problem + - SCRUTINY_WEB_NOTIFY_URLS=["http://gotify:80/message?token=a-gotify-token"] + depends_on: + - influxdb + restart: unless-stopped + networks: + - notifications + - monitoring +``` + +A freshly initialized Scrutiny instance can be accessed on port 8080, eg. `192.168.0.100:8080`. The interface will be +empty because no metrics have been collected yet. + +## Setting up a Spoke ***without*** Docker + +![drawing-3-1671744208](https://user-images.githubusercontent.com/86809766/209230155-386a8644-b506-497f-8245-0d24e15c9063.png) + +A spoke consists of the Scrutiny Collector binary that is run on a set interval via crontab and sends the data to the +Hub. The official +documentation [describes the manual setup of the Collector](https://github.com/AnalogJ/scrutiny/blob/master/docs/INSTALL_MANUAL.md#collector) +- dependencies and step by step commands. I have a shortened version that does the same thing but in one line of code. + +```bash +# Installing dependencies +apt install smartmontools -y + +# 1. Create directory for the binary +# 2. Download the binary into that directory +# 3. Make it exacutable +# 4. List the contents of the library for confirmation +mkdir -p /opt/scrutiny/bin && \ +curl -L https://github.com/AnalogJ/scrutiny/releases/download/v0.5.0/scrutiny-collector-metrics-linux-amd64 > /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 && \ +chmod +x /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 && \ +ls -lha /opt/scrutiny/bin +``` + +

When downloading Github Release Assests, make sure that you have the correct version. The provided example is with Release v0.5.0. [The release list can be found here.](https://github.com/analogj/scrutiny/releases)

+ +Once the Collector is installed, you can run it with the following command. Make sure to add the correct address and +port of your Hub as `--api-endpoint`. + +```bash +/opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 run --api-endpoint "http://192.168.0.100:8080" +``` + +This will run the Collector once and populate the Web interface of your Scrutiny instance. In order to collect metrics +for a time series, you need to run the command repeatedly. Here is an example for crontab, running the Collector every +15min. + +```bash +# open crontab +crontab -e + +# add a line for Scrutiny +*/15 * * * * /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 run --api-endpoint "http://192.168.0.100:8080" +``` + +The Collector has its own independent config file that lives in `/opt/scrutiny/config/collector.yaml` but I did not find +a need to modify +it. [A default collector.yaml can be found in the official documentation.](https://github.com/AnalogJ/scrutiny/blob/master/example.collector.yaml) + +## Setting up a Spoke ***with*** Docker + +![drawing-3-1671744277](https://user-images.githubusercontent.com/86809766/209230176-87c9e55a-4e3e-4f5f-9609-335d41529f3d.png) + +Setting up a remote Spoke in Docker requires you to split +the [official Hub-Spoke layout docker-compose.yml](https://github.com/AnalogJ/scrutiny/blob/master/docker/example.hubspoke.docker-compose.yml) +. In the following docker-compose you need to provide the `${API_ENDPOINT}`, in my case `http://192.168.0.100:8080`. +Also all drives that you wish to monitor need to be presented to the container under `devices`. + +The image handles the periodic scanning of the drives. + +```yaml +version: "3.4" + +services: + + collector: + image: 'ghcr.io/analogj/scrutiny:master-collector' + cap_add: + - SYS_RAWIO + volumes: + - '/run/udev:/run/udev:ro' + environment: + COLLECTOR_API_ENDPOINT: ${API_ENDPOINT} + devices: + - "/dev/sda" + - "/dev/sdb" +``` From 7f1023fa9ba3c04c453b025284b526562b41cf9c Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Wed, 11 Jan 2023 21:30:16 -0800 Subject: [PATCH 20/26] temporary fix for #426 using legacy open ssl provider for fixing `"error:0308010C:digital envelope routines::unsupported"` error. See https://stackoverflow.com/questions/69692842/error-message-error0308010cdigital-envelope-routinesunsupported We need to upgrade Angular version. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index edc14da..01d1a5b 100644 --- a/Makefile +++ b/Makefile @@ -98,6 +98,7 @@ endif # reduce logging, disable angular-cli analytics for ci environment binary-frontend: export NPM_CONFIG_LOGLEVEL = warn binary-frontend: export NG_CLI_ANALYTICS = false +binary-frontend: export NODE_OPTIONS = --openssl-legacy-provider binary-frontend: cd webapp/frontend npm install -g @angular/cli@9.1.4 From 4fcd11f497ae314f04411b70114caf8a73ba4125 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Wed, 11 Jan 2023 21:31:25 -0800 Subject: [PATCH 21/26] update coverage makefile with workaround. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 01d1a5b..1b3f765 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,7 @@ binary-frontend: .PHONY: binary-frontend-test-coverage # reduce logging, disable angular-cli analytics for ci environment +binary-frontend-test-coverage: export NODE_OPTIONS = --openssl-legacy-provider binary-frontend-test-coverage: cd webapp/frontend npm ci From 97f73703b19fb5d3264b17cf3c533c0a67a8c226 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Thu, 19 Jan 2023 22:21:48 -0800 Subject: [PATCH 22/26] update docs with instructions for customizing Influxdb creds. --- docs/TROUBLESHOOTING_INFLUXDB.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/TROUBLESHOOTING_INFLUXDB.md b/docs/TROUBLESHOOTING_INFLUXDB.md index faa9d4d..489d4e5 100644 --- a/docs/TROUBLESHOOTING_INFLUXDB.md +++ b/docs/TROUBLESHOOTING_INFLUXDB.md @@ -394,3 +394,32 @@ After running the Curl command above, you'll see a JSON response that looks like You must copy the token field from the JSON response, and save it in your `scrutiny.yaml` config file. After that's done, you can start the Scrutiny server +## Customize InfluxDB Admin Username & Password + +The full set of InfluxDB configuration options are available +in [code](https://github.com/AnalogJ/scrutiny/blob/master/webapp/backend/pkg/config/config.go?rgh-link-date=2023-01-19T16%3A23%3A40Z#L49-L51) +. + +During first startup Scrutiny will connect to the unprotected InfluxDB server, start the setup process (via API) using a +username and password of `admin`:`password12345` and then create an API token of `scrutiny-default-admin-token`. + +After that's complete, it will use the api token for all subsequent communication with InfluxDB. + +You can configure the values for the Admin username, password and token using the config file, or env variables: + +#### Config File Example + +```yaml +web: + influxdb: + token: 'my-custom-token' + init_username: 'my-custom-username' + init_password: 'my-custom-password' +``` + +#### Environmental Variables Example + +`SCRUTINY_WEB_INFLUXDB_TOKEN` , `SCRUTINY_WEB_INFLUXDB_INIT_USERNAME` and `SCRUTINY_WEB_INFLUXDB_INIT_PASSWORD` + +It's safe to change the InfluxDB Admin username/password after setup has completed, only the API token is used for +subsequent communication with InfluxDB. From 19a0b8c2acec819a23521906f421189c20d467b3 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Sat, 4 Feb 2023 08:41:47 -0800 Subject: [PATCH 23/26] Update TROUBLESHOOTING_INFLUXDB.md change volume mounts when upgrading from LSIO image --- docs/TROUBLESHOOTING_INFLUXDB.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/TROUBLESHOOTING_INFLUXDB.md b/docs/TROUBLESHOOTING_INFLUXDB.md index 489d4e5..c89cae9 100644 --- a/docs/TROUBLESHOOTING_INFLUXDB.md +++ b/docs/TROUBLESHOOTING_INFLUXDB.md @@ -82,6 +82,7 @@ this usually related to either: variables - remove the `SCRUTINY_WEB=true` and `SCRUTINY_COLLECTOR=true` environmental variables. They were used by the LSIO image, but are unnecessary and cause issues with the official Scrutiny image. + - Change your volume mappings to `/opt/scrutiny` from `/scrutiny` - Updated versions of the [LSIO Scrutiny images are broken](https://github.com/linuxserver/docker-scrutiny/issues/22), as they have not installed InfluxDB which is a required dependency of Scrutiny v0.4.x - You can revert to an earlier version of the LSIO image (`lscr.io/linuxserver/scrutiny:060ac7b8-ls34`), or just From e07a53046fbf05c0f749835be2fc0ed3f44462b4 Mon Sep 17 00:00:00 2001 From: Saswat Padhi Date: Mon, 6 Feb 2023 22:20:00 +0000 Subject: [PATCH 24/26] [FEAT] Allow insecure certificates on InfluxDB This change allows users to skip TLS certificate verification on their InfluxDB server, if they wish to do so, for instance when using self- signed certificates. Without this change, scrutiny failed to start and paniced with a `x509: certificate signed by unknown authority` error. --- webapp/backend/pkg/config/config.go | 1 + .../pkg/database/scrutiny_repository.go | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/webapp/backend/pkg/config/config.go b/webapp/backend/pkg/config/config.go index 3961373..605de86 100644 --- a/webapp/backend/pkg/config/config.go +++ b/webapp/backend/pkg/config/config.go @@ -49,6 +49,7 @@ func (c *configuration) Init() error { c.SetDefault("web.influxdb.init_username", "admin") c.SetDefault("web.influxdb.init_password", "password12345") c.SetDefault("web.influxdb.token", "scrutiny-default-admin-token") + c.SetDefault("web.influxdb.tls.insecure_skip_verify", false) c.SetDefault("web.influxdb.retention_policy", true) //c.SetDefault("disks.include", []string{}) diff --git a/webapp/backend/pkg/database/scrutiny_repository.go b/webapp/backend/pkg/database/scrutiny_repository.go index b163c2c..da95914 100644 --- a/webapp/backend/pkg/database/scrutiny_repository.go +++ b/webapp/backend/pkg/database/scrutiny_repository.go @@ -2,6 +2,7 @@ package database import ( "context" + "crypto/tls" "encoding/json" "fmt" "github.com/analogj/scrutiny/webapp/backend/pkg/config" @@ -95,11 +96,20 @@ func NewScrutinyRepository(appConfig config.Interface, globalLogger logrus.Field influxdbUrl := fmt.Sprintf("%s://%s:%s", appConfig.GetString("web.influxdb.scheme"), appConfig.GetString("web.influxdb.host"), appConfig.GetString("web.influxdb.port")) globalLogger.Debugf("InfluxDB url: %s", influxdbUrl) - client := influxdb2.NewClient(influxdbUrl, appConfig.GetString("web.influxdb.token")) + tlsConfig := &tls.Config{ + InsecureSkipVerify: appConfig.GetBool("web.influxdb.tls.insecure_skip_verify"), + } + globalLogger.Infof("InfluxDB certificate verification: %t\n", !tlsConfig.InsecureSkipVerify) + + client := influxdb2.NewClientWithOptions( + influxdbUrl, + appConfig.GetString("web.influxdb.token"), + influxdb2.DefaultOptions().SetTLSConfig(tlsConfig), + ) //if !appConfig.IsSet("web.influxdb.token") { globalLogger.Debugf("Determine Influxdb setup status...") - influxSetupComplete, err := InfluxSetupComplete(influxdbUrl) + influxSetupComplete, err := InfluxSetupComplete(influxdbUrl, tlsConfig) if err != nil { return nil, fmt.Errorf("failed to check influxdb setup status - %w", err) } @@ -218,7 +228,7 @@ func (sr *scrutinyRepository) HealthCheck(ctx context.Context) error { } -func InfluxSetupComplete(influxEndpoint string) (bool, error) { +func InfluxSetupComplete(influxEndpoint string, tlsConfig *tls.Config) (bool, error) { influxUri, err := url.Parse(influxEndpoint) if err != nil { return false, err @@ -228,7 +238,8 @@ func InfluxSetupComplete(influxEndpoint string) (bool, error) { return false, err } - res, err := http.Get(influxUri.String()) + client := &http.Client{Transport: &http.Transport{TLSClientConfig: tlsConfig}} + res, err := client.Get(influxUri.String()) if err != nil { return false, err } From c69770d1dd1ccdd8f4489607623f8f80ae4b1612 Mon Sep 17 00:00:00 2001 From: Saswat Padhi Date: Mon, 6 Feb 2023 22:34:06 +0000 Subject: [PATCH 25/26] Add `insecure_skip_verify` in example.scrutiny.yaml --- example.scrutiny.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/example.scrutiny.yaml b/example.scrutiny.yaml index c93725e..9d8c80a 100644 --- a/example.scrutiny.yaml +++ b/example.scrutiny.yaml @@ -47,6 +47,11 @@ web: # org: 'my-org' # bucket: 'bucket' retention_policy: true + # if you wish to disable TLS certificate verification, + # when using self-signed certificates for example, + # then uncomment the lines below and set `insecure_skip_verify: true` + # tls: + # insecure_skip_verify: false log: file: '' #absolute or relative paths allowed, eg. web.log From cb5226f6e401e1e7bc3dcb0de098782852a86993 Mon Sep 17 00:00:00 2001 From: Saswat Padhi Date: Tue, 7 Feb 2023 08:24:39 +0000 Subject: [PATCH 26/26] Update backend tests failing on insecure_skip_verify --- webapp/backend/pkg/web/server_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/webapp/backend/pkg/web/server_test.go b/webapp/backend/pkg/web/server_test.go index 227d3a2..ac775a0 100644 --- a/webapp/backend/pkg/web/server_test.go +++ b/webapp/backend/pkg/web/server_test.go @@ -103,6 +103,7 @@ func (suite *ServerTestSuite) TestHealthRoute() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. @@ -145,6 +146,7 @@ func (suite *ServerTestSuite) TestRegisterDevicesRoute() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. @@ -187,6 +189,7 @@ func (suite *ServerTestSuite) TestUploadDeviceMetricsRoute() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. @@ -244,6 +247,7 @@ func (suite *ServerTestSuite) TestPopulateMultiple() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. @@ -342,6 +346,7 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_WebhookFailure() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"https://unroutable.domain.example.asdfghj"}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail)) @@ -387,6 +392,7 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_ScriptFailure() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///missing/path/on/disk"}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail)) @@ -432,6 +438,7 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_ScriptSuccess() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///usr/bin/env"}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail)) @@ -477,6 +484,7 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_ShoutrrrFailure() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"discord://invalidtoken@channel"}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail)) @@ -521,6 +529,7 @@ func (suite *ServerTestSuite) TestGetDevicesSummaryRoute_Nvme() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail))