diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index cdf00ff4..2f8f56d2 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -250,7 +250,7 @@ jobs: - name: Go Tests run: | go get gotest.tools/gotestsum - gotestsum --no-summary=skipped --format dots -- -covermode=count -coverprofile=coverage.out -p=1 ./... + gotestsum --no-summary=skipped --format testname -- -covermode=count -coverprofile=coverage.out -p=1 ./... env: VERSION: ${{ env.VERSION }} COMMIT: ${{ github.sha }} @@ -482,24 +482,24 @@ jobs: - name: Docker Build :dev run: make buildx-dev - sentry-release: - needs: [test, test-postman-sqlite, test-postman-postgres, test-postman-mysql] - runs-on: ubuntu-latest - steps: - - name: Checkout Statping Repo - uses: actions/checkout@v2 - - - name: Setup Sentry CLI - uses: mathrix-education/setup-sentry-cli@master - with: - version: latest - url: ${{ secrets.SENTRY_URL }} - token: ${{ secrets.SENTRY_AUTH_TOKEN }} - organization: statping - - - name: Setting ENV's - run: echo ::set-env name=VERSION::$(cat version.txt) - shell: bash - - - name: Sentry Release - run: make sentry-release +# sentry-release: +# needs: [test, test-postman-sqlite, test-postman-postgres, test-postman-mysql] +# runs-on: ubuntu-latest +# steps: +# - name: Checkout Statping Repo +# uses: actions/checkout@v2 +# +# - name: Setup Sentry CLI +# uses: mathrix-education/setup-sentry-cli@master +# with: +# version: latest +# url: ${{ secrets.SENTRY_URL }} +# token: ${{ secrets.SENTRY_AUTH_TOKEN }} +# organization: statping +# +# - name: Setting ENV's +# run: echo ::set-env name=VERSION::$(cat version.txt) +# shell: bash +# +# - name: Sentry Release +# run: make sentry-release diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 002ba915..b16c68a2 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -250,7 +250,7 @@ jobs: - name: Go Tests run: | go get gotest.tools/gotestsum - gotestsum --no-summary=skipped --format dots -- -covermode=count -coverprofile=coverage.out -p=1 ./... + gotestsum --no-summary=skipped --format testname -- -covermode=count -coverprofile=coverage.out -p=1 ./... env: VERSION: ${{ env.VERSION }} COMMIT: ${{ github.sha }} @@ -482,27 +482,27 @@ jobs: - name: Docker Build :lastest run: make buildx-latest - sentry-release: - needs: docker-release - runs-on: ubuntu-latest - steps: - - name: Checkout Statping Repo - uses: actions/checkout@v2 - - - name: Setup Sentry CLI - uses: mathrix-education/setup-sentry-cli@master - with: - version: latest - url: ${{ secrets.SENTRY_URL }} - token: ${{ secrets.SENTRY_AUTH_TOKEN }} - organization: statping - - - name: Setting ENV's - run: echo ::set-env name=VERSION::$(cat version.txt) - shell: bash - - - name: Sentry Release - run: make sentry-release +# sentry-release: +# needs: docker-release +# runs-on: ubuntu-latest +# steps: +# - name: Checkout Statping Repo +# uses: actions/checkout@v2 +# +# - name: Setup Sentry CLI +# uses: mathrix-education/setup-sentry-cli@master +# with: +# version: latest +# url: ${{ secrets.SENTRY_URL }} +# token: ${{ secrets.SENTRY_AUTH_TOKEN }} +# organization: statping +# +# - name: Setting ENV's +# run: echo ::set-env name=VERSION::$(cat version.txt) +# shell: bash +# +# - name: Sentry Release +# run: make sentry-release homebrew-release: needs: docker-release diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 239851c8..a4d46946 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -117,7 +117,7 @@ jobs: - name: Go Tests run: | - SASS=`which sass` gotestsum --no-summary=skipped --format dots -- -covermode=count -coverprofile=coverage.out -p=1 ./... + SASS=`which sass` gotestsum --no-summary=skipped --format testname -- -covermode=count -coverprofile=coverage.out -p=1 ./... env: VERSION: ${{ env.VERSION }} COMMIT: ${{ github.sha }} diff --git a/CHANGELOG.md b/CHANGELOG.md index e6d693af..8ffefde4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 0.90.70 (10-1-2020) +- Merged PR #806 - Enhance GRPC Monitoring +- Merged PR #692 - When login fields are autofilled the sign in button should be enabled +- Modified multiple Vue forms to use number models for integer inputs +- Fixed page freeze issue for incidents https://github.com/statping/statping/issues/842 +- Modified cache routine from 5 seconds to 60 seconds + # 0.90.69 (09-18-2020) - Fixed issue with service view not loading. #808 #811 #800 diff --git a/Dockerfile b/Dockerfile index 44866305..0d00d822 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,10 @@ ENV IS_DOCKER=true ENV SASS=/usr/local/bin/sassc ENV STATPING_DIR=/app ENV PORT=8080 +ENV UID=1000 +ENV GID=1000 + +USER $UID:$GID EXPOSE $PORT diff --git a/frontend/src/forms/Checkin.vue b/frontend/src/forms/Checkin.vue index 52271995..223a86be 100644 --- a/frontend/src/forms/Checkin.vue +++ b/frontend/src/forms/Checkin.vue @@ -8,7 +8,7 @@ Send a GET request to this URL every {{checkin.interval}} seconds - + @@ -22,7 +22,7 @@
- +
diff --git a/frontend/src/forms/IncidentUpdates.vue b/frontend/src/forms/IncidentUpdates.vue index 4fa6f637..6ff6a997 100644 --- a/frontend/src/forms/IncidentUpdates.vue +++ b/frontend/src/forms/IncidentUpdates.vue @@ -5,7 +5,7 @@ No updates found, create a new Incident Update below.
-
+
@@ -49,7 +49,7 @@ }, data () { return { - updates: null, + updates: [], incident_update: { incident: this.incident.id, message: "", diff --git a/frontend/src/forms/Login.vue b/frontend/src/forms/Login.vue index b84c2d68..928b953b 100644 --- a/frontend/src/forms/Login.vue +++ b/frontend/src/forms/Login.vue @@ -4,13 +4,13 @@
- +
- +
diff --git a/frontend/src/forms/Message.vue b/frontend/src/forms/Message.vue index c56df1b8..504ce011 100644 --- a/frontend/src/forms/Message.vue +++ b/frontend/src/forms/Message.vue @@ -27,7 +27,7 @@
- @@ -44,16 +44,6 @@
-
- -
- -
-
-
diff --git a/frontend/src/forms/Notifier.vue b/frontend/src/forms/Notifier.vue index 73866ac3..ebbf0ff3 100644 --- a/frontend/src/forms/Notifier.vue +++ b/frontend/src/forms/Notifier.vue @@ -61,7 +61,7 @@
Limit {{notifier.limits}} per hour - + Notifier '{{notifier.title}}' will send a maximum of {{notifier.limits}} notifications per hour.
@@ -146,8 +146,7 @@ {{notifier.logs.length}}
- -
+
Service {{log.service}} {{log.success ? "Success Triggered" : "Failure Triggered"}} @@ -188,49 +187,47 @@ import '../codemirror_json' const beautify = require('js-beautify').js export default { - name: 'Notifier', + name: 'Notifier', components: { codemirror }, - props: { - notifier: { - type: Object, - required: true - } - }, - watch: { - + props: { + notifier: { + type: Object, + required: true + } + }, + watch: {}, + data() { + return { + loading: false, + loadingTest: false, + error: null, + response: null, + request: null, + success: false, + saved: false, + expanded: false, + expanded_logs: false, + success_data: null, + failure_data: null, + form: {}, + cmOptions: { + height: 700, + tabSize: 2, + lineNumbers: true, + line: true, + class: "json-field", + theme: 'neat', + mode: "mymode", + lineWrapping: true, + json: this.notifier.data_type === "json", + autoRefresh: true, + mime: this.notifier.data_type === "json" ? "application/json" : "text/plain" + }, + beautifySettings: {indent_size: 2, space_in_empty_paren: true}, + } }, - data() { - return { - loading: false, - loadingTest: false, - error: null, - response: null, - request: null, - success: false, - saved: false, - expanded: false, - expanded_logs: false, - success_data: null, - failure_data: null, - form: {}, - cmOptions: { - height: 700, - tabSize: 2, - lineNumbers: true, - line: true, - class: "json-field", - theme: 'neat', - mode: "mymode", - lineWrapping: true, - json: this.notifier.data_type === "json", - autoRefresh: true, - mime: this.notifier.data_type === "json" ? "application/json" : "text/plain" - }, - beautifySettings: { indent_size: 2, space_in_empty_paren: true }, - } - }, computed: { core() { return this.$store.getters.core @@ -240,92 +237,92 @@ export default { return "https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=" + encodeURIComponent(u) } }, - methods: { - formVisible(want, form) { - return !!want.includes(form.type); - }, - visible(isVisible, entry) { - if (isVisible) { - this.$refs.cmfailure.codemirror.refresh() - this.$refs.cmsuccess.codemirror.refresh() - } - }, - onCmSuccessReady(cm) { - this.success_data = this.notifier.success_data - if (this.notifier.data_type === "json") { - this.success_data = beautify(this.notifier.success_data, this.beautifySettings) - } - setTimeout(function() { - cm.refresh(); - },1); - }, - onCmFailureReady(cm) { - this.failure_data = this.notifier.failure_data - if (this.notifier.data_type === "json") { - this.failure_data = beautify(this.notifier.failure_data, this.beautifySettings) - } - setTimeout(function() { - cm.refresh(); - },1); - }, - async enableToggle() { - this.notifier.enabled = !!this.notifier.enabled - const form = { - enabled: !this.notifier.enabled, - method: this.notifier.method, - } - await Api.notifier_save(form) - }, - async saveNotifier() { - this.loading = true - this.form.enabled = this.notifier.enabled - this.form.limits = parseInt(this.notifier.limits) - this.form.method = this.notifier.method - if (this.notifier.form) { - this.notifier.form.forEach((f) => { - let field = f.field.toLowerCase() - let val = this.notifier[field] - if (this.isNumeric(val)) { - val = parseInt(val) - } - this.form[field] = val - }); - } - this.form.success_data = this.success_data - this.form.failure_data = this.failure_data - await Api.notifier_save(this.form) - const notifiers = await Api.notifiers() - await this.$store.commit('setNotifiers', notifiers) - this.saved = true - this.loading = false - }, - async testNotifier(method="success") { - this.success = false - this.loadingTest = true - this.form.method = this.notifier.method - if (this.notifier.form) { - this.notifier.form.forEach((f) => { - let field = f.field.toLowerCase() - let val = this.notifier[field] - if (this.isNumeric(val)) { - val = parseInt(val) - } - this.form[field] = val - }); + methods: { + formVisible(want, form) { + return !!want.includes(form.type); + }, + visible(isVisible, entry) { + if (isVisible) { + this.$refs.cmfailure.codemirror.refresh() + this.$refs.cmsuccess.codemirror.refresh() + } + }, + onCmSuccessReady(cm) { + this.success_data = this.notifier.success_data + if (this.notifier.data_type === "json") { + this.success_data = beautify(this.notifier.success_data, this.beautifySettings) + } + setTimeout(function () { + cm.refresh(); + }, 1); + }, + onCmFailureReady(cm) { + this.failure_data = this.notifier.failure_data + if (this.notifier.data_type === "json") { + this.failure_data = beautify(this.notifier.failure_data, this.beautifySettings) + } + setTimeout(function () { + cm.refresh(); + }, 1); + }, + async enableToggle() { + this.notifier.enabled = !!this.notifier.enabled + const form = { + enabled: !this.notifier.enabled, + method: this.notifier.method, + } + await Api.notifier_save(form) + }, + async saveNotifier() { + this.loading = true + this.form.enabled = this.notifier.enabled + this.form.limits = parseInt(this.notifier.limits) + this.form.method = this.notifier.method + if (this.notifier.form) { + this.notifier.form.forEach((f) => { + let field = f.field.toLowerCase() + let val = this.notifier[field] + if (this.isNumeric(val)) { + val = parseInt(val) } - let req = { - notifier: this.form, - method: method, - } - const tested = await Api.notifier_test(req, this.notifier.method) - if (tested.success) { - this.success = true - } else { - this.error = tested.error - } - this.response = tested.response - this.loadingTest = false - }, - } + this.form[field] = val + }); + } + this.form.success_data = this.success_data + this.form.failure_data = this.failure_data + await Api.notifier_save(this.form) + const notifiers = await Api.notifiers() + await this.$store.commit('setNotifiers', notifiers) + this.saved = true + this.loading = false + }, + async testNotifier(method = "success") { + this.success = false + this.loadingTest = true + this.form.method = this.notifier.method + if (this.notifier.form) { + this.notifier.form.forEach((f) => { + let field = f.field.toLowerCase() + let val = this.notifier[field] + if (this.isNumeric(val)) { + val = parseInt(val) + } + this.form[field] = val + }); + } + let req = { + notifier: this.form, + method: method, + } + const tested = await Api.notifier_test(req, this.notifier.method) + if (tested.success) { + this.success = true + } else { + this.error = tested.error + } + this.response = tested.response + this.loadingTest = false + }, + } } diff --git a/frontend/src/forms/Service.vue b/frontend/src/forms/Service.vue index a7e5cd1f..32bb78a4 100644 --- a/frontend/src/forms/Service.vue +++ b/frontend/src/forms/Service.vue @@ -13,7 +13,7 @@
- @@ -27,7 +27,7 @@
- @@ -57,11 +57,11 @@
{{secondsHumanize(service.check_interval)}} - + Interval to check your service state
- +
@@ -85,7 +85,7 @@
- +
@@ -107,12 +107,12 @@
{{secondsHumanize(service.timeout)}} - + If the endpoint does not respond within this time it will be considered to be offline
- +
@@ -155,8 +155,7 @@
- -
+
@@ -167,6 +166,33 @@
+
+ +
+ + + + + +
+
+ +
+ +
+ + Check GPRC health check response codes for more information. +
+
+ +
+ +
+ + A status code of 1 is success, or view all the GRPC Status Codes +
+
+
@@ -276,6 +302,7 @@ permalink: "", order: 1, verify_ssl: true, + grpc_health_check: false, redirect: true, allow_notifications: true, notify_all_changes: true, @@ -316,6 +343,21 @@ this.service = this.in_service } this.use_tls = this.service.tls_cert !== "" + }, + updateDefaultValues() { + if (this.service.type === "grpc") { + this.service.expected_status = 1 + this.service.expected = "status:SERVING" + this.service.port = 50051 + this.service.verify_ssl = false + this.service.method = "" + } else { + this.service.expected_status = 200 + this.service.expected = "" + this.service.port = 80 + this.service.verify_ssl = true + this.service.method = "GET" + } }, updatePermalink() { const a = 'àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;' diff --git a/frontend/src/forms/Setup.vue b/frontend/src/forms/Setup.vue index d97720a3..f1f2ceb9 100644 --- a/frontend/src/forms/Setup.vue +++ b/frontend/src/forms/Setup.vue @@ -40,7 +40,7 @@
- +
diff --git a/frontend/src/languages/data.csv b/frontend/src/languages/data.csv index cc8aa51b..2be8c851 100644 --- a/frontend/src/languages/data.csv +++ b/frontend/src/languages/data.csv @@ -1,139 +1,139 @@ -key,en -settings,Settings -dashboard,Dashboard -services,Services -service,Service -failures,Failures -users,Users -login,Login -logout,Logout -online,Online -offline,Offline -configs,Configuration -username,Username -password,Password -email,Email -confirm_password,Confirm Password -uptime,Uptime -name,Name -copy,Copy -close,Close -secret,Secret -regen_api,Regenerate API Keys -regen_desc,API Secret is used for read create update and delete routes. You can Regenerate API Keys if you need to. -visibility,Visibility -group,Group -group_create,Create Group -group_update,Update Group -group_public_desc,Show group services to the public -groups,Groups -no_group,No Group -public,Public -private,Private -announcements,Announcements -notifiers,Notifiers -logs,Logs -help,Help -type,Type -edit,Edit -update,Update -create,Create -view,View -save,Save -title,Title -status,Status -begins,Begins -total_services,Total Services -online_services,Online Services -request_timeout,Request Timeout -service_never_online,Service has never been online -service_online_check,Online checked -service_offline_time,Service has been offline for -days_ago,Days Ago -today,Today -week,Week -month,Month -day,Day -hour,Hour -minute,Minute -failures_24_hours,Failures last 24 hours -no_services,You currently don't have any services! -theme,Theme -cache,Cache -authentication,Authentication -import,Import -main_settings,Main Settings -variables,Variables -docs,Documentation -links,Links -changelog,Change Log -repo,Repository -language,Language -db_connection,Database Connection -db_host,Database Host -db_port,Database Port -db_username,Database Username -db_password,Database Password -db_database,Database Name -send_reports,Send Error Reports -send_reports_desc,Send errors to Statping for debugging -project_name,Status Page Name -description,Description -domain,Domain -enable_cdn,Enable CDN -newsletter,Newsletter -newsletter_note,We will only send you an email for major changes -loading,Loading -save_settings,Save Settings -average_response,Average Response -last_uptime,Uptime last -sign_in,Sign In -last_login,Last Login -admin,Admin -user,User -failed,Failed -wrong_login,Incorrect username or password -theme_editor,Theme Editor -enable_assets,Enable Local Assets -assets_desc,Customize your status page design by enabling local assets. This will create a 'assets' directory containing all CSS. -assets_btn,Enable Local Assets -assets_loading,Creating Assets -assets_dir,Assets Directory -footer,Footer -footer_notes,You can use HTML tags in footer -global_announcement,Global Announcement -announcement_date,Announcement Date Range -notify_users,Notify Users -notify_desc,Notify Users Before Scheduled Time -notify_method,Notification Method -notify_before,Notify Before -message_create,Create Announcement -message_edit,Edit Announcement -minutes,Minutes -hours,Hours -days,Days -user_create,Create User -user_update,Update User -administrator,Administrator -checkins,Checkins -incidents,Incidents -service_info,Service Info -service_name,Service Name -service_type,Service Type -permalink,Permalink URL -service_public,Public Service -check_interval,Check Interval -service_endpoint,Service Endpoint -service_check,Service Check Type -service_timeout,Request Timeout -expected_resp,Expected Response -expected_code,Expected Status Code -follow_redir,Follow Redirects -verify_ssl,Verify SSL -tls_cert,Use TLS Cert -notification_opts,Notification Options -notifications_enable,Enable Notifications -notify_after,Notify After Failures -notify_all,Notify All Changes -service_update,Update Service -service_create,Create Service +key,en,es,fr,ru,de,ja,it,ko,zh +settings,Settings,,,,,,,, +dashboard,Dashboard,,,,,,,, +services,Services,,,,,,,, +service,Service,,,,,,,, +failures,Failures,,,,,,,, +users,Users,,,,,,,, +login,Login,,,,,,,, +logout,Logout,,,,,,,, +online,Online,,,,,,,, +offline,Offline,,,,,,,, +configs,Configuration,,,,,,,, +username,Username,,,,,,,, +password,Password,,,,,,,, +email,Email,,,,,,,, +confirm_password,Confirm Password,,,,,,,, +uptime,Uptime,,,,,,,, +name,Name,,,,,,,, +copy,Copy,,,,,,,, +close,Close,,,,,,,, +secret,Secret,,,,,,,, +regen_api,Regenerate API Keys,,,,,,,, +regen_desc,API Secret is used for read create update and delete routes. You can Regenerate API Keys if you need to.,,,,,,,, +visibility,Visibility,,,,,,,, +group,Group,,,,,,,, +group_create,Create Group,,,,,,,, +group_update,Update Group,,,,,,,, +group_public_desc,Show group services to the public,,,,,,,, +groups,Groups,,,,,,,, +no_group,No Group,,,,,,,, +public,Public,,,,,,,, +private,Private,,,,,,,, +announcements,Announcements,,,,,,,, +notifiers,Notifiers,,,,,,,, +logs,Logs,,,,,,,, +help,Help,,,,,,,, +type,Type,,,,,,,, +edit,Edit,,,,,,,, +update,Update,,,,,,,, +create,Create,,,,,,,, +view,View,,,,,,,, +save,Save,,,,,,,, +title,Title,,,,,,,, +status,Status,,,,,,,, +begins,Begins,,,,,,,, +total_services,Total Services,,,,,,,, +online_services,Online Services,,,,,,,, +request_timeout,Request Timeout,,,,,,,, +service_never_online,Service has never been online,,,,,,,, +service_online_check,Online checked,,,,,,,, +service_offline_time,Service has been offline for,,,,,,,, +days_ago,Days Ago,,,,,,,, +today,Today,,,,,,,, +week,Week,,,,,,,, +month,Month,,,,,,,, +day,Day,,,,,,,, +hour,Hour,,,,,,,, +minute,Minute,,,,,,,, +failures_24_hours,Failures last 24 hours,,,,,,,, +no_services,You currently don't have any services!,,,,,,,, +theme,Theme,,,,,,,, +cache,Cache,,,,,,,, +authentication,Authentication,,,,,,,, +import,Import,,,,,,,, +main_settings,Main Settings,,,,,,,, +variables,Variables,,,,,,,, +docs,Documentation,,,,,,,, +links,Links,,,,,,,, +changelog,Change Log,,,,,,,, +repo,Repository,,,,,,,, +language,Language,,,,,,,, +db_connection,Database Connection,,,,,,,, +db_host,Database Host,,,,,,,, +db_port,Database Port,,,,,,,, +db_username,Database Username,,,,,,,, +db_password,Database Password,,,,,,,, +db_database,Database Name,,,,,,,, +send_reports,Send Error Reports,,,,,,,, +send_reports_desc,Send errors to Statping for debugging,,,,,,,, +project_name,Status Page Name,,,,,,,, +description,Description,,,,,,,, +domain,Domain,,,,,,,, +enable_cdn,Enable CDN,,,,,,,, +newsletter,Newsletter,,,,,,,, +newsletter_note,We will only send you an email for major changes,,,,,,,, +loading,Loading,,,,,,,, +save_settings,Save Settings,,,,,,,, +average_response,Average Response,,,,,,,, +last_uptime,Uptime last,,,,,,,, +sign_in,Sign In,,,,,,,, +last_login,Last Login,,,,,,,, +admin,Admin,,,,,,,, +user,User,,,,,,,, +failed,Failed,,,,,,,, +wrong_login,Incorrect username or password,,,,,,,, +theme_editor,Theme Editor,,,,,,,, +enable_assets,Enable Local Assets,,,,,,,, +assets_desc,Customize your status page design by enabling local assets. This will create a 'assets' directory containing all CSS.,,,,,,,, +assets_btn,Enable Local Assets,,,,,,,, +assets_loading,Creating Assets,,,,,,,, +assets_dir,Assets Directory,,,,,,,, +footer,Footer,,,,,,,, +footer_notes,You can use HTML tags in footer,,,,,,,, +global_announcement,Global Announcement,,,,,,,, +announcement_date,Announcement Date Range,,,,,,,, +notify_users,Notify Users,,,,,,,, +notify_desc,Notify Users Before Scheduled Time,,,,,,,, +notify_method,Notification Method,,,,,,,, +notify_before,Notify Before,,,,,,,, +message_create,Create Announcement,,,,,,,, +message_edit,Edit Announcement,,,,,,,, +minutes,Minutes,,,,,,,, +hours,Hours,,,,,,,, +days,Days,,,,,,,, +user_create,Create User,,,,,,,, +user_update,Update User,,,,,,,, +administrator,Administrator,,,,,,,, +checkins,Checkins,,,,,,,, +incidents,Incidents,,,,,,,, +service_info,Service Info,,,,,,,, +service_name,Service Name,,,,,,,, +service_type,Service Type,,,,,,,, +permalink,Permalink URL,,,,,,,, +service_public,Public Service,,,,,,,, +check_interval,Check Interval,,,,,,,, +service_endpoint,Service Endpoint,,,,,,,, +service_check,Service Check Type,,,,,,,, +service_timeout,Request Timeout,,,,,,,, +expected_resp,Expected Response,,,,,,,, +expected_code,Expected Status Code,,,,,,,, +follow_redir,Follow Redirects,,,,,,,, +verify_ssl,Verify SSL,,,,,,,, +tls_cert,Use TLS Cert,,,,,,,, +notification_opts,Notification Options,,,,,,,, +notifications_enable,Enable Notifications,,,,,,,, +notify_after,Notify After Failures,,,,,,,, +notify_all,Notify All Changes,,,,,,,, +service_update,Update Service,,,,,,,, +service_create,Create Service,,,,,,,, diff --git a/go.mod b/go.mod index 4316ede4..b7eae5d4 100644 --- a/go.mod +++ b/go.mod @@ -6,35 +6,32 @@ go 1.14 require ( github.com/GeertJohan/go.rice v1.0.0 github.com/aws/aws-sdk-go v1.30.20 - github.com/coreos/go-oidc v2.2.1+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/fatih/structs v1.1.0 github.com/foomo/simplecert v1.7.5 github.com/foomo/tlsconfig v0.0.0-20180418120404-b67861b076c9 github.com/getsentry/sentry-go v0.5.1 github.com/go-mail/mail v2.3.1+incompatible + github.com/go-redis/cache/v8 v8.0.0 + github.com/go-redis/redis/v8 v8.1.3 github.com/gorilla/mux v1.7.4 github.com/hako/durafmt v0.0.0-20200605151348-3a43fc422dd9 github.com/jinzhu/gorm v1.9.12 github.com/mattn/go-sqlite3 v2.0.3+incompatible github.com/pkg/errors v0.9.1 - github.com/pquerna/cachecontrol v0.0.0-20200819021114-67c6ae64274f // indirect github.com/prometheus/client_golang v1.1.0 github.com/sirupsen/logrus v1.5.0 github.com/spf13/cobra v1.0.0 github.com/spf13/viper v1.6.3 github.com/statping/emails v1.0.0 + github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.6.1 github.com/t-tiger/gorm-bulk-insert/v2 v2.0.1 - github.com/tensorflow/tensorflow v2.3.0+incompatible // indirect + go.uber.org/atomic v1.6.0 // indirect golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d + golang.org/x/text v0.3.3 // indirect google.golang.org/grpc v1.28.1 gopkg.in/natefinch/lumberjack.v2 v2.0.0 - gopkg.in/yaml.v2 v2.2.8 - gorm.io/driver/mysql v1.0.1 - gorm.io/driver/postgres v1.0.0 - gorm.io/driver/sqlite v1.1.1 - gorm.io/gorm v1.20.0 - gorm.io/plugin/dbresolver v1.0.0 + gopkg.in/yaml.v2 v2.3.0 ) diff --git a/go.sum b/go.sum index c49f49fe..23fb401f 100755 --- a/go.sum +++ b/go.sum @@ -83,7 +83,6 @@ github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4K github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 h1:xPMsUicZ3iosVPSIP7bW5EcGUzjiiMl1OYTe14y/R24= github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks= -github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 h1:WDC6ySpJzbxGWFh4aMxFFC28wwGp5pEuoTtvA4q/qQ4= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -99,7 +98,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/aliyun/alibaba-cloud-sdk-go v1.61.112/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.131 h1:ePFkFbwr/u1HM9/p+azqI5UaxwY1hYKv+H8dkaRCLs4= github.com/aliyun/alibaba-cloud-sdk-go v1.61.131/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= -github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aws/aws-sdk-go v1.30.20 h1:ktsy2vodSZxz/arYqo7DlpkIeNohHL+4Rmjdo7YGtrE= @@ -115,7 +113,10 @@ github.com/cenkalti/backoff/v4 v4.0.2 h1:JIufpQLbh4DkbQoii76ItQIUFzevQSqOLZca4ea github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -125,24 +126,19 @@ github.com/cloudflare/cloudflare-go v0.10.2/go.mod h1:qhVI5MKwBGhdNU89ZRz2plgYut github.com/cloudflare/cloudflare-go v0.11.6 h1:gErXaYucoS8aHdmoJnF4RMFiXJH449sk6rCtoP6EhrE= github.com/cloudflare/cloudflare-go v0.11.6/go.mod h1:lmCbgQdBeSQlMv0W0OSqoGgl8aFrgc5oXHhWMt47dh0= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= 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-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= -github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -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/cpu/goacmedns v0.0.2 h1:hYAgjnPu7HogTgb8trqQouR/RrBgXq1TPBgmxbK9eRA= github.com/cpu/goacmedns v0.0.2/go.mod h1:4MipLkI+qScwqtVxcNO6okBhbgRrr7/tKXUSgSL0teQ= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= 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/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= @@ -157,6 +153,8 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= @@ -214,6 +212,11 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-mail/mail v2.3.1+incompatible h1:UzNOn0k5lpfVtO31cK3hn6I4VEVGhe3lX8AJBAxXExM= github.com/go-mail/mail v2.3.1+incompatible/go.mod h1:VPWjmmNyRsWXQZHVHT3g0YbIINUkSmuKOiLIDkWbL6M= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-redis/cache/v8 v8.0.0 h1:J/v+5zau/tfyBWK8BGIR6ubnXKDh7/o3rMy/TAr9d2Q= +github.com/go-redis/cache/v8 v8.0.0/go.mod h1:qSXlomlN5lJZf7TIgddPHwVAYMKWxEcwnZobz6kltX8= +github.com/go-redis/redis/v8 v8.0.0/go.mod h1:isLoQT/NFSP7V67lyvM9GmdvLdyZ7pEhsXvvyQtnQTo= +github.com/go-redis/redis/v8 v8.1.3 h1:Wcla0pl4iobatJy3CmQonbmZOPF6w94xOaGkVFWH/rQ= +github.com/go-redis/redis/v8 v8.1.3/go.mod h1:ysgGY09J/QeDYbu3HikWEIPCwaeOkuNoTgKayTEaEOw= github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-resty/resty/v2 v2.2.0 h1:vgZ1cdblp8Aw4jZj3ZsKh6yKAlMg3CHMrqFSFFd+jgY= github.com/go-resty/resty/v2 v2.2.0/go.mod h1:nYW/8rxqQCmI3bPz9Fsmjbr2FBjGuR2Mzt6kDh3zZ7w= @@ -260,6 +263,9 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomarkdown/markdown v0.0.0-20200820230800-3724143f5294 h1:rSb2ZQZ3B1rlWBWamxobyn0jTuGZHbPO5Rmjw48uWRM= github.com/gomarkdown/markdown v0.0.0-20200820230800-3724143f5294/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU= @@ -271,6 +277,9 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -330,56 +339,6 @@ github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/ github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/schema v0.0.1 h1:10g/WnoRR+U+XXHWKBHeNy/+tZmM2kcAVGLOsz+yaDA= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= -github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= -github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= -github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= -github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= -github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= -github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= -github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= -github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= -github.com/jackc/pgconn v1.6.4 h1:S7T6cx5o2OqmxdHaXLH1ZeD1SbI8jBznyYE9Ec0RCQ8= -github.com/jackc/pgconn v1.6.4/go.mod h1:w2pne1C2tZgP+TvjqLpOigGzNqjBgQW9dUw/4Chex78= -github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= -github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= -github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= -github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= -github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.0.2 h1:q1Hsy66zh4vuNsajBUF2PNqfAMMfxU5mk594lPE9vjY= -github.com/jackc/pgproto3/v2 v2.0.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= -github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= -github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= -github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= -github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= -github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= -github.com/jackc/pgtype v1.4.2 h1:t+6LWm5eWPLX1H5Se702JSBcirq6uWa4jiG4wV1rAWY= -github.com/jackc/pgtype v1.4.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= -github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= -github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= -github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= -github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= -github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= -github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= -github.com/jackc/pgx/v4 v4.8.1 h1:SUbCLP2pXvf/Sr/25KsuI4aTxiFYIvpfk4l6aTSdyCw= -github.com/jackc/pgx/v4 v4.8.1/go.mod h1:4HOLxrl8wToZJReD04/yB20GDwf4KBYETvlHciCnwW0= -github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q= @@ -422,6 +381,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0 h1:GhthINjveNZAdFUD8QoQYfjxnOONZgztK/Yr6M23UTY= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.0 h1:wJbzvpYMVGG9iTI9VxpnNZfd4DzMPoCWze3GgSqz8yg= +github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ= github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b h1:DzHy0GlWeF0KAglaTMY7Q+khIFoG8toHP+wLFBVBQJc= @@ -433,7 +394,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -445,11 +405,8 @@ github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvf github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/lextoumbourou/goodhosts v2.1.0+incompatible h1:1U1p5Z1wrXl23/fW/GY4zdTbQ8UJbyvrkPbqAZ6tzbw= github.com/lextoumbourou/goodhosts v2.1.0+incompatible/go.mod h1:89s48k108X3gKDWn8AHk3gUzUGTcMZCCAOsE4QU1bbo= -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.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= github.com/lib/pq v1.1.1/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 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA= @@ -462,20 +419,14 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP 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/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= -github.com/mattn/go-sqlite3 v1.14.2/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw= github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= @@ -525,14 +476,22 @@ github.com/nrdcg/goinwx v0.6.1 h1:AJnjoWPELyCtofhGcmzzcEMFd9YdF2JB/LgutWsWt/s= github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2SwKQ= github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg= github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= +github.com/onsi/ginkgo v1.14.1/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/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= +github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/oracle/oci-go-sdk v17.4.0+incompatible h1:W9yFhlwQ9+p0mE2oPrS++v821eIT17gTUpJXkmGZb9o= @@ -554,8 +513,6 @@ 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/pquerna/cachecontrol v0.0.0-20200819021114-67c6ae64274f h1:JDEmUDtyiLMyMlFwiaDOv2hxUp35497fkwePcLeV7j4= -github.com/pquerna/cachecontrol v0.0.0-20200819021114-67c6ae64274f/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= @@ -587,9 +544,6 @@ github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKc github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -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 v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= @@ -598,16 +552,12 @@ github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ= github.com/sacloud/libsacloud v1.36.1 h1:tCpFjWsvu/2Im8/SDmRZ49SttVXy7nHerobRc1LU9pI= github.com/sacloud/libsacloud v1.36.1/go.mod h1:P7YAOVmnIn3DKHqCZcUKYUXmSwGBm3yS7IBEjKVSrjg= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -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/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/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.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= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= @@ -650,12 +600,14 @@ github.com/statping/statping v0.90.64/go.mod h1:lbyNPB73IjWtnommV4wSejYfgUT1yLhh github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= @@ -666,9 +618,6 @@ github.com/tdewolff/minify/v2 v2.8.0/go.mod h1:6zN8VLhMfFxNrwHROcboYNo2+huPNu4SV github.com/tdewolff/parse/v2 v2.4.4 h1:uMdbQRtYbKR/msP9CbI7li9wK6pionYiH6s7ipltyGY= github.com/tdewolff/parse/v2 v2.4.4/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho= github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/tensorflow/tensorflow v1.15.3 h1:xE0S0nl5ZTJPyvHm9jisVaovZWVSj58eWJz637ASW7Q= -github.com/tensorflow/tensorflow v2.3.0+incompatible h1:FbjZGMOzvKFeLAnToZb+J7PJEpki6Ee1uC1w07cu/yI= -github.com/tensorflow/tensorflow v2.3.0+incompatible/go.mod h1:itOSERT4trABok4UOoG+X4BoKds9F3rIsySdn+Lvu90= github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 h1:CpHxIaZzVy26GqJn8ptRyto8fuoYOd1v0fXm9bG3wQ8= github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -689,6 +638,15 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBn github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= +github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= +github.com/vmihailenco/go-tinylfu v0.0.0-20200714092347-120b932f0a08 h1:IYlYw/r3UIaL/ICXVepbMoVEC0femQdEObM8Kmc/3e0= +github.com/vmihailenco/go-tinylfu v0.0.0-20200714092347-120b932f0a08/go.mod h1:qZbD6U3F10Sfuxyy4c5wMq5CM4/t5I3eJJS9yMQoXU0= +github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/msgpack/v5 v5.0.0-beta.1 h1:d71/KA0LhvkrJ/Ok+Wx9qK7bU8meKA1Hk0jpVI5kJjk= +github.com/vmihailenco/msgpack/v5 v5.0.0-beta.1/go.mod h1:xlngVLeyQ/Qi05oQxhQ+oTuqa03RjMwMfk/7/TCs+QI= +github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA= github.com/vultr/govultr v0.3.3 h1:fVaF4h9u3VzTXxFsxvgBUCiM52EiahLqAPkizamLzYM= github.com/vultr/govultr v0.3.3/go.mod h1:TUuUizMOFc7z+PNMssb6iGjKjQfpw5arIaOLfocVudQ= @@ -706,7 +664,6 @@ github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FB github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -715,17 +672,17 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/otel v0.11.0 h1:IN2tzQa9Gc4ZVKnTaMbPVcHjvzOdg5n9QfnmlqiET7E= +go.opentelemetry.io/otel v0.11.0/go.mod h1:G8UCk+KooF2HLkgo8RHX9epABH/aRGYET7gQOqBVdB0= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y= go.uber.org/ratelimit v0.1.0 h1:U2AruXqeTb4Eh9sYQSTrMhH8Cb7M0Ian2ibBOnBcnAw= go.uber.org/ratelimit v0.1.0/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y= -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/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -734,19 +691,15 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y= golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a h1:y6sBfNd1b9Wy08a6K1Z1DZc4aXABUN5TKjkYhz7UKmo= @@ -763,6 +716,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200908183739-ae8ad444f925/go.mod h1:1phAWC201xIgDyaFpmDeZkgf70Q4Pd/CNqfRtVPtxNw= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -783,7 +737,8 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -804,7 +759,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -819,8 +773,11 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -862,15 +819,15 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= 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-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -880,6 +837,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c= golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -908,18 +867,15 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 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-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= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -939,8 +895,6 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4 h1:kDtqNkeBrZb8B+atrj50B5XLHpzXXqcCdZPP/ApQ5NY= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= @@ -965,6 +919,8 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -987,6 +943,8 @@ google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200420144010-e5e8543f8aeb h1:nAFaltAMbNVA0rixtwvdnqgSVLX3HFUUvMkEklmzbYM= google.golang.org/genproto v0.0.0-20200420144010-e5e8543f8aeb/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1008,6 +966,11 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= @@ -1024,7 +987,6 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8 gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0= gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= -gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -1044,6 +1006,7 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.0 h1:OZ4sdq+Y+SHfYB7vfthi1Ei8b0vkP8ZPQgUfUwdUSqo= gopkg.in/square/go-jose.v2 v2.5.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1052,19 +1015,10 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/mysql v1.0.1 h1:omJoilUzyrAp0xNoio88lGJCroGdIOen9hq2A/+3ifw= -gorm.io/driver/mysql v1.0.1/go.mod h1:KtqSthtg55lFp3S5kUXqlGaelnWpKitn4k1xZTnoiPw= -gorm.io/driver/postgres v1.0.0 h1:Yh4jyFQ0a7F+JPU0Gtiam/eKmpT/XFc1FKxotGqc6FM= -gorm.io/driver/postgres v1.0.0/go.mod h1:wtMFcOzmuA5QigNsgEIb7O5lhvH1tHAF1RbWmLWV4to= -gorm.io/driver/sqlite v1.1.1 h1:qtWqNAEUyi7gYSUAJXeiAMz0lUOdakZF5ia9Fqnp5G4= -gorm.io/driver/sqlite v1.1.1/go.mod h1:hm2olEcl8Tmsc6eZyxYSeznnsDaMqamBvEXLNtBg4cI= -gorm.io/gorm v1.9.19 h1:NMrwpxOZIHWJEFzZ0MM8PdYlcXyKLaXTHWfpDEDdBNg= -gorm.io/gorm v1.9.19/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.0 h1:qfIlyaZvrF7kMWY3jBdEBXkXJ2M5MFYMTppjILxS3fQ= -gorm.io/gorm v1.20.0/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/plugin/dbresolver v1.0.0 h1:fHIWRRkoDmXkBPYyg9GMmLugcM9fcbZiG0Zy/cwiPlM= -gorm.io/plugin/dbresolver v1.0.0/go.mod h1:sK1Alv120lfrjRQXrzyAw4ssxDPJjamm2cbBOZBHM68= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/handlers/cache.go b/handlers/cache.go index bc0e7b97..5a77d58b 100644 --- a/handlers/cache.go +++ b/handlers/cache.go @@ -27,7 +27,7 @@ type Item struct { // cleanRoutine is a go routine to automatically remove expired caches that haven't been hit recently func cleanRoutine(s *Storage) { - duration := 5 * time.Second + duration := 60 * time.Second CacheRoutine: for { @@ -40,7 +40,7 @@ CacheRoutine: s.Delete(k) } } - duration = 5 * time.Second + duration = 60 * time.Second } } } @@ -89,6 +89,8 @@ func (s Storage) List() map[string]Item { //Get a cached content by key func (s Storage) Get(key string) []byte { + s.mu.Lock() + defer s.mu.Unlock() item := s.items[key] if item.Expired() { CacheStorage.Delete(key) diff --git a/notifiers/amazon_sns.go b/notifiers/amazon_sns.go index f1405a48..123ccf06 100644 --- a/notifiers/amazon_sns.go +++ b/notifiers/amazon_sns.go @@ -35,7 +35,7 @@ var AmazonSNS = &amazonSNS{¬ifications.Notification{ Description: "Use amazonSNS to receive push notifications. Add your amazonSNS URL and App Token to receive notifications.", Author: "Hunter Long", AuthorUrl: "https://github.com/hunterlong", - Icon: "amazon", + Icon: "fab fa-amazon", Delay: 5 * time.Second, Limits: 60, SuccessData: null.NewNullString(`{{.Service.Name}} is back online and was down for {{.Service.Downtime.Human}}`), diff --git a/types/services/routine.go b/types/services/routine.go index 7a10fc21..50468945 100644 --- a/types/services/routine.go +++ b/types/services/routine.go @@ -2,11 +2,9 @@ package services import ( "bytes" + "context" "crypto/tls" "fmt" - "github.com/prometheus/client_golang/prometheus" - "github.com/statping/statping/types/metrics" - "google.golang.org/grpc" "net" "net/http" "net/url" @@ -14,9 +12,15 @@ import ( "strings" "time" + "github.com/prometheus/client_golang/prometheus" + "github.com/statping/statping/types/metrics" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "github.com/statping/statping/types/failures" "github.com/statping/statping/types/hits" "github.com/statping/statping/utils" + healthpb "google.golang.org/grpc/health/grpc_health_v1" ) // checkServices will start the checking go routine for each service @@ -115,6 +119,22 @@ func CheckGrpc(s *Service, record bool) (*Service, error) { timer := prometheus.NewTimer(metrics.ServiceTimer(s.Name)) defer timer.ObserveDuration() + // Strip URL scheme if present. Eg: https:// , http:// + if strings.Contains(s.Domain, "://") { + u, err := url.Parse(s.Domain) + if err != nil { + // Unable to parse. + log.Warnln(fmt.Sprintf("GRPC Service: '%s', Unable to parse URL: '%v'", s.Name, s.Domain)) + if record { + RecordFailure(s, fmt.Sprintf("Unable to parse GRPC domain %v, %v", s.Domain, err), "parse_domain") + } + } + + // Set domain as hostname without port number. + s.Domain = u.Hostname() + } + + // Calculate DNS check time dnsLookup, err := dnsCheck(s) if err != nil { if record { @@ -122,6 +142,18 @@ func CheckGrpc(s *Service, record bool) (*Service, error) { } return s, err } + + // Connect to grpc service without TLS certs. + grpcOption := grpc.WithInsecure() + + // Check if TLS is enabled + // Upgrade GRPC connection if using TLS + // Force to connect on HTTP2 with TLS. Needed when using a reverse proxy such as nginx. + if s.VerifySSL.Bool { + h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}}) + grpcOption = grpc.WithTransportCredentials(h2creds) + } + s.PingTime = dnsLookup t1 := utils.Now() domain := fmt.Sprintf("%v", s.Domain) @@ -131,28 +163,70 @@ func CheckGrpc(s *Service, record bool) (*Service, error) { domain = fmt.Sprintf("[%v]:%v", s.Domain, s.Port) } } - conn, err := grpc.Dial(domain, grpc.WithInsecure(), grpc.WithBlock()) - if err != nil { - log.Fatalf("did not connect: %v", err) - } + + // Context will cancel the request when timeout is exceeded. + // Cancel the context when request is served within the timeout limit. + timeout := time.Duration(s.Timeout) * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + conn, err := grpc.DialContext(ctx, domain, grpcOption, grpc.WithBlock()) if err != nil { if record { RecordFailure(s, fmt.Sprintf("Dial Error %v", err), "connection") } return s, err } + + if s.GrpcHealthCheck.Bool { + // Create a new health check client + c := healthpb.NewHealthClient(conn) + in := &healthpb.HealthCheckRequest{} + res, err := c.Check(ctx, in) + if err != nil { + if record { + RecordFailure(s, fmt.Sprintf("GRPC Error %v", err), "healthcheck") + } + return s, nil + } + + // Record responses + s.LastResponse = strings.TrimSpace(res.String()) + s.LastStatusCode = int(res.GetStatus()) + } + if err := conn.Close(); err != nil { if record { RecordFailure(s, fmt.Sprintf("%v Socket Close Error %v", strings.ToUpper(s.Type), err), "close") } return s, err } + + // Record latency s.Latency = utils.Now().Sub(t1).Microseconds() - s.LastResponse = "" s.Online = true + + if s.GrpcHealthCheck.Bool { + if s.ExpectedStatus != s.LastStatusCode { + if record { + RecordFailure(s, fmt.Sprintf("GRPC Service: '%s', Status Code: expected '%v', got '%v'", s.Name, s.ExpectedStatus, s.LastStatusCode), "response_code") + } + return s, nil + } + + if s.Expected.String != s.LastResponse { + log.Warnln(fmt.Sprintf("GRPC Service: '%s', Response: expected '%v', got '%v'", s.Name, s.Expected.String, s.LastResponse)) + if record { + RecordFailure(s, fmt.Sprintf("GRPC Response Body '%v' did not match '%v'", s.LastResponse, s.Expected.String), "response_body") + } + return s, nil + } + } + if record { RecordSuccess(s) } + return s, nil } diff --git a/types/services/routine_test.go b/types/services/routine_test.go new file mode 100644 index 00000000..92f1035c --- /dev/null +++ b/types/services/routine_test.go @@ -0,0 +1,202 @@ +package services + +import ( + "fmt" + "net" + "strconv" + "strings" + "testing" + + "github.com/statping/statping/types/null" + "google.golang.org/grpc" + "google.golang.org/grpc/health" + healthpb "google.golang.org/grpc/health/grpc_health_v1" +) + +// grpcServerDef is function type. +// Consumed by Test data. +type grpcServerDef func(int, bool) *grpc.Server + +// Test Data: Simulates testing scenarios +var testdata = []struct { + grpcService grpcServerDef + clientChecker *Service +}{ + { + grpcService: func(port int, enableHealthCheck bool) *grpc.Server { + return grpcServer(port, enableHealthCheck) + }, + clientChecker: &Service{ + Name: "GRPC Server with Health check", + Domain: "localhost", + Port: 50053, + Expected: null.NewNullString("status:SERVING"), + ExpectedStatus: 1, + Type: "grpc", + Timeout: 3, + VerifySSL: null.NewNullBool(false), + GrpcHealthCheck: null.NewNullBool(true), + }, + }, + { + grpcService: func(port int, enableHealthCheck bool) *grpc.Server { + return grpcServer(port, enableHealthCheck) + }, + clientChecker: &Service{ + Name: "Check TLS endpoint on GRPC Server with TLS disabled", + Domain: "localhost", + Port: 50054, + Expected: null.NewNullString(""), + ExpectedStatus: 0, + Type: "grpc", + Timeout: 1, + VerifySSL: null.NewNullBool(true), + GrpcHealthCheck: null.NewNullBool(true), + }, + }, + { + grpcService: func(port int, enableHealthCheck bool) *grpc.Server { + return grpcServer(port, enableHealthCheck) + }, + clientChecker: &Service{ + Name: "Check GRPC Server without Health check endpoint", + Domain: "localhost", + Port: 50055, + Expected: null.NewNullString(""), + ExpectedStatus: 0, + Type: "grpc", + Timeout: 1, + VerifySSL: null.NewNullBool(false), + }, + }, + { + grpcService: func(port int, enableHealthCheck bool) *grpc.Server { + return grpcServer(50056, enableHealthCheck) + }, + clientChecker: &Service{ + Name: "Check where no GRPC Server exists", + Domain: "localhost", + Port: 1000, + Expected: null.NewNullString(""), + ExpectedStatus: 0, + Type: "grpc", + Timeout: 1, + VerifySSL: null.NewNullBool(false), + GrpcHealthCheck: null.NewNullBool(true), + }, + }, + { + grpcService: func(port int, enableHealthCheck bool) *grpc.Server { + return grpcServer(50057, enableHealthCheck) + }, + clientChecker: &Service{ + Name: "Check where no GRPC Server exists (Verify TLS)", + Domain: "localhost", + Port: 1000, + Expected: null.NewNullString(""), + ExpectedStatus: 0, + Type: "grpc", + Timeout: 1, + VerifySSL: null.NewNullBool(true), + GrpcHealthCheck: null.NewNullBool(true), + }, + }, + { + grpcService: func(port int, enableHealthCheck bool) *grpc.Server { + return grpcServer(port, enableHealthCheck) + }, + clientChecker: &Service{ + Name: "Check GRPC Server with url", + Domain: "http://localhost", + Port: 50058, + Expected: null.NewNullString("status:SERVING"), + ExpectedStatus: 1, + Type: "grpc", + Timeout: 1, + VerifySSL: null.NewNullBool(false), + GrpcHealthCheck: null.NewNullBool(true), + }, + }, + { + grpcService: func(port int, enableHealthCheck bool) *grpc.Server { + return grpcServer(port, enableHealthCheck) + }, + clientChecker: &Service{ + Name: "Unparseable Url Error", + Domain: "http://local//host", + Port: 50059, + Expected: null.NewNullString(""), + ExpectedStatus: 0, + Type: "grpc", + Timeout: 1, + VerifySSL: null.NewNullBool(false), + GrpcHealthCheck: null.NewNullBool(true), + }, + }, + { + grpcService: func(port int, enableHealthCheck bool) *grpc.Server { + return grpcServer(50060, enableHealthCheck) + }, + clientChecker: &Service{ + Name: "Check GRPC on HTTP server", + Domain: "https://google.com", + Port: 443, + Expected: null.NewNullString(""), + ExpectedStatus: 0, + Type: "grpc", + Timeout: 1, + VerifySSL: null.NewNullBool(false), + }, + }, + { + grpcService: func(port int, enableHealthCheck bool) *grpc.Server { + return grpcServer(port, true) + }, + clientChecker: &Service{ + Name: "GRPC HealthCheck where health check endpoint is not implemented", + Domain: "http://localhost", + Port: 50061, + Expected: null.NewNullString(""), + ExpectedStatus: 0, + Type: "grpc", + Timeout: 1, + VerifySSL: null.NewNullBool(false), + GrpcHealthCheck: null.NewNullBool(false), + }, + }, +} + +// grpcServer creates grpc Service with optional parameters. +func grpcServer(port int, enableHealthCheck bool) *grpc.Server { + portString := strconv.Itoa(port) + server := grpc.NewServer() + lis, err := net.Listen("tcp", "localhost:"+portString) + if err != nil { + fmt.Println(err) + } + + if enableHealthCheck { + healthServer := health.NewServer() + healthServer.SetServingStatus("Test GRPC Service", healthpb.HealthCheckResponse_SERVING) + healthpb.RegisterHealthServer(server, healthServer) + go server.Serve(lis) + } + return server +} + +// TestCheckGrpc ranges over the testdata struct. +// Examines checkGrpc() function +func TestCheckGrpc(t *testing.T) { + for _, testscenario := range testdata { + v := testscenario + t.Run(v.clientChecker.Name, func(t *testing.T) { + t.Parallel() + server := v.grpcService(v.clientChecker.Port, v.clientChecker.GrpcHealthCheck.Bool) + defer server.Stop() + v.clientChecker.CheckService(false) + if v.clientChecker.LastStatusCode != v.clientChecker.ExpectedStatus || strings.TrimSpace(v.clientChecker.LastResponse) != v.clientChecker.Expected.String { + t.Errorf("Expected message: '%v', Got message: '%v' , Expected Status: '%v', Got Status: '%v'", v.clientChecker.Expected.String, v.clientChecker.LastResponse, v.clientChecker.ExpectedStatus, v.clientChecker.LastStatusCode) + } + }) + } +} diff --git a/types/services/services_test.go b/types/services/services_test.go index 81703b68..637e2088 100644 --- a/types/services/services_test.go +++ b/types/services/services_test.go @@ -469,7 +469,7 @@ func TestServices(t *testing.T) { item, err := Find(1) require.Nil(t, err) amount := item.Downtime().Seconds() - assert.GreaterOrEqual(t, int64(75), int64(amount)) + assert.GreaterOrEqual(t, int64(amount), int64(75)) }) t.Run("Test Failures Since", func(t *testing.T) { diff --git a/types/services/struct.go b/types/services/struct.go index 472614d3..ca55aaba 100644 --- a/types/services/struct.go +++ b/types/services/struct.go @@ -1,12 +1,13 @@ package services import ( + "time" + "github.com/statping/statping/types/checkins" "github.com/statping/statping/types/failures" "github.com/statping/statping/types/incidents" "github.com/statping/statping/types/messages" "github.com/statping/statping/types/null" - "time" ) // Service is the main struct for Services @@ -24,6 +25,7 @@ type Service struct { Timeout int `gorm:"default:30;column:timeout" json:"timeout" scope:"user,admin" yaml:"timeout"` Order int `gorm:"default:0;column:order_id" json:"order_id" yaml:"order_id"` VerifySSL null.NullBool `gorm:"default:false;column:verify_ssl" json:"verify_ssl" scope:"user,admin" yaml:"verify_ssl"` + GrpcHealthCheck null.NullBool `gorm:"default:false;column:grpc_health_check" json:"grpc_health_check" scope:"user,admin" yaml:"grpc_health_check"` Public null.NullBool `gorm:"default:true;column:public" json:"public" yaml:"public"` GroupId int `gorm:"default:0;column:group_id" json:"group_id" yaml:"group_id"` TLSCert null.NullString `gorm:"column:tls_cert" json:"tls_cert" scope:"user,admin" yaml:"tls_cert"` diff --git a/version.txt b/version.txt index 94b742c3..3e8f5ffe 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.90.69 \ No newline at end of file +0.90.70